This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new 15f5b0e950 add error type metrics (#11596)
15f5b0e950 is described below

commit 15f5b0e950402de9e459290e1c91ad2b1b6f9ec4
Author: jojocodeX <[email protected]>
AuthorDate: Tue Feb 28 15:42:20 2023 +0800

    add error type metrics (#11596)
---
 .../kubernetes/KubernetesServiceDiscoveryTest.java |  25 ++-
 .../apache/dubbo/metrics/event/MetricsEvent.java   |   5 +-
 .../apache/dubbo/metrics/model/MethodMetric.java   |  13 +-
 .../org/apache/dubbo/metrics/model/MetricsKey.java |  23 ++-
 .../collector/AggregateMetricsCollector.java       | 137 ++++++--------
 .../metrics/collector/DefaultMetricsCollector.java |   6 +-
 .../collector/sample/MethodMetricsSampler.java     |   9 +-
 .../sample/MetricsCountSampleConfigurer.java       |   1 -
 .../collector/sample/MetricsCountSampler.java      |   4 +
 .../metrics/collector/sample/MetricsSampler.java   |   1 -
 .../sample/SimpleMetricsCountSampler.java          |  96 +++++++---
 .../collector/sample/ThreadPoolMetricsSampler.java |  76 ++++----
 .../metrics/filter/MethodMetricsInterceptor.java   |  77 ++++----
 ...etricsFilter.java => MetricsClusterFilter.java} |  47 ++---
 .../apache/dubbo/metrics/filter/MetricsFilter.java |  10 +-
 ...g.apache.dubbo.rpc.cluster.filter.ClusterFilter |   1 +
 .../collector/AggregateMetricsCollectorTest.java   |  16 +-
 .../dubbo/metrics/filter/MetricsFilterTest.java    |  81 ++++++++-
 .../dubbo/metrics/sampler/CountSamplerTest.java    | 197 +++++++++++++++++++++
 19 files changed, 579 insertions(+), 246 deletions(-)

diff --git 
a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java
 
b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java
index 4f8371966a..b786953245 100644
--- 
a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java
+++ 
b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.registry.kubernetes;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
+import io.fabric8.kubernetes.api.model.Endpoints;
+import io.fabric8.kubernetes.api.model.EndpointsBuilder;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.PodBuilder;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.ServiceBuilder;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
@@ -38,15 +43,9 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import io.fabric8.kubernetes.api.model.Endpoints;
-import io.fabric8.kubernetes.api.model.EndpointsBuilder;
-import io.fabric8.kubernetes.api.model.Pod;
-import io.fabric8.kubernetes.api.model.PodBuilder;
-import io.fabric8.kubernetes.api.model.Service;
-import io.fabric8.kubernetes.api.model.ServiceBuilder;
-import io.fabric8.kubernetes.client.Config;
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient;
-import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 
 import static 
org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.NAMESPACE;
 import static org.awaitility.Awaitility.await;
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
index 3b21f6cc7f..5c49988f2e 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java
@@ -54,7 +54,10 @@ public abstract class MetricsEvent {
         PROCESSING,
         UNKNOWN_FAILED,
         TOTAL_FAILED,
-        APPLICATION_INFO
+        APPLICATION_INFO,
+        NETWORK_EXCEPTION,
+        SERVICE_UNAVAILABLE,
+        CODEC_EXCEPTION;
 
     }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java
index cbccdcf188..35b7a6bf71 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java
@@ -26,15 +26,15 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
 import static 
org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
-import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
+import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY;
+import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY;
-import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY;
 import static 
org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY;
 import static org.apache.dubbo.common.utils.NetUtils.getLocalHost;
 import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName;
@@ -51,9 +51,7 @@ public class MethodMetric implements Metric {
     private String group;
     private String version;
 
-    public MethodMetric() {
-
-    }
+    public MethodMetric() {}
 
     public MethodMetric(String applicationName, Invocation invocation) {
         this.applicationName = applicationName;
@@ -97,7 +95,6 @@ public class MethodMetric implements Metric {
         tags.put(TAG_IP, getLocalHost());
         tags.put(TAG_HOSTNAME, getLocalHostName());
         tags.put(TAG_APPLICATION_NAME, applicationName);
-
         tags.put(TAG_INTERFACE_KEY, interfaceName);
         tags.put(TAG_METHOD_KEY, methodName);
         tags.put(TAG_GROUP_KEY, group);
diff --git 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java
 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java
index 0e3e160a1b..8d55c707b1 100644
--- 
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java
+++ 
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java
@@ -22,13 +22,17 @@ public enum MetricsKey {
 
     // provider metrics key
     METRIC_REQUESTS("dubbo.%s.requests.total", "Total Requests"),
-    METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Succeed 
Requests"),
-    METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", 
"Failed Business Requests"),
+    METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Total Succeed 
Requests"),
+    
METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total","Total 
Failed Business Requests"),
+
     METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing", "Processing 
Requests"),
     METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout 
Failed Requests"),
     METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed 
Requests"),
-    METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Unknown 
Failed Requests"),
+    METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Total 
Unknown Failed Requests"),
     METRIC_REQUESTS_TOTAL_FAILED("dubbo.%s.requests.failed.total", "Total 
Failed Requests"),
+    METRIC_REQUESTS_NETWORK_FAILED("dubbo.%s.requests.failed.network.total", 
"Total network Failed Requests"),
+    
METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED("dubbo.%s.requests.failed.service.unavailable.total",
 "Total Service Unavailable Failed Requests"),
+    METRIC_REQUESTS_CODEC_FAILED("dubbo.%s.requests.failed.codec.total", 
"Total Codec Failed Requests"),
 
     METRIC_REQUESTS_TOTAL_AGG("dubbo.%s.requests.total.aggregate", "Aggregated 
Total Requests"),
     METRIC_REQUESTS_SUCCEED_AGG("dubbo.%s.requests.succeed.aggregate", 
"Aggregated Succeed Requests"),
@@ -37,6 +41,9 @@ public enum MetricsKey {
     METRIC_REQUESTS_TIMEOUT_AGG("dubbo.%s.requests.timeout.failed.aggregate", 
"Aggregated timeout Failed Requests"),
     METRIC_REQUESTS_LIMIT_AGG("dubbo.%s.requests.limit.aggregate", "Aggregated 
limit Requests"),
     
METRIC_REQUESTS_TOTAL_FAILED_AGG("dubbo.%s.requests.failed.total.aggregate", 
"Aggregated failed total Requests"),
+    
METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG("dubbo.%s.requests.failed.network.total.aggregate",
 "Aggregated failed network total Requests"),
+    
METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG("dubbo.%s.requests.failed.codec.total.aggregate",
 "Aggregated failed codec total Requests"),
+    
METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG("dubbo.%s.requests.failed.service.unavailable.total.aggregate",
 "Aggregated failed codec total Requests"),
 
     METRIC_QPS("dubbo.%s.qps.total", "Query Per Seconds"),
     METRIC_RT_LAST("dubbo.%s.rt.milliseconds.last", "Last Response Time"),
@@ -88,8 +95,8 @@ public enum MetricsKey {
     // consumer metrics key
     ;
 
-    private final String name;
-    private final String description;
+    private String name;
+    private String description;
 
     public final String getName() {
         return this.name;
@@ -99,6 +106,12 @@ public enum MetricsKey {
         return String.format(name, type);
     }
 
+
+    public final MetricsKey formatName(String type) {
+        this.name = String.format(name, type);
+        return this;
+    }
+
     public final String getDescription() {
         return this.description;
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java
index a929194922..1651c87dc3 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java
@@ -17,11 +17,6 @@
 
 package org.apache.dubbo.metrics.collector;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
 import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
 import org.apache.dubbo.config.MetricsConfig;
 import org.apache.dubbo.config.context.ConfigManager;
@@ -37,7 +32,11 @@ import org.apache.dubbo.metrics.model.MetricsKey;
 import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.rpc.model.ApplicationModel;
-
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import static org.apache.dubbo.metrics.model.MetricsCategory.QPS;
 import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS;
 import static org.apache.dubbo.metrics.model.MetricsCategory.RT;
@@ -49,24 +48,17 @@ import static 
org.apache.dubbo.metrics.model.MetricsCategory.RT;
 public class AggregateMetricsCollector implements MetricsCollector, 
MetricsListener {
     private int bucketNum;
     private int timeWindowSeconds;
-
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> totalRequests 
= new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> 
succeedRequests = new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> 
unknownFailedRequests = new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> 
businessFailedRequests = new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> 
timeoutRequests = new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> limitRequests 
= new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> 
totalFailedRequests = new ConcurrentHashMap<>();
-    private final ConcurrentMap<MethodMetric, TimeWindowCounter> qps = new 
ConcurrentHashMap<>();
+    private final Map<MetricsEvent.Type, ConcurrentHashMap<MethodMetric, 
TimeWindowCounter>> methodTypeCounter = new ConcurrentHashMap<>();
     private final ConcurrentMap<MethodMetric, TimeWindowQuantile> rt = new 
ConcurrentHashMap<>();
-
+    private final ConcurrentHashMap<MethodMetric, TimeWindowCounter> qps = new 
ConcurrentHashMap<>();
     private final ApplicationModel applicationModel;
-
     private static final Integer DEFAULT_COMPRESSION = 100;
     private static final Integer DEFAULT_BUCKET_NUM = 10;
     private static final Integer DEFAULT_TIME_WINDOW_SECONDS = 120;
 
     public AggregateMetricsCollector(ApplicationModel applicationModel) {
+        this.registryerEventTypeHandler();
+
         this.applicationModel = applicationModel;
         ConfigManager configManager = 
applicationModel.getApplicationConfigManager();
         MetricsConfig config = configManager.getMetrics().orElse(null);
@@ -80,10 +72,6 @@ public class AggregateMetricsCollector implements 
MetricsCollector, MetricsListe
         }
     }
 
-    private void registerListener() {
-        
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class).addListener(this);
-    }
-
     @Override
     public void onEvent(MetricsEvent event) {
         if (event instanceof RTEvent) {
@@ -100,45 +88,24 @@ public class AggregateMetricsCollector implements 
MetricsCollector, MetricsListe
         quantile.add(responseTime);
     }
 
+
     private void onRequestEvent(RequestEvent event) {
         MethodMetric metric = (MethodMetric) event.getSource();
-        RequestEvent.Type type = event.getType();
-        TimeWindowCounter counter = null;
-        switch (type) {
-            case TOTAL:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(totalRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                TimeWindowCounter qpsCounter = 
ConcurrentHashMapUtils.computeIfAbsent(qps, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                qpsCounter.increment();
-                break;
-            case SUCCEED:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(succeedRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-            case UNKNOWN_FAILED:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(unknownFailedRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-            case BUSINESS_FAILED:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(businessFailedRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-
-            case REQUEST_TIMEOUT:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(timeoutRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-
-            case REQUEST_LIMIT:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(limitRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-
-            case TOTAL_FAILED:
-                counter = 
ConcurrentHashMapUtils.computeIfAbsent(totalFailedRequests, metric, k -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
-                break;
-
-            default:
-                break;
+
+        MetricsEvent.Type type = event.getType();
+
+        ConcurrentMap<MethodMetric, TimeWindowCounter> counter = 
methodTypeCounter.get(type);
+
+        if (counter == null) {
+            return;
         }
+        TimeWindowCounter windowCounter = 
ConcurrentHashMapUtils.computeIfAbsent(counter, metric, methodMetric -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
 
-        if (counter != null) {
-            counter.increment();
+        if (type == MetricsEvent.Type.TOTAL) {
+            TimeWindowCounter qpsCounter = 
ConcurrentHashMapUtils.computeIfAbsent(qps, metric, methodMetric -> new 
TimeWindowCounter(bucketNum, timeWindowSeconds));
+            qpsCounter.increment();
         }
+        windowCounter.increment();
     }
 
     @Override
@@ -152,39 +119,51 @@ public class AggregateMetricsCollector implements 
MetricsCollector, MetricsListe
     }
 
     private void collectRequests(List<MetricSample> list) {
-        totalRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TOTAL_AGG, k, v)));
-        succeedRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_SUCCEED_AGG, k, v)));
-        unknownFailedRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_FAILED_AGG, k, v)));
-        businessFailedRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG, 
k, v)));
-        timeoutRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG, k, v)));
-        limitRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_LIMIT_AGG, k, v)));
-        totalFailedRequests.forEach((k, v) ->
-            
list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG, k, 
v)));
-
+        collectMethod(list, MetricsEvent.Type.TOTAL, 
MetricsKey.METRIC_REQUESTS_TOTAL_AGG);
+        collectMethod(list, MetricsEvent.Type.SUCCEED, 
MetricsKey.METRIC_REQUESTS_SUCCEED_AGG);
+        collectMethod(list, MetricsEvent.Type.UNKNOWN_FAILED, 
MetricsKey.METRIC_REQUESTS_FAILED_AGG);
+        collectMethod(list, MetricsEvent.Type.BUSINESS_FAILED, 
MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG);
+        collectMethod(list, MetricsEvent.Type.REQUEST_TIMEOUT, 
MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG);
+        collectMethod(list, MetricsEvent.Type.REQUEST_LIMIT, 
MetricsKey.METRIC_REQUESTS_LIMIT_AGG);
+        collectMethod(list, MetricsEvent.Type.TOTAL_FAILED, 
MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG);
+        collectMethod(list, MetricsEvent.Type.NETWORK_EXCEPTION, 
MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG);
+        collectMethod(list, MetricsEvent.Type.CODEC_EXCEPTION, 
MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG);
+        collectMethod(list, MetricsEvent.Type.SERVICE_UNAVAILABLE, 
MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG);
     }
 
-    private GaugeMetricSample getGaugeMetricSample(MetricsKey 
metricRequestsTotalAgg, MethodMetric k, TimeWindowCounter v) {
-        return new 
GaugeMetricSample(metricRequestsTotalAgg.getNameByType(k.getSide()),
-            metricRequestsTotalAgg.getDescription(), k.getTags(), REQUESTS, 
v::get);
+    private void collectMethod(List<MetricSample> list, MetricsEvent.Type 
eventType, MetricsKey metricsKey) {
+        ConcurrentHashMap<MethodMetric, TimeWindowCounter> windowCounter = 
methodTypeCounter.get(eventType);
+        if (windowCounter != null) {
+            windowCounter.forEach((k, v) -> list.add(new 
GaugeMetricSample(metricsKey.formatName(k.getSide()), k.getTags(), REQUESTS, 
v::get)));
+        }
     }
 
     private void collectQPS(List<MetricSample> list) {
-        qps.forEach((k, v) -> list.add(new 
GaugeMetricSample(MetricsKey.METRIC_QPS.getNameByType(k.getSide()),
-            MetricsKey.METRIC_QPS.getDescription(), k.getTags(), QPS, () -> 
v.get() / v.bucketLivedSeconds())));
+        qps.forEach((k, v) -> list.add(new 
GaugeMetricSample(MetricsKey.METRIC_QPS.formatName(k.getSide()), k.getTags(), 
QPS, () -> v.get() / v.bucketLivedSeconds())));
     }
 
     private void collectRT(List<MetricSample> list) {
         rt.forEach((k, v) -> {
-            list.add(new 
GaugeMetricSample(MetricsKey.METRIC_RT_P99.getNameByType(k.getSide()),
-                MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, () 
-> v.quantile(0.99)));
-            list.add(new 
GaugeMetricSample(MetricsKey.METRIC_RT_P95.getNameByType(k.getSide()),
-                MetricsKey.METRIC_RT_P95.getDescription(), k.getTags(), RT, () 
-> v.quantile(0.95)));
+            list.add(new 
GaugeMetricSample(MetricsKey.METRIC_RT_P99.formatName(k.getSide()), 
k.getTags(), RT, () -> v.quantile(0.99)));
+            list.add(new 
GaugeMetricSample(MetricsKey.METRIC_RT_P95.formatName(k.getSide()), 
k.getTags(), RT, () -> v.quantile(0.95)));
         });
     }
+
+    private void registryerEventTypeHandler() {
+        methodTypeCounter.put(MetricsEvent.Type.TOTAL, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.SUCCEED, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.UNKNOWN_FAILED, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.BUSINESS_FAILED, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.REQUEST_TIMEOUT, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.REQUEST_LIMIT, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.TOTAL_FAILED, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.SERVICE_UNAVAILABLE, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.NETWORK_EXCEPTION, new 
ConcurrentHashMap<>());
+        methodTypeCounter.put(MetricsEvent.Type.CODEC_EXCEPTION, new 
ConcurrentHashMap<>());
+    }
+
+    private void registerListener() {
+        
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class).addListener(this);
+    }
+
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java
index b91ae3a1de..87bd5ea53e 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java
@@ -29,10 +29,8 @@ import org.apache.dubbo.metrics.model.ApplicationMetric;
 import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.rpc.model.ApplicationModel;
-
 import java.util.ArrayList;
 import java.util.List;
-
 import static org.apache.dubbo.metrics.model.MetricsCategory.APPLICATION;
 import static 
org.apache.dubbo.metrics.model.MetricsKey.APPLICATION_METRIC_INFO;
 
@@ -84,6 +82,10 @@ public class DefaultMetricsCollector implements 
MetricsCollector {
         return this.methodSampler;
     }
 
+    public ThreadPoolMetricsSampler getThreadPoolSampler() {
+        return this.threadPoolSampler;
+    }
+
     public void collectApplication(ApplicationModel applicationModel) {
         this.setApplicationName(applicationModel.getApplicationName());
         this.applicationModel = applicationModel;
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
index 75bc637ab0..3144a3c241 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java
@@ -28,11 +28,9 @@ import org.apache.dubbo.metrics.model.MetricsKey;
 import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
 import org.apache.dubbo.rpc.Invocation;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Supplier;
-
 import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS;
 import static org.apache.dubbo.metrics.model.MetricsCategory.RT;
 
@@ -63,7 +61,8 @@ public class MethodMetricsSampler extends 
SimpleMetricsCountSampler<Invocation,
         List<MetricSample> metricSamples = new ArrayList<>();
 
         collect(metricSamples);
-        metricSamples.addAll(collectRT((key, metric, count) -> 
getGaugeMetricSample(key, metric, RT, () -> count)));
+        metricSamples.addAll(
+            this.collectRT((key, metric, count) -> getGaugeMetricSample(key, 
metric, RT, () -> count)));
 
         return metricSamples;
     }
@@ -77,8 +76,12 @@ public class MethodMetricsSampler extends 
SimpleMetricsCountSampler<Invocation,
         count(list, MetricsEvent.Type.REQUEST_TIMEOUT, 
MetricsKey.METRIC_REQUESTS_TIMEOUT);
         count(list, MetricsEvent.Type.REQUEST_LIMIT, 
MetricsKey.METRIC_REQUESTS_LIMIT);
         count(list, MetricsEvent.Type.TOTAL_FAILED, 
MetricsKey.METRIC_REQUESTS_TOTAL_FAILED);
+        count(list, MetricsEvent.Type.NETWORK_EXCEPTION, 
MetricsKey.METRIC_REQUESTS_NETWORK_FAILED);
+        count(list, MetricsEvent.Type.SERVICE_UNAVAILABLE, 
MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED);
+        
count(list,MetricsEvent.Type.CODEC_EXCEPTION,MetricsKey.METRIC_REQUESTS_CODEC_FAILED);
     }
 
