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 671e0f8bb9 Observability task: metadata center (#11593)
671e0f8bb9 is described below
commit 671e0f8bb9b7ebb447314660eea062869283888f
Author: wxbty <[email protected]>
AuthorDate: Wed Feb 22 20:44:58 2023 +0800
Observability task: metadata center (#11593)
* init metadata
* add pom
* add licence
* add licence
* remove unuse pom
* remove unuse pom
* remove unuse pom
* fix test
* fix test
* fix test
* fix pom
* use applicationModel
* remove unuse
* add test
* add push testcase
* add test case
* add test case
* add testcase
* rename
* opt
* debug
* fix testcase
* add pom
---------
Co-authored-by: x-shadow-man <[email protected]>
---
.../org/apache/dubbo/config/MetricsConfig.java | 19 +-
dubbo-config/dubbo-config-api/pom.xml | 6 +
.../config/deploy/DefaultApplicationDeployer.java | 2 +-
dubbo-distribution/dubbo-all/pom.xml | 8 +
dubbo-distribution/dubbo-bom/pom.xml | 5 +
.../collector/ApplicationMetricsCollector.java | 8 +-
.../dubbo/metrics/collector/MetricsCollector.java | 9 +-
.../event/GlobalMetricsEventMulticaster.java | 12 +-
.../metrics/listener/MetricsLifeListener.java | 6 +-
.../dubbo/metrics/listener/MetricsListener.java | 3 +-
.../org/apache/dubbo/metrics/model/MetricsKey.java | 26 ++-
.../dubbo/metrics/model/MetricsKeyWrapper.java | 4 +-
.../event/SimpleMetricsEventMulticasterTest.java | 8 +-
.../metrics/MetricsScopeModelInitializer.java | 2 +-
dubbo-metrics/{ => dubbo-metrics-metadata}/pom.xml | 17 +-
.../collector/MetadataMetricsCollector.java | 111 +++++++++++
.../collector/stat/MetadataStatComposite.java | 212 +++++++++++++++++++++
.../metrics/metadata/event/MetadataEvent.java | 109 +++++++++++
.../event/MetadataMetricsEventMulticaster.java} | 23 +--
.../metadata/event/MetricsPushListener.java | 49 +++++
.../metadata/event/MetricsSubscribeListener.java | 49 +++++
...apache.dubbo.metrics.collector.MetricsCollector | 1 +
.../collector/MetadataMetricsCollectorTest.java | 168 ++++++++++++++++
dubbo-metrics/pom.xml | 1 +
.../META-INF/native-image/reflect-config.json | 12 +-
dubbo-registry/dubbo-registry-api/pom.xml | 18 ++
.../registry/client/AbstractServiceDiscovery.java | 39 +++-
dubbo-test/dubbo-dependencies-all/pom.xml | 4 +
28 files changed, 861 insertions(+), 70 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
index 8811d5d612..1b8340138b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java
@@ -16,9 +16,6 @@
*/
package org.apache.dubbo.config;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.nested.AggregationConfig;
@@ -26,6 +23,9 @@ import org.apache.dubbo.config.nested.PrometheusConfig;
import org.apache.dubbo.config.support.Nested;
import org.apache.dubbo.rpc.model.ApplicationModel;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* MetricsConfig
*/
@@ -40,6 +40,11 @@ public class MetricsConfig extends AbstractConfig {
*/
private Boolean enableJvmMetrics;
+ /**
+ * Enable jvm metrics when collecting.
+ */
+ private Boolean enableMetadataMetrics;
+
/**
* @deprecated After metrics config is refactored.
* This parameter should no longer use and will be deleted in the future.
@@ -137,5 +142,13 @@ public class MetricsConfig extends AbstractConfig {
public void setExportServicePort(Integer exportServicePort) {
this.exportServicePort = exportServicePort;
}
+
+ public Boolean getEnableMetadataMetrics() {
+ return enableMetadataMetrics;
+ }
+
+ public void setEnableMetadataMetrics(Boolean enableMetadataMetrics) {
+ this.enableMetadataMetrics = enableMetadataMetrics;
+ }
}
diff --git a/dubbo-config/dubbo-config-api/pom.xml
b/dubbo-config/dubbo-config-api/pom.xml
index c863389111..2ba42d26a3 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -48,6 +48,12 @@
<version>${project.parent.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-api</artifactId>
diff --git
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
index e5853a9f4c..c526864ab4 100644
---
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
+++
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
@@ -359,7 +359,7 @@ public class DefaultApplicationDeployer extends
AbstractDeployer<ApplicationMode
private void initMetricsReporter() {
DefaultMetricsCollector collector =
-
applicationModel.getFrameworkModel().getBeanFactory().getBean(DefaultMetricsCollector.class);
+
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
MetricsConfig metricsConfig = configManager.getMetrics().orElse(null);
// TODO compatible with old usage of metrics, remove protocol check
after new metrics is ready for use.
if (metricsConfig != null &&
PROTOCOL_PROMETHEUS.equals(metricsConfig.getProtocol())) {
diff --git a/dubbo-distribution/dubbo-all/pom.xml
b/dubbo-distribution/dubbo-all/pom.xml
index 23b1192686..7e96659152 100644
--- a/dubbo-distribution/dubbo-all/pom.xml
+++ b/dubbo-distribution/dubbo-all/pom.xml
@@ -197,6 +197,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
<!-- monitor -->
<dependency>
@@ -495,6 +502,7 @@
<include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
<include>org.apache.dubbo:dubbo-metrics-api</include>
<include>org.apache.dubbo:dubbo-metrics-default</include>
+
<include>org.apache.dubbo:dubbo-metrics-metadata</include>
<include>org.apache.dubbo:dubbo-metrics-prometheus</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-monitor-default</include>
diff --git a/dubbo-distribution/dubbo-bom/pom.xml
b/dubbo-distribution/dubbo-bom/pom.xml
index 4b22ec55f9..42b26038cd 100644
--- a/dubbo-distribution/dubbo-bom/pom.xml
+++ b/dubbo-distribution/dubbo-bom/pom.xml
@@ -240,6 +240,11 @@
<artifactId>dubbo-metrics-prometheus</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- monitor -->
<dependency>
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
index b437561a7b..c1dc63e5b2 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java
@@ -17,18 +17,18 @@
package org.apache.dubbo.metrics.collector;
+import org.apache.dubbo.metrics.event.MetricsEvent;
+
/**
* Application-level collector.
* registration center, configuration center and other scenarios
*
* @Params <T> metrics type
*/
-public interface ApplicationMetricsCollector<T> extends MetricsCollector {
+public interface ApplicationMetricsCollector<T, E extends MetricsEvent>
extends MetricsCollector<E> {
void increment(String applicationName, T type);
- void decrease(String applicationName, T type);
-
- void addRT(String applicationName, Long responseTime);
+ void addRT(String applicationName, String registryOpType, Long
responseTime);
}
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
index d722f77547..3436d4f829 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java
@@ -19,7 +19,7 @@ package org.apache.dubbo.metrics.collector;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.metrics.event.MetricsEvent;
-import org.apache.dubbo.metrics.listener.MetricsListener;
+import org.apache.dubbo.metrics.listener.MetricsLifeListener;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import java.util.List;
@@ -29,11 +29,12 @@ import java.util.List;
* An interface of collector to collect framework internal metrics.
*/
@SPI
-public interface MetricsCollector extends MetricsListener {
+public interface MetricsCollector<E extends MetricsEvent> extends
MetricsLifeListener<E> {
default boolean isCollectEnabled() {
return false;
}
+
/**
* Collect metrics as {@link MetricSample}
*
@@ -41,8 +42,4 @@ public interface MetricsCollector extends MetricsListener {
*/
List<MetricSample> collect();
- @Override
- default void onEvent(MetricsEvent event) {
-
- }
}
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java
index b5d4effdfe..28f01d5c27 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java
@@ -20,15 +20,19 @@ package org.apache.dubbo.metrics.event;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.metrics.collector.MetricsCollector;
-import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.List;
+/**
+ * Global spi event publisher
+ */
public class GlobalMetricsEventMulticaster extends
SimpleMetricsEventMulticaster {
- public GlobalMetricsEventMulticaster(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- ExtensionLoader<MetricsCollector> extensionLoader =
frameworkModel.getExtensionLoader(MetricsCollector.class);
+ @SuppressWarnings({"rawtypes"})
+ public GlobalMetricsEventMulticaster(ApplicationModel applicationModel) {
+ ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
+ ExtensionLoader<MetricsCollector> extensionLoader =
applicationModel.getExtensionLoader(MetricsCollector.class);
if (extensionLoader != null) {
List<MetricsCollector> customizeCollectors = extensionLoader
.getActivateExtensions();
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
index 80098f67bf..bee82056be 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java
@@ -24,7 +24,9 @@ import org.apache.dubbo.metrics.event.MetricsEvent;
*/
public interface MetricsLifeListener<E extends MetricsEvent> extends
MetricsListener<E> {
- void onEventFinish(E event);
+ default void onEventFinish(E event) {
+ }
- void onEventError(E event);
+ default void onEventError(E event) {
+ }
}
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
index 058f583e94..64b4796af3 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
@@ -33,6 +33,7 @@ public interface MetricsListener<E extends MetricsEvent> {
*
* @param event BaseMetricsEvent
*/
- void onEvent(E event);
+ default void onEvent(E event) {
+ }
}
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 7649af788a..96c879c8dd 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
@@ -30,7 +30,6 @@ public enum MetricsKey {
METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Unknown
Failed Requests"),
METRIC_REQUESTS_TOTAL_FAILED("dubbo.%s.requests.failed.total", "Total
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"),
METRIC_REQUESTS_FAILED_AGG("dubbo.%s.requests.failed.aggregate",
"Aggregated Failed Requests"),
@@ -60,12 +59,25 @@ public enum MetricsKey {
GENERIC_METRIC_RT_P99("dubbo.%s.rt.seconds.p99", "Response Time P99"),
GENERIC_METRIC_RT_P95("dubbo.%s.rt.seconds.p95", "Response Time P95"),
- THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size","Thread Pool Core
Size"),
- THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size","Thread Pool
Largest Size"),
- THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size","Thread Pool Max Size"),
- THREAD_POOL_ACTIVE_SIZE("dubbo.thread.pool.active.size","Thread Pool
Active Size"),
- THREAD_POOL_THREAD_COUNT("dubbo.thread.pool.thread.count","Thread Pool
Thread Count"),
- THREAD_POOL_QUEUE_SIZE("dubbo.thread.pool.queue.size","Thread Pool Queue
Size");
+ THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size", "Thread Pool Core
Size"),
+ THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size", "Thread Pool
Largest Size"),
+ THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size", "Thread Pool Max Size"),
+ THREAD_POOL_ACTIVE_SIZE("dubbo.thread.pool.active.size", "Thread Pool
Active Size"),
+ THREAD_POOL_THREAD_COUNT("dubbo.thread.pool.thread.count", "Thread Pool
Thread Count"),
+ THREAD_POOL_QUEUE_SIZE("dubbo.thread.pool.queue.size", "Thread Pool Queue
Size"),
+
+ // metadata push metrics key
+ METADATA_PUSH_METRIC_NUM("dubbo.metadata.push.num.total", "Total Push
Num"),
+ METADATA_PUSH_METRIC_NUM_SUCCEED("dubbo.metadata.push.num.succeed.total",
"Succeed Push Num"),
+ METADATA_PUSH_METRIC_NUM_FAILED("dubbo.metadata.push.num.failed.total",
"Failed Push Num"),
+
+ // metadata subscribe metrics key
+ METADATA_SUBSCRIBE_METRIC_NUM("dubbo.metadata.subscribe.num.total", "Total
Metadata Subscribe Num"),
+
METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.metadata.subscribe.num.succeed.total",
"Succeed Metadata Subscribe Num"),
+
METADATA_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.metadata.subscribe.num.failed.total",
"Failed Metadata Subscribe Num"),
+
+ // consumer metrics key
+ ;
private final String name;
private final String description;
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
index 0a0afc95e8..54b791e5a8 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java
@@ -38,8 +38,8 @@ public class MetricsKeyWrapper {
return metricsKey;
}
- public boolean isKey(MetricsKey metricsKey) {
- return metricsKey == getMetricsKey();
+ public boolean isKey(MetricsKey metricsKey, String registryOpType) {
+ return metricsKey == getMetricsKey() &&
registryOpType.equals(getType());
}
public String targetKey() {
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
index de5314d803..15f6e66f23 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
+++
b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java
@@ -18,6 +18,7 @@
package org.apache.dubbo.metrics.event;
import org.apache.dubbo.metrics.listener.MetricsLifeListener;
+import org.apache.dubbo.metrics.listener.MetricsListener;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -32,7 +33,12 @@ public class SimpleMetricsEventMulticasterTest {
public void setup() {
eventMulticaster = new SimpleMetricsEventMulticaster();
obj = new Object[]{new Object()};
- eventMulticaster.addListener(event -> obj[0] = new Object());
+ eventMulticaster.addListener(new MetricsListener<MetricsEvent>() {
+ @Override
+ public void onEvent(MetricsEvent event) {
+ obj[0] = new Object();
+ }
+ });
requestEvent = new RequestEvent(obj[0], MetricsEvent.Type.TOTAL);
}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java
index 6f786b2c67..f8236f60d2 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java
@@ -34,7 +34,7 @@ public class MetricsScopeModelInitializer implements
ScopeModelInitializer {
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
- ScopeBeanFactory beanFactory =
applicationModel.getFrameworkModel().getBeanFactory();
+ ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(DefaultMetricsCollector.class);
beanFactory.registerBean(GlobalMetricsEventMulticaster.class);
}
diff --git a/dubbo-metrics/pom.xml
b/dubbo-metrics/dubbo-metrics-metadata/pom.xml
similarity index 80%
copy from dubbo-metrics/pom.xml
copy to dubbo-metrics/dubbo-metrics-metadata/pom.xml
index c504428498..f454e9558e 100644
--- a/dubbo-metrics/pom.xml
+++ b/dubbo-metrics/dubbo-metrics-metadata/pom.xml
@@ -13,35 +13,28 @@
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.
- -->
+-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
- <modules>
- <module>dubbo-metrics-api</module>
- <module>dubbo-metrics-default</module>
- <module>dubbo-metrics-prometheus</module>
- </modules>
<parent>
<groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-parent</artifactId>
+ <artifactId>dubbo-metrics</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>dubbo-metrics</artifactId>
- <packaging>pom</packaging>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ <packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The metrics module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
-
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-test-check</artifactId>
+ <artifactId>dubbo-metrics-api</artifactId>
<version>${project.parent.version}</version>
- <scope>test</scope>
</dependency>
</dependencies>
</project>
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
new file mode 100644
index 0000000000..c9140a288c
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java
@@ -0,0 +1,111 @@
+/*
+ * 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.metadata.collector;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.metrics.collector.ApplicationMetricsCollector;
+import org.apache.dubbo.metrics.collector.MetricsCollector;
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.MetricsEventMulticaster;
+import org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite;
+import org.apache.dubbo.metrics.metadata.event.MetadataEvent;
+import org.apache.dubbo.metrics.metadata.event.MetadataMetricsEventMulticaster;
+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.Optional;
+
+
+/**
+ * Registry implementation of {@link MetricsCollector}
+ */
+@Activate
+public class MetadataMetricsCollector implements
ApplicationMetricsCollector<MetadataEvent.Type, MetadataEvent> {
+
+ private Boolean collectEnabled = null;
+ private final MetadataStatComposite stats;
+ private final MetricsEventMulticaster metadataEventMulticaster;
+ private final ApplicationModel applicationModel;
+
+ public MetadataMetricsCollector(ApplicationModel applicationModel) {
+ this.stats = new MetadataStatComposite();
+ this.metadataEventMulticaster = new MetadataMetricsEventMulticaster();
+ this.applicationModel = applicationModel;
+ }
+
+ public void setCollectEnabled(Boolean collectEnabled) {
+ if (collectEnabled != null) {
+ this.collectEnabled = collectEnabled;
+ }
+ }
+
+ @Override
+ public boolean isCollectEnabled() {
+ if (collectEnabled == null) {
+ ConfigManager configManager =
applicationModel.getApplicationConfigManager();
+ configManager.getMetrics().ifPresent(metricsConfig ->
setCollectEnabled(metricsConfig.getEnableMetadataMetrics()));
+ }
+ return Optional.ofNullable(collectEnabled).orElse(false);
+ }
+
+ @Override
+ public void increment(String applicationName, MetadataEvent.Type
registryType) {
+ this.stats.increment(registryType, applicationName);
+ }
+
+ @Override
+ public void addRT(String applicationName, String registryOpType, Long
responseTime) {
+ stats.calcRt(applicationName, registryOpType, responseTime);
+ }
+
+ @Override
+ public List<MetricSample> collect() {
+ List<MetricSample> list = new ArrayList<>();
+ if (!isCollectEnabled()) {
+ return list;
+ }
+ list.addAll(stats.exportNumMetrics());
+ list.addAll(stats.exportRtMetrics());
+
+ return list;
+ }
+
+ @Override
+ public boolean isSupport(MetricsEvent event) {
+ return event instanceof MetadataEvent;
+ }
+
+ @Override
+ public void onEvent(MetadataEvent event) {
+ metadataEventMulticaster.publishEvent(event);
+ }
+
+
+ @Override
+ public void onEventFinish(MetadataEvent event) {
+ metadataEventMulticaster.publishFinishEvent(event);
+ }
+
+ @Override
+ public void onEventError(MetadataEvent event) {
+ metadataEventMulticaster.publishErrorEvent(event);
+ }
+}
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
new file mode 100644
index 0000000000..83cdbb855c
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java
@@ -0,0 +1,212 @@
+/*
+ * 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.metadata.collector.stat;
+
+import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
+import org.apache.dubbo.metrics.collector.MetricsCollector;
+import org.apache.dubbo.metrics.model.ApplicationMetric;
+import org.apache.dubbo.metrics.model.MetricsCategory;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.MetricsKeyWrapper;
+import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
+import org.apache.dubbo.metrics.metadata.event.MetadataEvent;
+import org.apache.dubbo.metrics.report.MetricsExport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAccumulator;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+/**
+ * As a data aggregator, use internal data containers calculates and classifies
+ * the registry data collected by {@link MetricsCollector MetricsCollector},
and
+ * provides an {@link MetricsExport MetricsExport} interface for exporting
standard output formats.
+ */
+public class MetadataStatComposite implements MetricsExport {
+
+
+ public Map<MetadataEvent.Type, Map<String, AtomicLong>> numStats = new
ConcurrentHashMap<>();
+ public List<LongContainer<? extends Number>> rtStats = new ArrayList<>();
+ public static String OP_TYPE_PUSH = "push";
+ public static String OP_TYPE_SUBSCRIBE = "subscribe";
+
+ public MetadataStatComposite() {
+ for (MetadataEvent.Type type : MetadataEvent.Type.values()) {
+ numStats.put(type, new ConcurrentHashMap<>());
+ }
+
+ rtStats.addAll(initStats(OP_TYPE_PUSH));
+ rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE));
+ }
+
+ private List<LongContainer<? extends Number>> initStats(String
registryOpType) {
+ List<LongContainer<? extends Number>> singleRtStats = new
ArrayList<>();
+ singleRtStats.add(new AtomicLongContainer(new
MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_LAST)));
+ singleRtStats.add(new LongAccumulatorContainer(new
MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MIN), new
LongAccumulator(Long::min, Long.MAX_VALUE)));
+ singleRtStats.add(new LongAccumulatorContainer(new
MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MAX), new
LongAccumulator(Long::max, Long.MIN_VALUE)));
+ singleRtStats.add(new AtomicLongContainer(new
MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_SUM),
(responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime)));
+ // AvgContainer is a special counter that stores the number of times
but outputs function of sum/times
+ AtomicLongContainer avgContainer = new AtomicLongContainer(new
MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_AVG), (k, v) ->
v.incrementAndGet());
+ avgContainer.setValueSupplier(applicationName -> {
+ LongContainer<? extends Number> totalContainer =
rtStats.stream().filter(longContainer ->
longContainer.isKeyWrapper(MetricsKey.GENERIC_METRIC_RT_SUM,
registryOpType)).findFirst().get();
+ AtomicLong totalRtTimes = avgContainer.get(applicationName);
+ AtomicLong totalRtSum = (AtomicLong)
totalContainer.get(applicationName);
+ return totalRtSum.get() / totalRtTimes.get();
+ });
+ singleRtStats.add(avgContainer);
+ return singleRtStats;
+ }
+
+ public void increment(MetadataEvent.Type type, String applicationName) {
+ if (!numStats.containsKey(type)) {
+ return;
+ }
+ numStats.get(type).computeIfAbsent(applicationName, k -> new
AtomicLong(0L)).incrementAndGet();
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public void calcRt(String applicationName, String registryOpType, Long
responseTime) {
+ for (LongContainer container : rtStats.stream().filter(longContainer
-> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) {
+ Number current = (Number)
ConcurrentHashMapUtils.computeIfAbsent(container, applicationName,
container.getInitFunc());
+ container.getConsumerFunc().accept(responseTime, current);
+ }
+ }
+
+ @Override
+ public List<GaugeMetricSample> exportNumMetrics() {
+ List<GaugeMetricSample> list = new ArrayList<>();
+ for (MetadataEvent.Type type : numStats.keySet()) {
+ Map<String, AtomicLong> stringAtomicLongMap = numStats.get(type);
+ for (String applicationName : stringAtomicLongMap.keySet()) {
+ list.add(convertToSample(applicationName, type,
MetricsCategory.REGISTRY, stringAtomicLongMap.get(applicationName)));
+ }
+ }
+ return list;
+ }
+
+ @Override
+ public List<GaugeMetricSample> exportRtMetrics() {
+ List<GaugeMetricSample> list = new ArrayList<>();
+ for (LongContainer<? extends Number> rtContainer : rtStats) {
+ MetricsKeyWrapper metricsKeyWrapper =
rtContainer.getMetricsKeyWrapper();
+ for (Map.Entry<String, ? extends Number> entry :
rtContainer.entrySet()) {
+ list.add(new GaugeMetricSample(metricsKeyWrapper.targetKey(),
metricsKeyWrapper.targetDesc(),
ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, () ->
rtContainer.getValueSupplier().apply(entry.getKey())));
+ }
+ }
+ return list;
+ }
+
+ public GaugeMetricSample convertToSample(String applicationName,
MetadataEvent.Type type, MetricsCategory category, AtomicLong targetNumber) {
+ return new GaugeMetricSample(type.getMetricsKey(),
ApplicationMetric.getTagsByName(applicationName), category, targetNumber::get);
+ }
+
+
+ /**
+ * Collect Number type data
+ *
+ * @param <NUMBER>
+ */
+ public static class LongContainer<NUMBER extends Number> extends
ConcurrentHashMap<String, NUMBER> {
+
+ /**
+ * Provide the metric type name
+ */
+ private final MetricsKeyWrapper metricsKeyWrapper;
+ /**
+ * The initial value corresponding to the key is generally 0 of
different data types
+ */
+ private final Function<String, NUMBER> initFunc;
+ /**
+ * Statistical data calculation function, which can be self-increment,
self-decrement, or more complex avg function
+ */
+ private final BiConsumer<Long, NUMBER> consumerFunc;
+ /**
+ * Data output function required by {@link GaugeMetricSample
GaugeMetricSample}
+ */
+ private Function<String, Long> valueSupplier;
+
+
+ public LongContainer(MetricsKeyWrapper metricsKeyWrapper,
Supplier<NUMBER> initFunc, BiConsumer<Long, NUMBER> consumerFunc) {
+ this.metricsKeyWrapper = metricsKeyWrapper;
+ this.initFunc = s -> initFunc.get();
+ this.consumerFunc = consumerFunc;
+ this.valueSupplier = k -> this.get(k).longValue();
+ }
+
+ public boolean specifyType(String type) {
+ return type.equals(getMetricsKeyWrapper().getType());
+ }
+
+ public MetricsKeyWrapper getMetricsKeyWrapper() {
+ return metricsKeyWrapper;
+ }
+
+ public boolean isKeyWrapper(MetricsKey metricsKey, String
registryOpType) {
+ return metricsKeyWrapper.isKey(metricsKey,registryOpType);
+ }
+
+ public Function<String, NUMBER> getInitFunc() {
+ return initFunc;
+ }
+
+ public BiConsumer<Long, NUMBER> getConsumerFunc() {
+ return consumerFunc;
+ }
+
+ public Function<String, Long> getValueSupplier() {
+ return valueSupplier;
+ }
+
+ public void setValueSupplier(Function<String, Long> valueSupplier) {
+ this.valueSupplier = valueSupplier;
+ }
+
+ @Override
+ public String toString() {
+ return "LongContainer{" +
+ "metricsKeyWrapper=" + metricsKeyWrapper +
+ '}';
+ }
+ }
+
+ public static class AtomicLongContainer extends LongContainer<AtomicLong> {
+
+ public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) {
+ super(metricsKeyWrapper, AtomicLong::new, (responseTime,
longAccumulator) -> longAccumulator.set(responseTime));
+ }
+
+ public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper,
BiConsumer<Long, AtomicLong> consumerFunc) {
+ super(metricsKeyWrapper, AtomicLong::new, consumerFunc);
+ }
+
+ }
+
+ public static class LongAccumulatorContainer extends
LongContainer<LongAccumulator> {
+ public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper,
LongAccumulator accumulator) {
+ super(metricsKeyWrapper, () -> accumulator, (responseTime,
longAccumulator) -> longAccumulator.accumulate(responseTime));
+ }
+ }
+
+
+}
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
new file mode 100644
index 0000000000..8d68e5a189
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java
@@ -0,0 +1,109 @@
+/*
+ * 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.metadata.event;
+
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.TimeCounter;
+import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.TimePair;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+/**
+ * Registry related events
+ */
+public class MetadataEvent extends MetricsEvent implements TimeCounter {
+ private final TimePair timePair;
+ private final MetadataMetricsCollector collector;
+ private final boolean available;
+
+ public MetadataEvent(ApplicationModel applicationModel, TimePair timePair)
{
+ super(applicationModel);
+ this.timePair = timePair;
+ this.collector =
applicationModel.getBeanFactory().getBean(MetadataMetricsCollector.class);
+ this.available = this.collector != null &&
collector.isCollectEnabled();
+ }
+
+ public ApplicationModel getSource() {
+ return (ApplicationModel) source;
+ }
+
+ public MetadataMetricsCollector getCollector() {
+ return collector;
+ }
+
+ public boolean isAvailable() {
+ return available;
+ }
+
+ @Override
+ public TimePair getTimePair() {
+ return timePair;
+ }
+
+ public enum Type {
+ P_TOTAL(MetricsKey.METADATA_PUSH_METRIC_NUM),
+ P_SUCCEED(MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED),
+ P_FAILED(MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED),
+
+ S_TOTAL(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM),
+ S_SUCCEED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED),
+ S_FAILED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED),
+
+ ;
+
+
+ private final MetricsKey metricsKey;
+ private final boolean isIncrement;
+
+
+ Type(MetricsKey metricsKey) {
+ this(metricsKey, true);
+ }
+
+ Type(MetricsKey metricsKey, boolean isIncrement) {
+ this.metricsKey = metricsKey;
+ this.isIncrement = isIncrement;
+ }
+
+ public MetricsKey getMetricsKey() {
+ return metricsKey;
+ }
+
+ public boolean isIncrement() {
+ return isIncrement;
+ }
+ }
+
+ public static class PushEvent extends MetadataEvent {
+
+ public PushEvent(ApplicationModel applicationModel, TimePair timePair)
{
+ super(applicationModel, timePair);
+ }
+
+ }
+
+ public static class SubscribeEvent extends MetadataEvent {
+
+ public SubscribeEvent(ApplicationModel applicationModel, TimePair
timePair) {
+ super(applicationModel, timePair);
+ }
+
+ }
+
+}
diff --git
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
similarity index 67%
copy from
dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
copy to
dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
index 058f583e94..92b3c96da3 100644
---
a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java
@@ -15,24 +15,17 @@
* limitations under the License.
*/
-package org.apache.dubbo.metrics.listener;
+package org.apache.dubbo.metrics.metadata.event;
-import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
-/**
- * Metrics Listener.
- */
-public interface MetricsListener<E extends MetricsEvent> {
+public final class MetadataMetricsEventMulticaster extends
SimpleMetricsEventMulticaster {
- default boolean isSupport(MetricsEvent event) {
- return true;
- }
+ public MetadataMetricsEventMulticaster() {
+ super.addListener(new MetricsPushListener());
+ super.addListener(new MetricsSubscribeListener());
- /**
- * notify event.
- *
- * @param event BaseMetricsEvent
- */
- void onEvent(E event);
+ setAvailable();
+ }
}
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java
new file mode 100644
index 0000000000..d08ec366c8
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java
@@ -0,0 +1,49 @@
+/*
+ * 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.metadata.event;
+
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.listener.MetricsLifeListener;
+
+import static
org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_PUSH;
+
+public class MetricsPushListener implements
MetricsLifeListener<MetadataEvent.PushEvent> {
+
+
+ @Override
+ public boolean isSupport(MetricsEvent event) {
+ return event instanceof MetadataEvent.PushEvent && ((MetadataEvent)
event).isAvailable();
+ }
+
+ @Override
+ public void onEvent(MetadataEvent.PushEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.P_TOTAL);
+ }
+
+ @Override
+ public void onEventFinish(MetadataEvent.PushEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.P_SUCCEED);
+ event.getCollector().addRT(event.getSource().getApplicationName(),
OP_TYPE_PUSH, event.getTimePair().calc());
+ }
+
+ @Override
+ public void onEventError(MetadataEvent.PushEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.P_FAILED);
+ event.getCollector().addRT(event.getSource().getApplicationName(),
OP_TYPE_PUSH, event.getTimePair().calc());
+ }
+}
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java
new file mode 100644
index 0000000000..a247f539a5
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java
@@ -0,0 +1,49 @@
+/*
+ * 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.metadata.event;
+
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.listener.MetricsLifeListener;
+
+import static
org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_SUBSCRIBE;
+
+public class MetricsSubscribeListener implements
MetricsLifeListener<MetadataEvent.SubscribeEvent> {
+
+ @Override
+ public boolean isSupport(MetricsEvent event) {
+ return event instanceof MetadataEvent.SubscribeEvent &&
((MetadataEvent) event).isAvailable();
+ }
+
+ @Override
+ public void onEvent(MetadataEvent.SubscribeEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.S_TOTAL);
+ }
+
+ @Override
+ public void onEventFinish(MetadataEvent.SubscribeEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.S_SUCCEED);
+ event.getCollector().addRT(event.getSource().getApplicationName(),
OP_TYPE_SUBSCRIBE, event.getTimePair().calc());
+ }
+
+ @Override
+ public void onEventError(MetadataEvent.SubscribeEvent event) {
+ event.getCollector().increment(event.getSource().getApplicationName(),
MetadataEvent.Type.S_FAILED);
+ event.getCollector().addRT(event.getSource().getApplicationName(),
OP_TYPE_SUBSCRIBE, event.getTimePair().calc());
+ }
+
+}
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector
b/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector
new file mode 100644
index 0000000000..c90627a2d0
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector
@@ -0,0 +1 @@
+metadata-collector=org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector
diff --git
a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java
b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java
new file mode 100644
index 0000000000..a07712bccd
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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 metrics.metrics.collector;
+
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
+import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector;
+import org.apache.dubbo.metrics.metadata.event.MetadataEvent;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.model.MetricsKeyWrapper;
+import org.apache.dubbo.metrics.model.TimePair;
+import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static
org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
+import static
org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_PUSH;
+import static
org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_SUBSCRIBE;
+
+
+class MetadataMetricsCollectorTest {
+
+ private ApplicationModel applicationModel;
+
+ @BeforeEach
+ public void setup() {
+ FrameworkModel frameworkModel = FrameworkModel.defaultModel();
+ applicationModel = frameworkModel.newApplication();
+ ApplicationConfig config = new ApplicationConfig();
+ config.setName("MockMetrics");
+
+ applicationModel.getApplicationConfigManager().setApplication(config);
+
+ }
+
+ @AfterEach
+ public void teardown() {
+ applicationModel.destroy();
+ }
+
+ @Test
+ void testPushMetrics() throws InterruptedException {
+
+ TimePair timePair = TimePair.start();
+ GlobalMetricsEventMulticaster eventMulticaster =
applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class);
+ MetadataMetricsCollector collector =
applicationModel.getBeanFactory().getOrRegisterBean(MetadataMetricsCollector.class);
+ collector.setCollectEnabled(true);
+
+ eventMulticaster.publishEvent(new
MetadataEvent.PushEvent(applicationModel, timePair));
+ List<MetricSample> metricSamples = collector.collect();
+
+ // push success +1
+ Assertions.assertEquals(metricSamples.size(), 1);
+ Assertions.assertTrue(metricSamples.get(0) instanceof
GaugeMetricSample);
+ Assertions.assertEquals(metricSamples.get(0).getName(),
MetricsKey.METADATA_PUSH_METRIC_NUM.getName());
+
+ eventMulticaster.publishFinishEvent(new
MetadataEvent.PushEvent(applicationModel, timePair));
+ // push finish rt +1
+ metricSamples = collector.collect();
+ //num(total+success) + rt(5) = 7
+ Assertions.assertEquals(metricSamples.size(), 7);
+ long c1 = timePair.calc();
+ TimePair lastTimePair = TimePair.start();
+ eventMulticaster.publishEvent(new
MetadataEvent.PushEvent(applicationModel, lastTimePair));
+ Thread.sleep(50);
+ // push error rt +1
+ eventMulticaster.publishErrorEvent(new
MetadataEvent.PushEvent(applicationModel, lastTimePair));
+ long c2 = lastTimePair.calc();
+ metricSamples = collector.collect();
+
+ // num(total+success+error) + rt(5)
+ Assertions.assertEquals(metricSamples.size(), 8);
+
+ // calc rt
+ for (MetricSample sample : metricSamples) {
+ Map<String, String> tags = sample.getTags();
+ Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME),
applicationModel.getApplicationName());
+ }
+ Map<String, Long> sampleMap =
metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> {
+ Number number = ((GaugeMetricSample) k).getSupplier().get();
+ return number.longValue();
+ }));
+
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_PUSH,
MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc());
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()),
Math.min(c1, c2));
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()),
Math.max(c1, c2));
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()),
(c1 + c2) / 2);
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()),
c1 + c2);
+ }
+
+ @Test
+ void testSubscribeMetrics() throws InterruptedException {
+
+ TimePair timePair = TimePair.start();
+ GlobalMetricsEventMulticaster eventMulticaster =
applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class);
+ MetadataMetricsCollector collector =
applicationModel.getBeanFactory().getOrRegisterBean(MetadataMetricsCollector.class);
+ collector.setCollectEnabled(true);
+
+ eventMulticaster.publishEvent(new
MetadataEvent.SubscribeEvent(applicationModel, timePair));
+ List<MetricSample> metricSamples = collector.collect();
+
+ // push success +1
+ Assertions.assertEquals(metricSamples.size(), 1);
+ Assertions.assertTrue(metricSamples.get(0) instanceof
GaugeMetricSample);
+ Assertions.assertEquals(metricSamples.get(0).getName(),
MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM.getName());
+
+ eventMulticaster.publishFinishEvent(new
MetadataEvent.SubscribeEvent(applicationModel, timePair));
+ // push finish rt +1
+ metricSamples = collector.collect();
+ //num(total+success) + rt(5) = 7
+ Assertions.assertEquals(metricSamples.size(), 7);
+ long c1 = timePair.calc();
+ TimePair lastTimePair = TimePair.start();
+ eventMulticaster.publishEvent(new
MetadataEvent.SubscribeEvent(applicationModel, lastTimePair));
+ Thread.sleep(50);
+ // push error rt +1
+ eventMulticaster.publishErrorEvent(new
MetadataEvent.SubscribeEvent(applicationModel, lastTimePair));
+ long c2 = lastTimePair.calc();
+ metricSamples = collector.collect();
+
+ // num(total+success+error) + rt(5)
+ Assertions.assertEquals(metricSamples.size(), 8);
+
+ // calc rt
+ for (MetricSample sample : metricSamples) {
+ Map<String, String> tags = sample.getTags();
+ Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME),
applicationModel.getApplicationName());
+ }
+ Map<String, Long> sampleMap =
metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> {
+ Number number = ((GaugeMetricSample) k).getSupplier().get();
+ return number.longValue();
+ }));
+
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_SUBSCRIBE,
MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc());
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_SUBSCRIBE,
MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2));
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_SUBSCRIBE,
MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2));
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_SUBSCRIBE,
MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2);
+ Assertions.assertEquals(sampleMap.get(new
MetricsKeyWrapper(OP_TYPE_SUBSCRIBE,
MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2);
+ }
+
+
+}
diff --git a/dubbo-metrics/pom.xml b/dubbo-metrics/pom.xml
index c504428498..835c2b1b44 100644
--- a/dubbo-metrics/pom.xml
+++ b/dubbo-metrics/pom.xml
@@ -20,6 +20,7 @@
<modules>
<module>dubbo-metrics-api</module>
<module>dubbo-metrics-default</module>
+ <module>dubbo-metrics-metadata</module>
<module>dubbo-metrics-prometheus</module>
</modules>
<parent>
diff --git
a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json
b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json
index 8ffe07af6c..816a1aff40 100644
---
a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json
+++
b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json
@@ -2110,6 +2110,16 @@
}
]
},
+ {
+ "name": "org.apache.dubbo.metrics.MetricsScopeModelInitializer",
+ "allPublicMethods": true,
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
{
"name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory",
"allPublicMethods": true
@@ -2908,7 +2918,7 @@
"methods": [
{
"name": "<init>",
- "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"]
+ "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"]
}
]
}
diff --git a/dubbo-registry/dubbo-registry-api/pom.xml
b/dubbo-registry/dubbo-registry-api/pom.xml
index 8cb1496544..f9c580f8c9 100644
--- a/dubbo-registry/dubbo-registry-api/pom.xml
+++ b/dubbo-registry/dubbo-registry-api/pom.xml
@@ -80,5 +80,23 @@
<artifactId>zookeeper</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-api</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-default</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
</project>
diff --git
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
index 6241fe1778..edb974da48 100644
---
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
+++
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
@@ -16,14 +16,6 @@
*/
package org.apache.dubbo.registry.client;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -34,6 +26,9 @@ import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import
org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster;
+import org.apache.dubbo.metrics.metadata.event.MetadataEvent;
+import org.apache.dubbo.metrics.model.TimePair;
import org.apache.dubbo.registry.NotifyListener;
import
org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
@@ -41,6 +36,14 @@ import
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
import org.apache.dubbo.registry.client.metadata.store.MetaCacheManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
import static
org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_INFO_CACHE_EXPIRE;
import static
org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_INFO_CACHE_SIZE;
import static
org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
@@ -225,12 +228,19 @@ public abstract class AbstractServiceDiscovery implements
ServiceDiscovery {
// try to load metadata from remote.
int triedTimes = 0;
while (triedTimes < 3) {
+
+ TimePair timePair = TimePair.start();
+ GlobalMetricsEventMulticaster eventMulticaster =
applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class);
+ eventMulticaster.publishEvent(new
MetadataEvent.SubscribeEvent(applicationModel, timePair));
+
metadata = MetadataUtils.getRemoteMetadata(revision,
instances, metadataReport);
if (metadata != MetadataInfo.EMPTY) {// succeeded
metadata.init();
+ eventMulticaster.publishFinishEvent(new
MetadataEvent.SubscribeEvent(applicationModel, timePair));
break;
} else {// failed
+ eventMulticaster.publishErrorEvent(new
MetadataEvent.SubscribeEvent(applicationModel, timePair));
if (triedTimes > 0) {
if (logger.isDebugEnabled()) {
logger.debug("Retry the " + triedTimes + " times
to get metadata for revision=" + revision);
@@ -301,7 +311,7 @@ public abstract class AbstractServiceDiscovery implements
ServiceDiscovery {
* Can be override if registry support update instance directly.
* <br/>
* NOTICE: Remind to update {@link
AbstractServiceDiscovery#serviceInstance}'s reference if updated
- * and report metadata by {@link
AbstractServiceDiscovery#reportMetadata(MetadataInfo)}
+ * and report metadata by {@link
AbstractServiceDiscovery#reportMetadata(MetadataInfo)}
*
* @param oldServiceInstance origin service instance
* @param newServiceInstance new service instance
@@ -351,12 +361,21 @@ public abstract class AbstractServiceDiscovery implements
ServiceDiscovery {
if (metadataInfo == null) {
return;
}
+ TimePair timePair = TimePair.start();
+ GlobalMetricsEventMulticaster eventMulticaster =
applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class);
+ eventMulticaster.publishEvent(new
MetadataEvent.PushEvent(applicationModel, timePair));
if (metadataReport != null) {
SubscriberMetadataIdentifier identifier = new
SubscriberMetadataIdentifier(serviceName, metadataInfo.getRevision());
if ((DEFAULT_METADATA_STORAGE_TYPE.equals(metadataType) &&
metadataReport.shouldReportMetadata()) ||
REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
- metadataReport.publishAppMetadata(identifier, metadataInfo);
+ try {
+ metadataReport.publishAppMetadata(identifier,
metadataInfo);
+ } catch (IllegalStateException e) {
+ eventMulticaster.publishErrorEvent(new
MetadataEvent.PushEvent(applicationModel, timePair));
+ throw e;
+ }
}
}
+ eventMulticaster.publishFinishEvent(new
MetadataEvent.PushEvent(applicationModel, timePair));
MetadataInfo clonedMetadataInfo = metadataInfo.clone();
metadataInfos.put(metadataInfo.getRevision(), new
MetadataInfoStat(clonedMetadataInfo));
}
diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml
b/dubbo-test/dubbo-dependencies-all/pom.xml
index f97e0a6945..66f84b58f6 100644
--- a/dubbo-test/dubbo-dependencies-all/pom.xml
+++ b/dubbo-test/dubbo-dependencies-all/pom.xml
@@ -148,6 +148,10 @@
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-default</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metrics-metadata</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-prometheus</artifactId>