You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by mi...@apache.org on 2019/04/12 03:34:28 UTC
[incubator-dubbo] branch master updated: metrics service (#3833)
This is an automated email from the ASF dual-hosted git repository.
min pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
The following commit(s) were added to refs/heads/master by this push:
new fa8aabf metrics service (#3833)
fa8aabf is described below
commit fa8aabfd3a6977d027751a37041c1139369bbbcb
Author: panxiaojun233 <43...@users.noreply.github.com>
AuthorDate: Fri Apr 12 11:34:23 2019 +0800
metrics service (#3833)
* metrics service
* bug fix
* full method name
* return type fix
* return type fix
* modify bug
* bug fix
* bug fix
* add metrics message
* bug fix
* add config ip
* code optimization
---
.../java/org/apache/dubbo/common/Constants.java | 2 +
.../org/apache/dubbo/common/utils/NetUtils.java | 10 +
.../dubbo/config/AbstractInterfaceConfig.java | 12 +
.../org/apache/dubbo/config/MetricsConfig.java | 33 ++-
.../org/apache/dubbo/config/ReferenceConfig.java | 2 +
.../org/apache/dubbo/config/ServiceConfig.java | 2 +
.../apache/dubbo/config/spring/ReferenceBean.java | 17 ++
.../apache/dubbo/config/spring/ServiceBean.java | 31 ++-
.../spring/schema/DubboNamespaceHandler.java | 9 +-
.../src/main/resources/META-INF/compat/dubbo.xsd | 24 ++
.../src/main/resources/META-INF/dubbo.xsd | 24 ++
dubbo-monitor/dubbo-monitor-api/pom.xml | 19 +-
.../org/apache/dubbo/monitor/MetricsService.java} | 14 +-
.../dubbo/monitor/support/MetricsFilter.java | 102 --------
.../dubbo/internal/org.apache.dubbo.rpc.Filter | 1 -
.../dubbo/monitor/support/MetricsFilterTest.java | 167 ------------
dubbo-monitor/dubbo-monitor-default/pom.xml | 14 +-
.../apache/dubbo/monitor/dubbo/MetricsFilter.java | 254 ++++++++++++++++++
.../dubbo/internal/org.apache.dubbo.rpc.Filter | 1 +
.../dubbo/monitor/dubbo/MetricsFilterTest.java | 289 +++++++++++++++++++++
.../dubbo/monitor/dubbo}/service/DemoService.java | 2 +-
21 files changed, 720 insertions(+), 309 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
index b43c532..596d91c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
@@ -871,6 +871,8 @@ public class Constants {
public static final String METHOD = "method";
public static final String DUBBO_GROUP = "dubbo";
public static final String METRICS_KEY = "metrics";
+ public static final String METRICS_PORT = "metrics.port";
+ public static final String METRICS_PROTOCOL = "metrics.protocol";
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
index 91f04b8..187e0e2 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -210,6 +211,15 @@ public class NetUtils {
return host;
}
+ public static String getIpByConfig() {
+ String configIp = ConfigurationUtils.getProperty(Constants.DUBBO_IP_TO_BIND);
+ if (configIp != null) {
+ return configIp;
+ }
+
+ return getIpByHost(getLocalAddress().getHostName());
+ }
+
/**
* Find first valid IP from local network card
*
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index 082a0c1..57cb6c3 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -141,6 +141,11 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
* Disconnection events
*/
protected String ondisconnect;
+
+ /**
+ * The metrics configuration
+ */
+ protected MetricsConfig metrics;
protected MetadataReportConfig metadataReportConfig;
protected ConfigCenterConfig configCenter;
@@ -825,4 +830,11 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
this.metadataReportConfig = metadataReportConfig;
}
+ public MetricsConfig getMetrics() {
+ return metrics;
+ }
+
+ public void setMetrics(MetricsConfig metrics) {
+ this.metrics = metrics;
+ }
}
diff --git a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetricsConfig.java
similarity index 53%
copy from dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
copy to dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetricsConfig.java
index 149da77..907d88e 100644
--- a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetricsConfig.java
@@ -14,17 +14,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.monitor.service;
-public interface DemoService {
+package org.apache.dubbo.config;
- String sayName(String name);
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.config.support.Parameter;
- void timeoutException();
+public class MetricsConfig extends AbstractConfig {
- void throwDemoException() throws Exception;
+ private static final long serialVersionUID = -9089919311611546383L;
- int echo(int i);
+ private String port;
+ private String protocol;
+ public MetricsConfig() {
+ }
+
+ @Parameter(key = Constants.METRICS_PORT)
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ @Parameter(key = Constants.METRICS_PROTOCOL)
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index d265399..87ccdf3 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -260,6 +260,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
Map<String, String> map = new HashMap<String, String>();
map.put(Constants.SIDE_KEY, Constants.CONSUMER_SIDE);
+
appendRuntimeParameters(map);
if (!isGeneric()) {
String revision = Version.getVersion(interfaceClass, version);
@@ -276,6 +277,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
}
}
map.put(Constants.INTERFACE_KEY, interfaceName);
+ appendParameters(map, metrics);
appendParameters(map, application);
appendParameters(map, module);
appendParameters(map, consumer, Constants.DEFAULT_KEY);
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 24d6b83..dce2c94 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -426,7 +426,9 @@ public class ServiceConfig<T> extends AbstractServiceConfig {
Map<String, String> map = new HashMap<String, String>();
map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
+
appendRuntimeParameters(map);
+ appendParameters(map, metrics);
appendParameters(map, application);
appendParameters(map, module);
appendParameters(map, provider, Constants.DEFAULT_KEY);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
index 3daec13..3c1111b 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
@@ -27,6 +27,7 @@ import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.MetricsConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.apache.dubbo.config.support.Parameter;
@@ -216,6 +217,22 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
}
}
+ if (getMetrics() == null) {
+ Map<String, MetricsConfig> metricsConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MetricsConfig.class, false, false);
+ if (metricsConfigMap != null && metricsConfigMap.size() > 0) {
+ MetricsConfig metricsConfig = null;
+ for (MetricsConfig config : metricsConfigMap.values()) {
+ if (metricsConfig != null) {
+ throw new IllegalStateException("Duplicate metrics configs: " + metricsConfig + " and " + config);
+ }
+ metricsConfig = config;
+ }
+ if (metricsConfig != null) {
+ setMetrics(metricsConfig);
+ }
+ }
+ }
+
if (shouldInit()) {
getObject();
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
index 7c216a6..ec132ee 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
@@ -19,15 +19,16 @@ package org.apache.dubbo.config.spring;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ConfigCenterConfig;
-import org.apache.dubbo.config.MetadataReportConfig;
-import org.apache.dubbo.config.ModuleConfig;
-import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
-import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ConfigCenterConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
@@ -256,6 +257,22 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
}
}
+ if (getMetrics() == null) {
+ Map<String, MetricsConfig> metricsConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MetricsConfig.class, false, false);
+ if (metricsConfigMap != null && metricsConfigMap.size() > 0) {
+ MetricsConfig metricsConfig = null;
+ for (MetricsConfig config : metricsConfigMap.values()) {
+ if (metricsConfig != null) {
+ throw new IllegalStateException("Duplicate metrics configs: " + metricsConfig + " and " + config);
+ }
+ metricsConfig = config;
+ }
+ if (metricsConfig != null) {
+ setMetrics(metricsConfig);
+ }
+ }
+ }
+
if (StringUtils.isEmpty(getProtocolIds())) {
if (getProvider() != null && StringUtils.isNotEmpty(getProvider().getProtocolIds())) {
setProtocolIds(getProvider().getProtocolIds());
@@ -352,4 +369,4 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
-}
\ No newline at end of file
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
index 4d7b0af..915a9ea 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
@@ -17,14 +17,16 @@
package org.apache.dubbo.config.spring.schema;
import org.apache.dubbo.common.Version;
+
import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.MonitorConfig;
-import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.MetricsConfig;
import org.apache.dubbo.config.ProviderConfig;
-import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
@@ -50,6 +52,7 @@ public class DubboNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
+ registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
index 6568ab1..01996ae 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd
@@ -773,6 +773,19 @@
</xsd:attribute>
</xsd:complexType>
+ <xsd:complexType name="metricsType">
+ <xsd:attribute name="port" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service port. ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="protocol" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service protocol. ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
<xsd:complexType name="methodType">
<xsd:complexContent>
<xsd:extension base="abstractMethodType">
@@ -1459,4 +1472,15 @@
</xsd:annotation>
</xsd:element>
+ <xsd:element name="metrics" type="metricsType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="org.apache.dubbo.config.MetricsConfig"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:element>
+
</xsd:schema>
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index 03fe3f7..33ff3ad 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -767,6 +767,19 @@
</xsd:attribute>
</xsd:complexType>
+ <xsd:complexType name="metricsType">
+ <xsd:attribute name="port" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service port. ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="protocol" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service protocol. ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
<xsd:complexType name="methodType">
<xsd:complexContent>
<xsd:extension base="abstractMethodType">
@@ -1484,4 +1497,15 @@
</xsd:annotation>
</xsd:element>
+ <xsd:element name="metrics" type="metricsType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics service ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="org.apache.dubbo.config.MetricsConfig"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:element>
+
</xsd:schema>
diff --git a/dubbo-monitor/dubbo-monitor-api/pom.xml b/dubbo-monitor/dubbo-monitor-api/pom.xml
index ec69d4e..14f157a 100644
--- a/dubbo-monitor/dubbo-monitor-api/pom.xml
+++ b/dubbo-monitor/dubbo-monitor-api/pom.xml
@@ -36,18 +36,17 @@
</dependency>
<dependency>
- <groupId>com.alibaba.middleware</groupId>
- <artifactId>metrics-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>com.alibaba.middleware</groupId>
- <artifactId>metrics-core-impl</artifactId>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-remoting-netty4</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
</dependency>
+
<dependency>
- <groupId>com.alibaba.middleware</groupId>
- <artifactId>metrics-common</artifactId>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-serialization-hessian2</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
</dependency>
-
-
</dependencies>
</project>
diff --git a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MetricsService.java
similarity index 79%
copy from dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
copy to dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MetricsService.java
index 149da77..41c7b3b 100644
--- a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
+++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MetricsService.java
@@ -14,17 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.monitor.service;
-
-public interface DemoService {
-
- String sayName(String name);
-
- void timeoutException();
-
- void throwDemoException() throws Exception;
-
- int echo(int i);
+package org.apache.dubbo.monitor;
+public interface MetricsService {
+ String getMetricsByGroup(String group);
}
diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MetricsFilter.java
deleted file mode 100644
index 648d231..0000000
--- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MetricsFilter.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.monitor.support;
-
-import com.alibaba.metrics.FastCompass;
-import com.alibaba.metrics.MetricLevel;
-import com.alibaba.metrics.MetricManager;
-import com.alibaba.metrics.MetricName;
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-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.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.support.RpcUtils;
-
-import java.util.HashMap;
-
-public class MetricsFilter implements Filter {
-
- private static final Logger logger = LoggerFactory.getLogger(MetricsFilter.class);
-
- @Override
- public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
- RpcContext context = RpcContext.getContext();
- boolean isProvider = context.isProviderSide();
- long start = System.currentTimeMillis();
- try {
- Result result = invoker.invoke(invocation); // proceed invocation chain
- long duration = System.currentTimeMillis() - start;
- reportMetrics(invoker, invocation, duration, "success", isProvider);
- return result;
- } catch (RpcException e) {
- long duration = System.currentTimeMillis() - start;
- String result = "error";
- if (e.isTimeout()) {
- result = "timeoutError";
- }
- if (e.isBiz()) {
- result = "bisError";
- }
- if (e.isNetwork()) {
- result = "networkError";
- }
- if (e.isSerialization()) {
- result = "serializationError";
- }
- reportMetrics(invoker, invocation, duration, result, isProvider);
- throw e;
- }
- }
-
- private void reportMetrics(Invoker<?> invoker, Invocation invocation, long duration, String result, boolean isProvider) {
- String serviceName = invoker.getInterface().getName();
- String methodName = RpcUtils.getMethodName(invocation);
- MetricName global;
- MetricName method;
- if (isProvider) {
- global = new MetricName(Constants.DUBBO_PROVIDER, MetricLevel.MAJOR);
- method = new MetricName(Constants.DUBBO_PROVIDER_METHOD, new HashMap<String, String>(4) {
- {
- put(Constants.SERVICE, serviceName);
- put(Constants.METHOD, methodName);
- }
- }, MetricLevel.NORMAL);
- } else {
- global = new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR);
- method = new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
- {
- put(Constants.SERVICE, serviceName);
- put(Constants.METHOD, methodName);
- }
- }, MetricLevel.NORMAL);
- }
- setCompassQuantity(Constants.DUBBO_GROUP, result, duration, global, method);
- }
-
- private void setCompassQuantity(String groupName, String result, long duration, MetricName... metricNames) {
- for (MetricName metricName : metricNames) {
- FastCompass compass = MetricManager.getFastCompass(groupName, metricName);
- compass.record(duration, result);
- }
- }
-
-}
diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-monitor/dubbo-monitor-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
index 2407d6b..fbeff59 100644
--- a/dubbo-monitor/dubbo-monitor-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
+++ b/dubbo-monitor/dubbo-monitor-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -1,2 +1 @@
monitor=org.apache.dubbo.monitor.support.MonitorFilter
-metrics=org.apache.dubbo.monitor.support.MetricsFilter
diff --git a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MetricsFilterTest.java b/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MetricsFilterTest.java
deleted file mode 100644
index 8645aa2..0000000
--- a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MetricsFilterTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.monitor.support;
-
-import com.alibaba.metrics.FastCompass;
-import com.alibaba.metrics.IMetricManager;
-import com.alibaba.metrics.MetricLevel;
-import com.alibaba.metrics.MetricManager;
-import com.alibaba.metrics.MetricName;
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.monitor.service.DemoService;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-
-public class MetricsFilterTest {
-
- private final Invoker<DemoService> serviceInvoker = new Invoker<DemoService>() {
- @Override
- public Class<DemoService> getInterface() {
- return DemoService.class;
- }
-
- public URL getUrl() {
- return URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/org.apache.dubbo.monitor.service.DemoService");
- }
-
- @Override
- public boolean isAvailable() {
- return false;
- }
-
- public Result invoke(Invocation invocation) throws RpcException {
- return null;
- }
-
- @Override
- public void destroy() {
- }
- };
-
- private final Invoker<DemoService> timeoutInvoker = new Invoker<DemoService>() {
- @Override
- public Class<DemoService> getInterface() {
- return DemoService.class;
- }
-
- public URL getUrl() {
- return URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/org.apache.dubbo.monitor.service.DemoService");
- }
-
- @Override
- public boolean isAvailable() {
- return false;
- }
-
- public Result invoke(Invocation invocation) throws RpcException {
- throw new RpcException(RpcException.TIMEOUT_EXCEPTION);
- }
-
- @Override
- public void destroy() {
- }
- };
-
- @Test
- public void testConsumerSuccess() throws Exception {
- IMetricManager metricManager = MetricManager.getIMetricManager();
- metricManager.clear();
- MetricsFilter metricsFilter = new MetricsFilter();
- Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
- RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
- RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE));
- for (int i = 0; i < 100; i++) {
- metricsFilter.invoke(serviceInvoker, invocation);
- }
- FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR));
- FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
- {
- put(Constants.SERVICE, "org.apache.dubbo.monitor.service.DemoService");
- put(Constants.METHOD, "sayName");
- }
- }, MetricLevel.NORMAL));
- long timestamp = System.currentTimeMillis() / 5000 * 5000;
- Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp));
- timestamp = timestamp / 15000 * 15000;
- Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp));
-
- }
-
- @Test
- public void testConsumerTimeout() {
- IMetricManager metricManager = MetricManager.getIMetricManager();
- metricManager.clear();
- MetricsFilter metricsFilter = new MetricsFilter();
- Invocation invocation = new RpcInvocation("timeoutException", null, null);
- RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
- RpcContext.getContext().setUrl(timeoutInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE)
- .addParameter(Constants.TIMEOUT_KEY, 300));
- for (int i = 0; i < 10; i++) {
- try {
- metricsFilter.invoke(timeoutInvoker, invocation);
- } catch (RpcException e) {
- //ignore
- }
- }
- FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR));
- FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
- {
- put(Constants.SERVICE, "org.apache.dubbo.monitor.service.DemoService");
- put(Constants.METHOD, "timeoutException");
- }
- }, MetricLevel.NORMAL));
- long timestamp = System.currentTimeMillis() / 5000 * 5000;
- Assertions.assertEquals(10, dubboClient.getMethodCountPerCategory(0).get("timeoutError").get(timestamp));
- timestamp = timestamp / 15000 * 15000;
- Assertions.assertEquals(10, dubboMethod.getMethodCountPerCategory(0).get("timeoutError").get(timestamp));
-
- }
-
- @Test
- public void testProviderSuccess() throws Exception {
- IMetricManager metricManager = MetricManager.getIMetricManager();
- metricManager.clear();
- MetricsFilter metricsFilter = new MetricsFilter();
- Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
- RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
- RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.PROVIDER));
- for (int i = 0; i < 100; i++) {
- metricsFilter.invoke(serviceInvoker, invocation);
- }
- FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_PROVIDER, MetricLevel.MAJOR));
- FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_PROVIDER_METHOD, new HashMap<String, String>(4) {
- {
- put(Constants.SERVICE, "org.apache.dubbo.monitor.service.DemoService");
- put(Constants.METHOD, "sayName");
- }
- }, MetricLevel.NORMAL));
- long timestamp = System.currentTimeMillis() / 5000 * 5000;
- Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp));
- timestamp = timestamp / 15000 * 15000;
- Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp));
- }
-}
diff --git a/dubbo-monitor/dubbo-monitor-default/pom.xml b/dubbo-monitor/dubbo-monitor-default/pom.xml
index 0b84690..de785c1 100644
--- a/dubbo-monitor/dubbo-monitor-default/pom.xml
+++ b/dubbo-monitor/dubbo-monitor-default/pom.xml
@@ -35,6 +35,18 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
+ <groupId>com.alibaba.middleware</groupId>
+ <artifactId>metrics-core-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba.middleware</groupId>
+ <artifactId>metrics-core-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba.middleware</groupId>
+ <artifactId>metrics-common</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${project.parent.version}</version>
@@ -53,4 +65,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
new file mode 100644
index 0000000..c613f75
--- /dev/null
+++ b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
@@ -0,0 +1,254 @@
+/*
+ * 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.monitor.dubbo;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.metrics.FastCompass;
+import com.alibaba.metrics.MetricLevel;
+import com.alibaba.metrics.MetricManager;
+import com.alibaba.metrics.MetricName;
+import com.alibaba.metrics.MetricRegistry;
+import com.alibaba.metrics.common.CollectLevel;
+import com.alibaba.metrics.common.MetricObject;
+import com.alibaba.metrics.common.MetricsCollector;
+import com.alibaba.metrics.common.MetricsCollectorFactory;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.store.DataStore;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.monitor.MetricsService;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcResult;
+import org.apache.dubbo.rpc.support.RpcUtils;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class MetricsFilter implements Filter {
+
+ private static final Logger logger = LoggerFactory.getLogger(MetricsFilter.class);
+ private static volatile AtomicBoolean exported = new AtomicBoolean(false);
+ private Integer port;
+ private String protocolName;
+
+ @Override
+ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+ if (exported.compareAndSet(false, true)) {
+ this.protocolName = invoker.getUrl().getParameter(Constants.METRICS_PROTOCOL) == null ?
+ Constants.DEFAULT_PROTOCOL : invoker.getUrl().getParameter(Constants.METRICS_PROTOCOL);
+
+ Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(protocolName);
+
+ this.port = invoker.getUrl().getParameter(Constants.METRICS_PORT) == null ?
+ protocol.getDefaultPort() : Integer.valueOf(invoker.getUrl().getParameter(Constants.METRICS_PORT));
+
+ Invoker<MetricsService> metricsInvoker = initMetricsInvoker();
+
+ try {
+ protocol.export(metricsInvoker);
+ } catch (RuntimeException e) {
+ logger.error("Metrics Service need to be configured" +
+ " when multiple processes are running on a host" + e.getMessage());
+ }
+ }
+
+ RpcContext context = RpcContext.getContext();
+ boolean isProvider = context.isProviderSide();
+ long start = System.currentTimeMillis();
+ try {
+ Result result = invoker.invoke(invocation); // proceed invocation chain
+ long duration = System.currentTimeMillis() - start;
+ reportMetrics(invoker, invocation, duration, "success", isProvider);
+ return result;
+ } catch (RpcException e) {
+ long duration = System.currentTimeMillis() - start;
+ String result = "error";
+ if (e.isTimeout()) {
+ result = "timeoutError";
+ }
+ if (e.isBiz()) {
+ result = "bisError";
+ }
+ if (e.isNetwork()) {
+ result = "networkError";
+ }
+ if (e.isSerialization()) {
+ result = "serializationError";
+ }
+ reportMetrics(invoker, invocation, duration, result, isProvider);
+ throw e;
+ }
+ }
+
+ private String buildMethodName(Invocation invocation) {
+ String methodName = RpcUtils.getMethodName(invocation);
+ StringBuilder method = new StringBuilder(methodName);
+ Class<?>[] argTypes = RpcUtils.getParameterTypes(invocation);
+
+ method.append("(");
+
+ for (int i = 0; i < argTypes.length; i++) {
+ method.append((i == 0 ? "" : ", ") + argTypes[i].getSimpleName());
+ }
+ method.append(")");
+ Class<?> returnType = RpcUtils.getReturnType(invocation);
+ String typeName = null;
+ if(returnType != null) {
+ typeName = returnType.getTypeName();
+ typeName = typeName.substring(typeName.lastIndexOf(".") + 1);
+ }
+
+ return (typeName == null ? "void" : typeName) + " " + method;
+ }
+
+ private void reportMetrics(Invoker<?> invoker, Invocation invocation, long duration, String result, boolean isProvider) {
+ String serviceName = invoker.getInterface().getName();
+ String methodName = buildMethodName(invocation);
+ MetricName global;
+ MetricName method;
+ if (isProvider) {
+ global = new MetricName(Constants.DUBBO_PROVIDER, MetricLevel.MAJOR);
+ method = new MetricName(Constants.DUBBO_PROVIDER_METHOD, new HashMap<String, String>(4) {
+ {
+ put(Constants.SERVICE, serviceName);
+ put(Constants.METHOD, methodName);
+ }
+ }, MetricLevel.NORMAL);
+ } else {
+ global = new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR);
+ method = new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
+ {
+ put(Constants.SERVICE, serviceName);
+ put(Constants.METHOD, methodName);
+ }
+ }, MetricLevel.NORMAL);
+ }
+ setCompassQuantity(Constants.DUBBO_GROUP, result, duration, global, method);
+ }
+
+ private void setCompassQuantity(String groupName, String result, long duration, MetricName... metricNames) {
+ for (MetricName metricName : metricNames) {
+ FastCompass compass = MetricManager.getFastCompass(groupName, metricName);
+ compass.record(duration, result);
+ }
+ }
+
+ private List<MetricObject> getThreadPoolMessage() {
+ DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
+ Map<String, Object> executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
+
+ List<MetricObject> threadPoolMtricList = new ArrayList<>();
+ for (Map.Entry<String, Object> entry : executors.entrySet()) {
+ String port = entry.getKey();
+ ExecutorService executor = (ExecutorService) entry.getValue();
+ if (executor instanceof ThreadPoolExecutor) {
+ ThreadPoolExecutor tp = (ThreadPoolExecutor) executor;
+ // ignore metrcis service
+ if (port.equals(this.port + "")) {
+ continue;
+ }
+
+ threadPoolMtricList.add(value2MetricObject("threadPool.active", tp.getActiveCount(), MetricLevel.MAJOR));
+ threadPoolMtricList.add(value2MetricObject("threadPool.core", tp.getCorePoolSize(), MetricLevel.MAJOR));
+ threadPoolMtricList.add(value2MetricObject("threadPool.max", tp.getMaximumPoolSize(), MetricLevel.MAJOR));
+ threadPoolMtricList.add(value2MetricObject("threadPool.current", tp.getPoolSize(), MetricLevel.MAJOR));
+ }
+ }
+
+ return threadPoolMtricList;
+ }
+
+ private MetricObject value2MetricObject(String metric, Integer value, MetricLevel level) {
+ if (metric == null || value == null || level == null)
+ return null;
+
+ return new MetricObject
+ .Builder(metric)
+ .withValue(value)
+ .withLevel(level)
+ .build();
+ }
+
+ private Invoker<MetricsService> initMetricsInvoker() {
+ Invoker<MetricsService> metricsInvoker = new Invoker<MetricsService>() {
+ @Override
+ public Class<MetricsService> getInterface() {
+ return MetricsService.class;
+ }
+
+ @Override
+ public Result invoke(Invocation invocation) throws RpcException {
+ String group = invocation.getArguments()[0].toString();
+ MetricRegistry registry = MetricManager.getIMetricManager().getMetricRegistryByGroup(group);
+
+ SortedMap<MetricName, FastCompass> fastCompasses = registry.getFastCompasses();
+
+ long timestamp = System.currentTimeMillis();
+ double rateFactor = TimeUnit.SECONDS.toSeconds(1);
+ double durationFactor = 1.0 / TimeUnit.MILLISECONDS.toNanos(1);
+
+
+ MetricsCollector collector = MetricsCollectorFactory.createNew(
+ CollectLevel.NORMAL, Collections.EMPTY_MAP, rateFactor, durationFactor, null);
+
+ for (Map.Entry<MetricName, FastCompass> entry : fastCompasses.entrySet()) {
+ collector.collect(entry.getKey(), entry.getValue(), timestamp);
+ }
+
+ RpcResult result = new RpcResult();
+
+ List res = collector.build();
+ res.addAll(getThreadPoolMessage());
+ result.setValue(JSON.toJSONString(res));
+ return result;
+ }
+
+ @Override
+ public URL getUrl() {
+ return URL.valueOf(protocolName + "://" + NetUtils.getIpByConfig() + ":" + port + "/" + MetricsService.class.getName());
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return false;
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+ };
+
+ return metricsInvoker;
+ }
+}
diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-monitor/dubbo-monitor-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000..8441a9c
--- /dev/null
+++ b/dubbo-monitor/dubbo-monitor-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+metrics=org.apache.dubbo.monitor.dubbo.MetricsFilter
diff --git a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java
new file mode 100644
index 0000000..bca62f4
--- /dev/null
+++ b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java
@@ -0,0 +1,289 @@
+/*
+ * 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.monitor.dubbo;
+
+import com.alibaba.metrics.FastCompass;
+import com.alibaba.metrics.IMetricManager;
+import com.alibaba.metrics.MetricLevel;
+import com.alibaba.metrics.MetricManager;
+import com.alibaba.metrics.MetricName;
+import com.alibaba.metrics.common.MetricObject;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.monitor.MetricsService;
+import org.apache.dubbo.monitor.dubbo.service.DemoService;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MetricsFilterTest {
+
+ private final Invoker<DemoService> serviceInvoker = new Invoker<DemoService>() {
+ @Override
+ public Class<DemoService> getInterface() {
+ return DemoService.class;
+ }
+
+ public URL getUrl() {
+ return URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/org.apache.dubbo.monitor.dubbo.service.DemoService");
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return false;
+ }
+
+ public Result invoke(Invocation invocation) throws RpcException {
+ return null;
+ }
+
+ @Override
+ public void destroy() {
+ }
+ };
+
+ private final Invoker<DemoService> timeoutInvoker = new Invoker<DemoService>() {
+ @Override
+ public Class<DemoService> getInterface() {
+ return DemoService.class;
+ }
+
+ public URL getUrl() {
+ return URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880/org.apache.dubbo.monitor.dubbo.service.DemoService");
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return false;
+ }
+
+ public Result invoke(Invocation invocation) throws RpcException {
+ throw new RpcException(RpcException.TIMEOUT_EXCEPTION);
+ }
+
+ @Override
+ public void destroy() {
+ }
+ };
+
+ @Test
+ public void testConsumerSuccess() throws Exception {
+ IMetricManager metricManager = MetricManager.getIMetricManager();
+ metricManager.clear();
+ MetricsFilter metricsFilter = new MetricsFilter();
+ Invocation invocation = new RpcInvocation("sayName", new Class<?>[] {Integer.class}, new Object[0]);
+ RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
+ RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE));
+ for (int i = 0; i < 100; i++) {
+ metricsFilter.invoke(serviceInvoker, invocation);
+ }
+ FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR));
+ FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
+ {
+ put(Constants.SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService");
+ put(Constants.METHOD, "void sayName(Integer)");
+ }
+ }, MetricLevel.NORMAL));
+ long timestamp = System.currentTimeMillis() / 5000 * 5000;
+ Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp));
+ timestamp = timestamp / 15000 * 15000;
+ Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp));
+
+ }
+
+ @Test
+ public void testConsumerTimeout() {
+ IMetricManager metricManager = MetricManager.getIMetricManager();
+ metricManager.clear();
+ MetricsFilter metricsFilter = new MetricsFilter();
+ Invocation invocation = new RpcInvocation("timeoutException", null, null);
+ RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
+ RpcContext.getContext().setUrl(timeoutInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.CONSUMER_SIDE)
+ .addParameter(Constants.TIMEOUT_KEY, 300));
+ for (int i = 0; i < 10; i++) {
+ try {
+ metricsFilter.invoke(timeoutInvoker, invocation);
+ } catch (RpcException e) {
+ //ignore
+ }
+ }
+ FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER, MetricLevel.MAJOR));
+ FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) {
+ {
+ put(Constants.SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService");
+ put(Constants.METHOD, "void timeoutException()");
+ }
+ }, MetricLevel.NORMAL));
+ long timestamp = System.currentTimeMillis() / 5000 * 5000;
+ Assertions.assertEquals(10, dubboClient.getMethodCountPerCategory(0).get("timeoutError").get(timestamp));
+ timestamp = timestamp / 15000 * 15000;
+ Assertions.assertEquals(10, dubboMethod.getMethodCountPerCategory(0).get("timeoutError").get(timestamp));
+
+ }
+
+ @Test
+ public void testProviderSuccess() throws Exception {
+ IMetricManager metricManager = MetricManager.getIMetricManager();
+ metricManager.clear();
+ MetricsFilter metricsFilter = new MetricsFilter();
+ Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
+ RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
+ RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.PROVIDER));
+ for (int i = 0; i < 100; i++) {
+ metricsFilter.invoke(serviceInvoker, invocation);
+ }
+ FastCompass dubboClient = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_PROVIDER, MetricLevel.MAJOR));
+ FastCompass dubboMethod = metricManager.getFastCompass(Constants.DUBBO_GROUP, new MetricName(Constants.DUBBO_PROVIDER_METHOD, new HashMap<String, String>(4) {
+ {
+ put(Constants.SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService");
+ put(Constants.METHOD, "void sayName()");
+ }
+ }, MetricLevel.NORMAL));
+ long timestamp = System.currentTimeMillis() / 5000 * 5000;
+ Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp));
+ timestamp = timestamp / 15000 * 15000;
+ Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp));
+ }
+
+ @Test
+ public void testInvokeMetricsService() {
+ IMetricManager metricManager = MetricManager.getIMetricManager();
+ metricManager.clear();
+ MetricsFilter metricsFilter = new MetricsFilter();
+ Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
+ RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
+ RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.PROVIDER_SIDE)
+ .addParameter(Constants.TIMEOUT_KEY, 300));
+ for (int i = 0; i < 50; i++) {
+ try {
+ metricsFilter.invoke(serviceInvoker, invocation);
+ metricsFilter.invoke(timeoutInvoker, invocation);
+ } catch (RpcException e) {
+ //ignore
+ }
+ }
+ Protocol protocol = new DubboProtocol();
+ URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":20880/" + MetricsService.class.getName());
+ Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url);
+ invocation = new RpcInvocation("getMetricsByGroup", new Class<?>[]{String.class}, new Object[]{Constants.DUBBO_GROUP});
+ try{
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ // ignore
+ }
+ String resStr = invoker.invoke(invocation).getValue().toString();
+ List<MetricObject> metricObjectList = new Gson().fromJson(resStr, new TypeToken<List<MetricObject>>(){}.getType());
+ Map<String, Object> metricMap = new HashMap<>();
+ for(int i = 0; i < metricObjectList.size(); i++) {
+ MetricObject object = metricObjectList.get(i);
+ String metric = object.getMetric().substring(object.getMetric().lastIndexOf(".") + 1);
+ if((double)object.getValue() > 0.0 && object.getMetricLevel().equals(MetricLevel.MAJOR))
+ metricMap.put(metric, object.getValue());
+ }
+
+ Assertions.assertEquals(50.0, metricMap.get("success_bucket_count"));
+ Assertions.assertEquals(50.0, metricMap.get("timeoutError_bucket_count"));
+ Assertions.assertEquals(100.0, metricMap.get("bucket_count"));
+ Assertions.assertEquals(100.0 / 5, metricMap.get("qps"));
+ Assertions.assertEquals(50.0 / 100.0, metricMap.get("success_rate"));
+ }
+
+ @Test
+ public void testInvokeMetricsMethodService() {
+ IMetricManager metricManager = MetricManager.getIMetricManager();
+ metricManager.clear();
+ MetricsFilter metricsFilter = new MetricsFilter();
+ Invocation sayNameInvocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
+ Invocation echoInvocation = new RpcInvocation("echo", new Class<?>[]{Integer.class}, new Integer[]{1});
+ RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
+ RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(Constants.SIDE_KEY, Constants.PROVIDER_SIDE)
+ .addParameter(Constants.TIMEOUT_KEY, 300));
+ for (int i = 0; i < 50; i++) {
+ metricsFilter.invoke(serviceInvoker, sayNameInvocation);
+ metricsFilter.invoke(serviceInvoker, echoInvocation);
+ try {
+ metricsFilter.invoke(timeoutInvoker, sayNameInvocation);
+ } catch (RpcException e) {
+ // ignore
+ }
+ try {
+ metricsFilter.invoke(timeoutInvoker, echoInvocation);
+ } catch (RpcException e) {
+ // ignore
+ }
+ }
+
+ Protocol protocol = new DubboProtocol();
+ URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":20880/" + MetricsService.class.getName());
+ Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url);
+ Invocation invocation = new RpcInvocation("getMetricsByGroup", new Class<?>[]{String.class}, new Object[]{Constants.DUBBO_GROUP});
+ try{
+ Thread.sleep(15000);
+ } catch (Exception e) {
+ // ignore
+ }
+ String resStr = invoker.invoke(invocation).getValue().toString();
+ List<MetricObject> metricObjectList = new Gson().fromJson(resStr, new TypeToken<List<MetricObject>>(){}.getType());
+ Map<String, Map<String, Object>> methodMetricMap = new HashMap<>();
+ for(int i = 0; i < metricObjectList.size(); i++) {
+ MetricObject object = metricObjectList.get(i);
+ String service = object.getTags().get("service");
+ String method = service + "." + object.getTags().get("method");
+ String metric = object.getMetric().substring(object.getMetric().lastIndexOf(".") + 1);
+ Map map = methodMetricMap.get(method);
+ if(map == null) {
+ map = new HashMap();
+ methodMetricMap.put(method, map);
+ }
+ map.put(metric, object.getValue());
+ }
+
+ Assertions.assertEquals(50.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_bucket_count"));
+ Assertions.assertEquals(50.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_bucket_count"));
+
+ Assertions.assertEquals(50.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("timeoutError_bucket_count"));
+ Assertions.assertEquals(50.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("timeoutError_bucket_count"));
+
+ Assertions.assertEquals(100.0 / 15,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("qps"));
+ Assertions.assertEquals(100.0 / 15,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("qps"));
+
+ Assertions.assertEquals(50.0 / 100.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_rate"));
+ Assertions.assertEquals(50.0 / 100.0,
+ methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_rate"));
+ }
+}
diff --git a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/service/DemoService.java
similarity index 95%
rename from dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
rename to dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/service/DemoService.java
index 149da77..a2fb2d1 100644
--- a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/service/DemoService.java
+++ b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/service/DemoService.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.monitor.service;
+package org.apache.dubbo.monitor.dubbo.service;
public interface DemoService {