+
     private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, 
MethodMetric methodMetric,
                                                    MetricsCategory 
metricsCategory, Supplier<Number> get) {
         return new 
GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), 
metricsKey.getDescription(),
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java
index 15da69cd56..439b04eabf 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java
@@ -18,7 +18,6 @@
 package org.apache.dubbo.metrics.collector.sample;
 
 import org.apache.dubbo.metrics.model.Metric;
-
 import java.util.function.Consumer;
 import java.util.function.Function;
 
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
index 06512199aa..3fbd3da676 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java
@@ -38,10 +38,14 @@ public interface MetricsCountSampler<S, K, M extends 
Metric> extends MetricsSamp
 
     void addRT(S source, Long rt);
 
+    void addRT(S source, K metricName, Long rt);
+
     Optional<ConcurrentMap<M, AtomicLong>> getCount(K metricName);
 
     <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M, R> 
factory);
 
+    <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M, R> 
factory,K metricName);
+
     interface MetricSampleFactory<M, R extends MetricSample> {
         R newInstance(MetricsKey key, M metric, Long count);
     }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java
index 9d59726288..55111af991 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java
@@ -18,7 +18,6 @@
 package org.apache.dubbo.metrics.collector.sample;
 
 import org.apache.dubbo.metrics.model.sample.MetricSample;
-
 import java.util.List;
 
 public interface MetricsSampler {
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
index 898e0d9dd8..5e1ddded2a 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java
@@ -44,14 +44,15 @@ public abstract class SimpleMetricsCountSampler<S, K, M 
extends Metric>
     implements MetricsCountSampler<S, K, M> {
 
     private final ConcurrentMap<M, AtomicLong> EMPTY_COUNT = new 
ConcurrentHashMap<>();
-
+    private Map<K, ConcurrentMap<M, AtomicLong>> metricCounter = new 
ConcurrentHashMap<>();
+    // lastRT, totalRT, rtCount, avgRT share a container, can utilize the 
system cache line
+    private final ConcurrentMap<M, AtomicLongArray> rtSample = new 
ConcurrentHashMap<>();
     private final ConcurrentMap<M, LongAccumulator> minRT = new 
ConcurrentHashMap<>();
     private final ConcurrentMap<M, LongAccumulator> maxRT = new 
ConcurrentHashMap<>();
 
-    // lastRT, totalRT, rtCount, avgRT share a container, can utilize the 
system cache line
-    private final ConcurrentMap<M, AtomicLongArray> rtArray = new 
ConcurrentHashMap<>();
-
-    private final Map<K, ConcurrentMap<M, AtomicLong>> metricCounter = new 
ConcurrentHashMap<>();
+    private final ConcurrentMap<K, ConcurrentMap<M,AtomicLongArray>> 
rtGroupSample = new ConcurrentHashMap<>();
+    private final ConcurrentMap<K, ConcurrentMap<M,LongAccumulator>> 
groupMinRT   = new ConcurrentHashMap<>();
+    private final ConcurrentMap<K, ConcurrentMap<M,LongAccumulator>> 
groupMaxRT  = new ConcurrentHashMap<>();
 
     @Override
     public void inc(S source, K metricName) {
@@ -84,7 +85,6 @@ public abstract class SimpleMetricsCountSampler<S, K, M 
extends Metric>
             return true;
         });
     }
-
     @Override
     public void addRT(S source, Long rt) {
         MetricsCountSampleConfigurer<S, K, M> sampleConfigure = new 
MetricsCountSampleConfigurer<>();
@@ -94,16 +94,16 @@ public abstract class SimpleMetricsCountSampler<S, K, M 
extends Metric>
 
         M metric = sampleConfigure.getMetric();
 
-        AtomicLongArray rtArray = 
ConcurrentHashMapUtils.computeIfAbsent(this.rtArray, metric, k -> new 
AtomicLongArray(4));
+        AtomicLongArray rtCalculator = 
ConcurrentHashMapUtils.computeIfAbsent(this.rtSample, metric, k -> new 
AtomicLongArray(4));
 
         // set lastRT
-        rtArray.set(0, rt);
+        rtCalculator.set(0, rt);
 
         // add to totalRT
-        rtArray.addAndGet(1, rt);
+        rtCalculator.addAndGet(1, rt);
 
         // add to rtCount
-        rtArray.incrementAndGet(2);
+        rtCalculator.incrementAndGet(2);
 
         // calc avgRT. In order to reduce the amount of calculation, 
calculated when collect
         //rtArray.set(3, Math.floorDiv(rtArray.get(1), rtArray.get(2)));
@@ -119,6 +119,49 @@ public abstract class SimpleMetricsCountSampler<S, K, M 
extends Metric>
         sampleConfigure.getFireEventHandler().accept(sampleConfigure);
     }
 
+    @Override
+    public void addRT(S source, K metricName, Long rt) {
+        MetricsCountSampleConfigurer<S,K,M> sampleConfigure = new 
MetricsCountSampleConfigurer<>();
+        sampleConfigure.setSource(source);
+        sampleConfigure.setMetricsName(metricName);
+
+        this.rtConfigure(sampleConfigure);
+
+        M metric = sampleConfigure.getMetric();
+
+        ConcurrentMap<M, AtomicLongArray> nameToCalculator = 
rtGroupSample.get(metricName);
+
+        if (nameToCalculator == null) {
+            ConcurrentHashMap<M, AtomicLongArray> calculator = new 
ConcurrentHashMap<>();
+            calculator.put(metric, new AtomicLongArray(4));
+
+            rtGroupSample.put(metricName,calculator);
+
+            nameToCalculator = rtGroupSample.get(metricName);
+        }
+        AtomicLongArray calculator = nameToCalculator.get(metric);
+
+        // set lastRT
+        calculator.set(0, rt);
+
+        // add to totalRT
+        calculator.addAndGet(1, rt);
+
+        // add to rtCount
+        calculator.incrementAndGet(2);
+
+        ConcurrentMap<M, LongAccumulator> minRT = 
ConcurrentHashMapUtils.computeIfAbsent(groupMinRT, metricName, k -> new 
ConcurrentHashMap<>());
+        LongAccumulator min = ConcurrentHashMapUtils.computeIfAbsent(minRT, 
metric, k -> new LongAccumulator(Long::min, Long.MAX_VALUE));
+        min.accumulate(rt);
+
+        ConcurrentMap<M, LongAccumulator> maxRT = 
ConcurrentHashMapUtils.computeIfAbsent(groupMaxRT, metricName, k -> new 
ConcurrentHashMap<>());
+        LongAccumulator max = ConcurrentHashMapUtils.computeIfAbsent(maxRT, 
metric, k -> new LongAccumulator(Long::max, Long.MIN_VALUE));
+        max.accumulate(rt);
+        sampleConfigure.setRt(rt);
+
+        sampleConfigure.getFireEventHandler().accept(sampleConfigure);
+    }
+
     @Override
     public Optional<ConcurrentMap<M, AtomicLong>> getCount(K metricName) {
         return Optional.ofNullable(metricCounter.get(metricName) == null ?
@@ -128,29 +171,40 @@ public abstract class SimpleMetricsCountSampler<S, K, M 
extends Metric>
 
     @Override
     public <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M, 
R> factory) {
-        final List<R> rtMetricSamples = new ArrayList<>();
-        rtArray.forEach((k, v) -> {
+        return collect(factory, rtSample, this.minRT, this.maxRT);
+    }
+
+    public  <R extends MetricSample> List<R> collectRT(MetricSampleFactory<M, 
R> factory,K metricName){
+        return collect(factory, rtGroupSample.get(metricName), 
groupMinRT.get(metricName),
+            groupMaxRT.get(metricName));
+    }
+
+    private <R extends MetricSample> List<R> collect(MetricSampleFactory<M, R> 
factory,
+                                                  ConcurrentMap<M, 
AtomicLongArray> rtSample,
+                                                  ConcurrentMap<M, 
LongAccumulator> min,
+                                                  ConcurrentMap<M, 
LongAccumulator> max){
+        final List<R> result = new ArrayList<>();
+        rtSample.forEach((k, v) -> {
             // lastRT
-            rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, 
k, v.get(0)));
+            result.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, 
v.get(0)));
             // totalRT
             long totalRT = v.get(1);
             long rtCount = v.get(2);
-            rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, 
k, totalRT));
+            result.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, 
totalRT));
             // avgRT
-            rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, 
k, Math.floorDiv(totalRT, rtCount)));
+            result.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, 
Math.floorDiv(totalRT, rtCount)));
         });
 
-        this.minRT.forEach((k, v) ->
-            rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, 
k, v.get())));
+        min.forEach((k, v) ->
+            result.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, 
v.get())));
 
-        this.maxRT.forEach((k, v) ->
-            rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, 
k, v.get())));
+        max.forEach((k, v) ->
+            result.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, 
v.get())));
 
-        return rtMetricSamples;
+        return result;
     }
 
     protected void rtConfigure(MetricsCountSampleConfigurer<S, K, M> 
configure) {
-
     }
 
     protected abstract void countConfigure(MetricsCountSampleConfigurer<S, K, 
M> sampleConfigure);
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
index 17ad4bb5e3..6198f76261 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java
@@ -15,70 +15,84 @@
  * limitations under the License.
  */
 package org.apache.dubbo.metrics.collector.sample;
-
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
 import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
 import org.apache.dubbo.metrics.model.MetricsKey;
 import org.apache.dubbo.metrics.model.ThreadPoolMetric;
 import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
 import org.apache.dubbo.metrics.model.sample.MetricSample;
-
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
-import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ThreadPoolExecutor;
-
+import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION;
 import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL;
 
 public class ThreadPoolMetricsSampler implements MetricsSampler {
 
-    private final DefaultMetricsCollector collector;
+    private final ErrorTypeAwareLogger logger = 
LoggerFactory.getErrorTypeAwareLogger(ThreadPoolMetricsSampler.class);
+
+    private DefaultMetricsCollector collector;
     private FrameworkExecutorRepository frameworkExecutorRepository;
-    private final Set<ThreadPoolMetric> threadPoolMetricSet = new HashSet<>();
+    private Map<String, ThreadPoolExecutor> sampleThreadPoolExecutor = new 
ConcurrentHashMap<>();
 
     public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) {
         this.collector = collector;
+        this.registryDefaultSampleThreadPoolExecutor();
+    }
+
+    public void addExecutors(String name, ExecutorService executorService) {
+        Optional.ofNullable(executorService).filter(Objects::nonNull).filter(e 
-> e instanceof ThreadPoolExecutor)
+            .map(e -> (ThreadPoolExecutor) e)
+            .ifPresent(threadPoolExecutor -> 
sampleThreadPoolExecutor.put(name, threadPoolExecutor));
     }
 
     @Override
     public List<MetricSample> sample() {
-        collect();
         List<MetricSample> metricSamples = new ArrayList<>();
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_CORE_SIZE, e.getTags(), THREAD_POOL, 
e::getCorePoolSize)));
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_LARGEST_SIZE, e.getTags(), 
THREAD_POOL, e::getLargestPoolSize)));
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_MAX_SIZE, e.getTags(), THREAD_POOL, 
e::getMaximumPoolSize)));
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_ACTIVE_SIZE, e.getTags(), THREAD_POOL, 
e::getActiveCount)));
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_THREAD_COUNT, e.getTags(), 
THREAD_POOL, e::getPoolSize)));
-        threadPoolMetricSet.forEach(e -> metricSamples.add(new 
GaugeMetricSample(MetricsKey.THREAD_POOL_QUEUE_SIZE, e.getTags(), THREAD_POOL, 
e::getQueueSize)));
+
+        sampleThreadPoolExecutor.forEach((name, executor)->{
+            metricSamples.addAll(createMetricsSample(name,executor));
+        });
 
         return metricSamples;
     }
 
-    private void collect() {
+    private List<MetricSample> createMetricsSample(String 
name,ThreadPoolExecutor executor) {
+        List<MetricSample> list = new ArrayList<>();
+        ThreadPoolMetric poolMetrics = new 
ThreadPoolMetric(collector.getApplicationName(), name, executor);
+
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_CORE_SIZE, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getCorePoolSize));
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_LARGEST_SIZE, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getLargestPoolSize));
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_MAX_SIZE, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getMaximumPoolSize));
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_ACTIVE_SIZE, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getActiveCount));
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_THREAD_COUNT, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getPoolSize));
+        list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_QUEUE_SIZE, 
poolMetrics.getTags(), THREAD_POOL, poolMetrics::getQueueSize));
+
+        return list;
+    }
+
+    private void registryDefaultSampleThreadPoolExecutor() {
         try {
             if (this.frameworkExecutorRepository == null) {
-                this.frameworkExecutorRepository = 
collector.getApplicationModel().getFrameworkModel().getBeanFactory().getBean(FrameworkExecutorRepository.class);
+                this.frameworkExecutorRepository = 
collector.getApplicationModel()
+                    .getFrameworkModel().getBeanFactory()
+                    .getBean(FrameworkExecutorRepository.class);
             }
-        } catch (Exception ignored) {
+        } catch (Exception ex) {
+            logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", 
"ThreadPoolMetricsSampler! frameworkExecutorRepository non-init");
         }
-
-        if (frameworkExecutorRepository != null) {
-            addThread("SharedExecutor", 
frameworkExecutorRepository.getSharedExecutor());
-            addThread("MappingRefreshingExecutor", 
frameworkExecutorRepository.getMappingRefreshingExecutor());
-            addThread("PoolRouterExecutor", 
frameworkExecutorRepository.getPoolRouterExecutor());
+        if (this.frameworkExecutorRepository != null) {
+            this.addExecutors("sharedExecutor", 
frameworkExecutorRepository.getSharedExecutor());
+            this.addExecutors("mappingRefreshingExecutor", 
frameworkExecutorRepository.getMappingRefreshingExecutor());
+            this.addExecutors("poolRouterExecutor", 
frameworkExecutorRepository.getPoolRouterExecutor());
         }
     }
 
-    private void addThread(String threadPoolName, ExecutorService 
executorService) {
-        Optional<ExecutorService> executorOptional = 
Optional.ofNullable(executorService);
-        if (executorOptional.isPresent() && executorOptional.get() instanceof 
ThreadPoolExecutor) {
-            threadPoolMetricSet.add(
-                    new ThreadPoolMetric(collector.getApplicationName(), 
threadPoolName,
-                            (ThreadPoolExecutor) executorOptional.get()));
-        }
-
-    }
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
index 9dd6113909..a66c42139d 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java
@@ -16,15 +16,11 @@
  */
 
 package org.apache.dubbo.metrics.filter;
-
 import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler;
 import org.apache.dubbo.metrics.event.MetricsEvent;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-
-import java.util.function.Supplier;
-
 import static 
org.apache.dubbo.common.constants.MetricsConstants.METRIC_FILTER_START_TIME;
 
 public class MethodMetricsInterceptor {
@@ -35,60 +31,61 @@ public class MethodMetricsInterceptor {
         this.sampler = sampler;
     }
 
-    public void beforeExecute(Invocation invocation) {
+    public void beforeMethod(Invocation invocation) {
         sampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL);
         sampler.incOnEvent(invocation,MetricsEvent.Type.PROCESSING);
         invocation.put(METRIC_FILTER_START_TIME, System.currentTimeMillis());
     }
 
-    public void postExecute(Invocation invocation, Result result) {
+    public void afterMethod(Invocation invocation, Result result) {
         if (result.hasException()) {
-            throwExecute(invocation, result.getException());
-            return;
+            handleMethodException(invocation, result.getException());
+        }else{
+            sampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED);
+            onCompleted(invocation);
         }
-        sampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED);
-        endExecute(invocation);
     }
 
-    public void throwExecute(Invocation invocation, Throwable throwable) {
-        if (throwable instanceof RpcException) {
-            RpcException rpcException = (RpcException) throwable;
-            switch (rpcException.getCode()) {
-
-                case RpcException.TIMEOUT_EXCEPTION:
-                    
sampler.incOnEvent(invocation,MetricsEvent.Type.REQUEST_TIMEOUT);
-                    break;
+    public void handleMethodException(Invocation invocation, Throwable 
throwable) {
+        if (throwable == null) {
+            return;
+        }
 
-                case RpcException.LIMIT_EXCEEDED_EXCEPTION:
-                    
sampler.incOnEvent(invocation,MetricsEvent.Type.REQUEST_LIMIT);
-                    break;
+        if (throwable instanceof RpcException) {
+            RpcException e = (RpcException) throwable;
 
-                case RpcException.BIZ_EXCEPTION:
-                    
sampler.incOnEvent(invocation,MetricsEvent.Type.BUSINESS_FAILED);
-                    break;
+            MetricsEvent.Type eventType = MetricsEvent.Type.UNKNOWN_FAILED;
 
-                default:
-                    
sampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED);
+            if (e.isTimeout()) {
+                eventType = MetricsEvent.Type.REQUEST_TIMEOUT;
+            }
+            if (e.isLimitExceed()) {
+                eventType = MetricsEvent.Type.REQUEST_LIMIT;
             }
+            if (e.isBiz()) {
+                eventType = MetricsEvent.Type.BUSINESS_FAILED;
+            }
+            if (e.isSerialization()) {
+                eventType = MetricsEvent.Type.CODEC_EXCEPTION;
+            }
+            if (e.isNetwork()) {
+                eventType = MetricsEvent.Type.NETWORK_EXCEPTION;
+            }
+            sampler.incOnEvent(invocation,eventType);
         }
 
-        sampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL_FAILED);
-
-        endExecute(invocation, () -> throwable instanceof RpcException && 
((RpcException) throwable).isBiz());
-    }
+        if (throwable instanceof RpcException && ((RpcException) 
throwable).isBiz()) {
+            onCompleted(invocation);
+        }
 
-    private void endExecute(Invocation invocation) {
-        endExecute(invocation, () -> true);
+        sampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL_FAILED);
     }
 
-    private void endExecute(Invocation invocation, Supplier<Boolean> rtStat) {
-        if (rtStat.get()) {
-            Long endTime = System.currentTimeMillis();
-            Long beginTime = (Long) invocation.get(METRIC_FILTER_START_TIME);
-            Long rt = endTime - beginTime;
-            sampler.addRT(invocation, rt);
-        }
+    private void onCompleted(Invocation invocation) {
+        Long endTime = System.currentTimeMillis();
+        Long beginTime = (Long) invocation.get(METRIC_FILTER_START_TIME);
+        Long rt = endTime - beginTime;
+        sampler.addRT(invocation, rt);
         sampler.dec(invocation,MetricsEvent.Type.PROCESSING);
     }
-
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java
similarity index 66%
copy from 
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
copy to 
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java
index 51c89a40ae..114b191fa0 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java
@@ -14,66 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.metrics.filter;
 
+package org.apache.dubbo.metrics.filter;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
+import org.apache.dubbo.metrics.event.MetricsEvent;
 import org.apache.dubbo.rpc.BaseFilter;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ScopeModelAware;
-
 import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
-
-@Activate(group = {CONSUMER, PROVIDER}, order = -1)
-public class MetricsFilter implements Filter, BaseFilter.Listener, 
ScopeModelAware {
-
-    private DefaultMetricsCollector collector = null;
 
-    private MethodMetricsInterceptor metricsInterceptor;
+@Activate(group = CONSUMER)
+public class MetricsClusterFilter implements ClusterFilter, 
BaseFilter.Listener, ScopeModelAware {
 
+    private DefaultMetricsCollector collector;
 
     @Override
     public void setApplicationModel(ApplicationModel applicationModel) {
-        collector = 
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
-
-        if (collector != null) {
-            metricsInterceptor = new 
MethodMetricsInterceptor(collector.getMethodSampler());
-        }
-
+        this.collector = 
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
     }
 
     @Override
     public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
-        if (collector == null || !collector.isCollectEnabled()) {
-            return invoker.invoke(invocation);
-        }
-
-        metricsInterceptor.beforeExecute(invocation);
-
         return invoker.invoke(invocation);
-
     }
 
     @Override
     public void onResponse(Result result, Invoker<?> invoker, Invocation 
invocation) {
-        if (collector == null || !collector.isCollectEnabled()) {
-            return;
-        }
-        metricsInterceptor.postExecute(invocation, result);
+        handleMethodException(result.getException(), invocation);
     }
 
     @Override
     public void onError(Throwable t, Invoker<?> invoker, Invocation 
invocation) {
+        handleMethodException(t, invocation);
+    }
+
+    private void handleMethodException(Throwable t, Invocation invocation) {
         if (collector == null || !collector.isCollectEnabled()) {
             return;
         }
-        metricsInterceptor.throwExecute(invocation, t);
+        if (t != null && t instanceof RpcException) {
+            RpcException e = (RpcException) t;
+            if (e.isForbidden()) {
+                collector.getMethodSampler().incOnEvent(invocation, 
MetricsEvent.Type.SERVICE_UNAVAILABLE);
+            }
+        }
     }
-
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
index 51c89a40ae..c981f62831 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java
@@ -34,10 +34,8 @@ import static 
org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
 public class MetricsFilter implements Filter, BaseFilter.Listener, 
ScopeModelAware {
 
     private DefaultMetricsCollector collector = null;
-
     private MethodMetricsInterceptor metricsInterceptor;
 
-
     @Override
     public void setApplicationModel(ApplicationModel applicationModel) {
         collector = 
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
@@ -45,7 +43,6 @@ public class MetricsFilter implements Filter, 
BaseFilter.Listener, ScopeModelAwa
         if (collector != null) {
             metricsInterceptor = new 
MethodMetricsInterceptor(collector.getMethodSampler());
         }
-
     }
 
     @Override
@@ -54,10 +51,9 @@ public class MetricsFilter implements Filter, 
BaseFilter.Listener, ScopeModelAwa
             return invoker.invoke(invocation);
         }
 
-        metricsInterceptor.beforeExecute(invocation);
+        metricsInterceptor.beforeMethod(invocation);
 
         return invoker.invoke(invocation);
-
     }
 
     @Override
@@ -65,7 +61,7 @@ public class MetricsFilter implements Filter, 
BaseFilter.Listener, ScopeModelAwa
         if (collector == null || !collector.isCollectEnabled()) {
             return;
         }
-        metricsInterceptor.postExecute(invocation, result);
+        metricsInterceptor.afterMethod(invocation, result);
     }
 
     @Override
@@ -73,7 +69,7 @@ public class MetricsFilter implements Filter, 
BaseFilter.Listener, ScopeModelAwa
         if (collector == null || !collector.isCollectEnabled()) {
             return;
         }
-        metricsInterceptor.throwExecute(invocation, t);
+        metricsInterceptor.handleMethodException(invocation, t);
     }
 
 }
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
 
b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
index 8407d6c769..5714fefb30 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
@@ -1 +1,2 @@
 observationsender=org.apache.dubbo.metrics.observation.ObservationSenderFilter
+metricsClusterFilter=org.apache.dubbo.metrics.filter.MetricsClusterFilter
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java
 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java
index c12e3ef335..bba5f0a1ee 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java
@@ -105,10 +105,14 @@ class AggregateMetricsCollectorTest {
         defaultCollector.setApplicationName(applicationName);
         MethodMetricsSampler methodMetricsCountSampler = 
defaultCollector.getMethodSampler();
 
-        methodMetricsCountSampler.incOnEvent(invocation, 
MetricsEvent.Type.TOTAL);
-        methodMetricsCountSampler.incOnEvent(invocation, 
MetricsEvent.Type.SUCCEED);
-        methodMetricsCountSampler.incOnEvent(invocation, 
MetricsEvent.Type.UNKNOWN_FAILED);
-        methodMetricsCountSampler.incOnEvent(invocation, 
MetricsEvent.Type.BUSINESS_FAILED);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.BUSINESS_FAILED);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.NETWORK_EXCEPTION);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SERVICE_UNAVAILABLE);
+        
methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.CODEC_EXCEPTION);
+
 
         List<MetricSample> samples = collector.collect();
         for (MetricSample sample : samples) {
@@ -131,6 +135,10 @@ class AggregateMetricsCollectorTest {
         
Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_FAILED_AGG.getNameByType(side)),
 1L);
         
Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG.getNameByType(side)),
 1L);
 
+        
Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG.getNameByType(side)),
 1L);
+        
Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG.getNameByType(side)),
 1L);
+        
Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG.getNameByType(side)),
 1L);
+
         
Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_QPS.getNameByType(side)));
     }
 
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java
 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java
index f18115607f..11029fef55 100644
--- 
a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java
@@ -44,6 +44,11 @@ import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
 import static 
org.apache.dubbo.common.constants.CommonConstants.GENERIC_PARAMETER_DESC;
 import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY;
@@ -57,6 +62,7 @@ class MetricsFilterTest {
 
     private ApplicationModel applicationModel;
     private MetricsFilter filter;
+    private MetricsClusterFilter metricsClusterFilter;
     private DefaultMetricsCollector collector;
     private RpcInvocation invocation;
     private final Invoker<?> invoker = mock(Invoker.class);
@@ -86,6 +92,8 @@ class MetricsFilterTest {
         invocation.setInvoker(new TestMetricsInvoker(side));
         
RpcContext.getServiceContext().setUrl(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side="
 + side));
 
+        metricsClusterFilter = new MetricsClusterFilter();
+        metricsClusterFilter.setApplicationModel(applicationModel);
     }
 
     @AfterEach
@@ -128,7 +136,6 @@ class MetricsFilterTest {
         Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION);
     }
 
-
     @Test
     void testBusinessFailedRequests() {
         collector.setCollectEnabled(true);
@@ -257,6 +264,78 @@ class MetricsFilterTest {
         Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION);
     }
 
+    @Test
+    public void testErrors(){
+        testFilterError(RpcException.SERIALIZATION_EXCEPTION, 
MetricsKey.METRIC_REQUESTS_CODEC_FAILED.formatName(side));
+        testFilterError(RpcException.NETWORK_EXCEPTION, 
MetricsKey.METRIC_REQUESTS_NETWORK_FAILED.formatName(side));
+    }
+
+    @Test
+    public void testNoProvider(){
+        testClusterFilterError(RpcException.FORBIDDEN_EXCEPTION,
+            
MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED.formatName(CommonConstants.CONSUMER));
+    }
+
+    private void testClusterFilterError(int errorCode,MetricsKey metricsKey){
+        setup();
+        collector.setCollectEnabled(true);
+        given(invoker.invoke(invocation)).willThrow(new 
RpcException(errorCode));
+        initParam();
+
+        Long count = 1L;
+
+        for (int i = 0; i < count; i++) {
+            try {
+                metricsClusterFilter.invoke(invoker, invocation);
+            } catch (Exception e) {
+                Assertions.assertTrue(e instanceof RpcException);
+                metricsClusterFilter.onError(e, invoker, invocation);
+            }
+        }
+        Map<String, MetricSample> metricsMap = getMetricsMap();
+        Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName()));
+
+        MetricSample sample = metricsMap.get(metricsKey.getName());
+
+        Assertions.assertSame(((GaugeMetricSample) 
sample).getSupplier().get().longValue(), count);
+        teardown();
+    }
+
+    private void testFilterError(int errorCode,MetricsKey metricsKey){
+        setup();
+        collector.setCollectEnabled(true);
+        given(invoker.invoke(invocation)).willThrow(new 
RpcException(errorCode));
+        initParam();
+
+        Long count = 1L;
+
+        for (int i = 0; i < count; i++) {
+            try {
+                filter.invoke(invoker, invocation);
+            } catch (Exception e) {
+                Assertions.assertTrue(e instanceof RpcException);
+                filter.onError(e, invoker, invocation);
+            }
+        }
+        Map<String, MetricSample> metricsMap = getMetricsMap();
+        Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName()));
+
+        MetricSample sample = metricsMap.get(metricsKey.getName());
+
+        Assertions.assertSame(((GaugeMetricSample) 
sample).getSupplier().get().longValue(), count);
+
+
+        Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName()));
+        Map<String, String> tags = sample.getTags();
+
+        Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), INTERFACE_NAME);
+        Assertions.assertEquals(tags.get(TAG_METHOD_KEY), METHOD_NAME);
+        Assertions.assertEquals(tags.get(TAG_GROUP_KEY), GROUP);
+        Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION);
+
+        teardown();
+    }
+
     @Test
     void testMissingVersion() {
         collector.setCollectEnabled(true);
diff --git 
a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java
 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java
new file mode 100644
index 0000000000..98cab8f0d6
--- /dev/null
+++ 
b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dubbo.metrics.sampler;
+
+import org.apache.dubbo.metrics.collector.sample.MetricsCountSampleConfigurer;
+import org.apache.dubbo.metrics.collector.sample.SimpleMetricsCountSampler;
+import org.apache.dubbo.metrics.model.MethodMetric;
+import org.apache.dubbo.metrics.model.Metric;
+import org.apache.dubbo.metrics.model.MetricsCategory;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import static org.apache.dubbo.metrics.model.MetricsCategory.RT;
+
+public class CountSamplerTest {
+
+    public RequestMetricsCountSampler sampler = new 
RequestMetricsCountSampler();
+
+    @BeforeEach
+    public void before() {
+        sampler = new RequestMetricsCountSampler();
+    }
+
+    @Test
+    public void rtTest() {
+        String applicationName = "test";
+
+        sampler.addRT(applicationName, RTType.METHOD_REQUEST, 2L);
+        Map<String, GaugeMetricSample> collect = 
getCollect(RTType.METHOD_REQUEST);
+
+        Assertions.assertNotNull(collect);
+
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 2);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 2);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 2);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 2);
+
+        sampler.addRT(applicationName, RTType.METHOD_REQUEST, 1L);
+        collect = getCollect(RTType.METHOD_REQUEST);
+
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 1);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 1);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 1);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 3);
+
+        sampler.addRT(applicationName, RTType.APPLICATION, 4L);
+        collect = getCollect(RTType.APPLICATION);
+
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 4);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 4);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 4);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 4);
+        Assertions.assertTrue(
+            null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && 
collect.get(
+                
MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 4);
+    }
+
+    @NotNull
+    private Map<String, GaugeMetricSample> getCollect(RTType rtType) {
+        List<GaugeMetricSample> metricSamples = sampler.collectRT((key, 
metric, count) -> new GaugeMetricSample(key.formatName("consumer"), 
metric.getTags(), RT, () -> count),rtType);
+
+        Map<String, GaugeMetricSample> collect = metricSamples.stream()
+            .collect(Collectors.toMap(MetricSample::getName, v -> v));
+        return collect;
+    }
+
+    private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, 
MethodMetric methodMetric,
+                                                   MetricsCategory 
metricsCategory, Supplier<Number> get) {
+        return new 
GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), 
metricsKey.getDescription(),
+            methodMetric.getTags(), metricsCategory, get);
+    }
+
+
+    public class RequestMetricsCountSampler
+        extends SimpleMetricsCountSampler<String, RTType, 
RequestMethodMetrics> {
+
+        @Override
+        public List<MetricSample> sample() {
+            return null;
+        }
+
+        @Override
+        protected void countConfigure(
+            MetricsCountSampleConfigurer<String, RTType, RequestMethodMetrics> 
sampleConfigure) {
+            sampleConfigure.configureMetrics(
+                configure -> new RequestMethodMetrics(configure.getSource()));
+            sampleConfigure.configureEventHandler(configure -> {
+                System.out.println("generic event");
+            });
+        }
+
+        @Override
+        public void rtConfigure(
+            MetricsCountSampleConfigurer<String, RTType, RequestMethodMetrics> 
sampleConfigure) {
+            sampleConfigure.configureMetrics(configure -> new 
RequestMethodMetrics(configure.getSource()));
+            sampleConfigure.configureEventHandler(configure -> {
+                System.out.println("rt event");
+            });
+        }
+    }
+
+    static enum RTType{
+        METHOD_REQUEST,
+        APPLICATION
+    }
+
+    static class RequestMethodMetrics implements Metric {
+
+        private String applicationName;
+
+        public RequestMethodMetrics(String applicationName) {
+            this.applicationName=applicationName;
+        }
+        @Override
+        public Map<String, String> getTags() {
+            Map<String,String> tags = new HashMap<>();
+            tags.put("serviceName", "test");
+            tags.put("version", "1.0.0");
+            tags.put("uptime", "20220202");
+            return tags;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (!(o instanceof RequestMethodMetrics))
+                return false;
+            RequestMethodMetrics that = (RequestMethodMetrics) o;
+            return Objects.equals(applicationName, that.applicationName);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(applicationName);
+        }
+    }
+
+}
+

Reply via email to