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 6faf548e24 Add histogram (#11632)
6faf548e24 is described below
commit 6faf548e2463693e70274015bc8d11d624c12f19
Author: gsralex <[email protected]>
AuthorDate: Mon Mar 27 09:49:09 2023 +0800
Add histogram (#11632)
---
.../dubbo/common/constants/MetricsConstants.java | 2 +
.../org/apache/dubbo/config/MetricsConfig.java | 12 +++
.../dubbo/config/nested/HistogramConfig.java | 93 ++++++++++++++++++++++
.../org/apache/dubbo/config/MetricsConfigTest.java | 9 ++-
.../spring/schema/DubboBeanDefinitionParser.java | 5 ++
.../src/main/resources/META-INF/dubbo.xsd | 15 ++++
.../configprops/SpringBootConfigPropsTest.java | 4 +-
.../SpringBootMultipleConfigPropsTest.java | 4 +-
.../metrics/SpringBootConfigMetricsTest.java | 2 +
.../org/apache/dubbo/metrics/model/MetricsKey.java | 6 ++
.../org/apache/dubbo/metrics/DubboMetrics.java | 3 +-
...ubboMetrics.java => MetricsGlobalRegistry.java} | 22 ++---
.../collector/HistogramMetricsCollector.java | 88 ++++++++++++++++++++
.../metrics/register/HistogramMetricRegister.java | 81 +++++++++++++++++++
.../MetricRegister.java} | 24 ++----
.../metrics/report/AbstractMetricsReporter.java | 6 +-
.../HistogramMetricSample.java} | 25 +++---
17 files changed, 342 insertions(+), 59 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java
index 58b6b39887..b41e716bd2 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/MetricsConstants.java
@@ -54,6 +54,8 @@ public interface MetricsConstants {
String AGGREGATION_TIME_WINDOW_SECONDS_KEY =
"aggregation.time.window.seconds";
+ String HISTOGRAM_ENABLED_KEY = "histogram.enabled";
+
String PROMETHEUS_EXPORTER_ENABLED_KEY = "prometheus.exporter.enabled";
String PROMETHEUS_EXPORTER_ENABLE_HTTP_SERVICE_DISCOVERY_KEY =
"prometheus.exporter.enable.http.service.discovery";
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 07a1e5f425..d915f53d6b 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
@@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.nested.AggregationConfig;
import org.apache.dubbo.config.nested.PrometheusConfig;
+import org.apache.dubbo.config.nested.HistogramConfig;
import org.apache.dubbo.config.support.Nested;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -69,6 +70,9 @@ public class MetricsConfig extends AbstractConfig {
@Nested
private AggregationConfig aggregation;
+ @Nested
+ private HistogramConfig histogram;
+
private String exportServiceProtocol;
private Integer exportServicePort;
@@ -140,6 +144,14 @@ public class MetricsConfig extends AbstractConfig {
this.aggregation = aggregation;
}
+ public HistogramConfig getHistogram() {
+ return histogram;
+ }
+
+ public void setHistogram(HistogramConfig histogram) {
+ this.histogram = histogram;
+ }
+
public String getExportServiceProtocol() {
return exportServiceProtocol;
}
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/HistogramConfig.java
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/HistogramConfig.java
new file mode 100644
index 0000000000..53ef9ac9e4
--- /dev/null
+++
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/HistogramConfig.java
@@ -0,0 +1,93 @@
+/*
+ * 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.config.nested;
+
+import java.io.Serializable;
+
+public class HistogramConfig implements Serializable {
+
+ private Boolean enabled;
+
+ private Integer[] bucketsMs;
+
+ private Integer minExpectedMs;
+
+ private Integer maxExpectedMs;
+
+ private Boolean enabledPercentiles;
+
+ private double[] percentiles;
+
+ private Integer distributionStatisticExpiryMin;
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Integer[] getBucketsMs() {
+ return bucketsMs;
+ }
+
+ public void setBucketsMs(Integer[] bucketsMs) {
+ this.bucketsMs = bucketsMs;
+ }
+
+ public Integer getMinExpectedMs() {
+ return minExpectedMs;
+ }
+
+ public void setMinExpectedMs(Integer minExpectedMs) {
+ this.minExpectedMs = minExpectedMs;
+ }
+
+ public Integer getMaxExpectedMs() {
+ return maxExpectedMs;
+ }
+
+ public void setMaxExpectedMs(Integer maxExpectedMs) {
+ this.maxExpectedMs = maxExpectedMs;
+ }
+
+ public Boolean getEnabledPercentiles() {
+ return enabledPercentiles;
+ }
+
+ public void setEnabledPercentiles(Boolean enabledPercentiles) {
+ this.enabledPercentiles = enabledPercentiles;
+ }
+
+ public double[] getPercentiles() {
+ return percentiles;
+ }
+
+ public void setPercentiles(double[] percentiles) {
+ this.percentiles = percentiles;
+ }
+
+ public Integer getDistributionStatisticExpiryMin() {
+ return distributionStatisticExpiryMin;
+ }
+
+ public void setDistributionStatisticExpiryMin(Integer
distributionStatisticExpiryMin) {
+ this.distributionStatisticExpiryMin = distributionStatisticExpiryMin;
+ }
+}
diff --git
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MetricsConfigTest.java
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MetricsConfigTest.java
index f752b7e86c..13a29b8966 100644
---
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MetricsConfigTest.java
+++
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MetricsConfigTest.java
@@ -19,7 +19,7 @@ package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.nested.AggregationConfig;
import org.apache.dubbo.config.nested.PrometheusConfig;
-
+import org.apache.dubbo.config.nested.HistogramConfig;
import org.junit.jupiter.api.Test;
import static
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
@@ -47,6 +47,10 @@ class MetricsConfigTest {
aggregation.setEnabled(true);
metrics.setAggregation(aggregation);
+ HistogramConfig histogram = new HistogramConfig();
+ histogram.setEnabled(true);
+ metrics.setHistogram(histogram);
+
URL url = metrics.toUrl();
assertThat(url.getProtocol(), equalTo(PROTOCOL_PROMETHEUS));
@@ -56,6 +60,7 @@ class MetricsConfigTest {
assertThat(url.getParameter("prometheus.exporter.enabled"),
equalTo("true"));
assertThat(url.getParameter("prometheus.pushgateway.enabled"),
equalTo("true"));
assertThat(url.getParameter("aggregation.enabled"), equalTo("true"));
+ assertThat(url.getParameter("histogram.enabled"), equalTo("true"));
}
@Test
@@ -117,4 +122,4 @@ class MetricsConfigTest {
assertThat(metrics.getAggregation().getBucketNum(), equalTo(5));
assertThat(metrics.getAggregation().getTimeWindowSeconds(),
equalTo(120));
}
-}
\ No newline at end of file
+}
diff --git
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
index 832c91f0c4..8f63565b21 100644
---
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
+++
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
@@ -33,6 +33,7 @@ import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.nested.AggregationConfig;
import org.apache.dubbo.config.nested.PrometheusConfig;
+import org.apache.dubbo.config.nested.HistogramConfig;
import org.apache.dubbo.config.spring.Constants;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
@@ -265,6 +266,10 @@ public class DubboBeanDefinitionParser implements
BeanDefinitionParser {
AggregationConfig aggregation = new AggregationConfig();
assignProperties(aggregation, child, parserContext);
beanDefinition.getPropertyValues().addPropertyValue("aggregation", aggregation);
+ }else if("histogram".equals(child.getNodeName()) ||
"histogram".equals(child.getLocalName())){
+ HistogramConfig histogram = new HistogramConfig();
+ assignProperties(histogram, child, parserContext);
+
beanDefinition.getPropertyValues().addPropertyValue("histogram", histogram);
} else if ("prometheus-exporter".equals(child.getNodeName()) ||
"prometheus-exporter".equals(child.getLocalName())) {
if (prometheus == null) {
prometheus = new PrometheusConfig();
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 d801ffefc3..e1f272f402 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
@@ -1044,6 +1044,7 @@
<xsd:element ref="prometheus-exporter" minOccurs="0"/>
<xsd:element ref="prometheus-pushgateway" minOccurs="0"/>
<xsd:element ref="aggregation" minOccurs="0"/>
+ <xsd:element ref="histogram" minOccurs="0"/>
</xsd:all>
<xsd:attribute name="protocol" type="xsd:string">
<xsd:annotation>
@@ -1155,6 +1156,14 @@
</xsd:attribute>
</xsd:complexType>
+ <xsd:complexType name="histogramType">
+ <xsd:attribute name="enabled" type="xsd:boolean">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ Enable local rt histogram or not.
]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
<xsd:complexType name="methodType">
<xsd:complexContent>
<xsd:extension base="abstractMethodType">
@@ -2045,4 +2054,10 @@
<xsd:documentation><![CDATA[ The metrics aggregation config.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
+
+ <xsd:element name="histogram" type="histogramType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[ The metrics rt histogram config.
]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
</xsd:schema>
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
index 9ce1a7f5aa..2eaa56b828 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootConfigPropsTest.java
@@ -64,6 +64,7 @@ import static
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMET
"dubbo.metrics.aggregation.enabled=true",
"dubbo.metrics.aggregation.bucket-num=5",
"dubbo.metrics.aggregation.time-window-seconds=120",
+ "dubbo.metrics.histogram.enabled=true",
"dubbo.monitor.address=zookeeper://127.0.0.1:32770",
"dubbo.Config-center.address=${zookeeper.connection.address.1}",
"dubbo.config-Center.group=group1",
@@ -116,6 +117,7 @@ class SpringBootConfigPropsTest {
Assertions.assertEquals(5,
metricsConfig.getAggregation().getBucketNum());
Assertions.assertEquals(120,
metricsConfig.getAggregation().getTimeWindowSeconds());
Assertions.assertTrue(metricsConfig.getAggregation().getEnabled());
+ Assertions.assertTrue(metricsConfig.getHistogram().getEnabled());
List<ProtocolConfig> defaultProtocols =
configManager.getDefaultProtocols();
Assertions.assertEquals(1, defaultProtocols.size());
@@ -153,4 +155,4 @@ class SpringBootConfigPropsTest {
}
-}
\ No newline at end of file
+}
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
index 9bb31c119c..482cd054cd 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/boot/configprops/SpringBootMultipleConfigPropsTest.java
@@ -63,6 +63,7 @@ import static
org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMET
"dubbo.metricses.my-metrics.aggregation.enabled=true",
"dubbo.metricses.my-metrics.aggregation.bucket-num=5",
"dubbo.metricses.my-metrics.aggregation.time-window-seconds=120",
+ "dubbo.metricses.my-metrics.histogram.enabled=true",
"dubbo.monitors.my-monitor.address=zookeeper://127.0.0.1:32770",
"dubbo.config-centers.my-configcenter.address=${zookeeper.connection.address.1}",
"dubbo.config-centers.my-configcenter.group=group1",
@@ -116,6 +117,7 @@ class SpringBootMultipleConfigPropsTest {
Assertions.assertEquals(5,
metricsConfig.getAggregation().getBucketNum());
Assertions.assertEquals(120,
metricsConfig.getAggregation().getTimeWindowSeconds());
Assertions.assertTrue(metricsConfig.getAggregation().getEnabled());
+ Assertions.assertTrue(metricsConfig.getHistogram().getEnabled());
List<ProtocolConfig> defaultProtocols =
configManager.getDefaultProtocols();
Assertions.assertEquals(1, defaultProtocols.size());
@@ -154,4 +156,4 @@ class SpringBootMultipleConfigPropsTest {
}
-}
\ No newline at end of file
+}
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
index 3b54f09bd0..089e691af2 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/metrics/SpringBootConfigMetricsTest.java
@@ -50,6 +50,7 @@ import org.springframework.context.annotation.Configuration;
"dubbo.metrics.aggregation.enabled=true",
"dubbo.metrics.aggregation.bucket-num=5",
"dubbo.metrics.aggregation.time-window-seconds=120",
+ "dubbo.metrics.histogram.enabled=true",
"dubbo.metadata-report.address=${zookeeper.connection.address.2}"
},
classes = {
@@ -90,6 +91,7 @@ public class SpringBootConfigMetricsTest {
Assertions.assertEquals(5,
metricsConfig.getAggregation().getBucketNum());
Assertions.assertEquals(120,
metricsConfig.getAggregation().getTimeWindowSeconds());
Assertions.assertTrue(metricsConfig.getAggregation().getEnabled());
+ Assertions.assertTrue(metricsConfig.getHistogram().getEnabled());
}
}
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 6065ee5289..adc558ef9c 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
@@ -61,6 +61,12 @@ public enum MetricsKey {
REGISTER_METRIC_REQUESTS("dubbo.registry.register.requests.total", "Total
Register Requests"),
REGISTER_METRIC_REQUESTS_SUCCEED("dubbo.registry.register.requests.succeed.total",
"Succeed Register Requests"),
REGISTER_METRIC_REQUESTS_FAILED("dubbo.registry.register.requests.failed.total",
"Failed Register Requests"),
+ METRIC_RT_HISTOGRAM("dubbo.%s.rt.milliseconds.histogram", "Response Time
Histogram"),
+
+
+ GENERIC_METRIC_REQUESTS("dubbo.%s.requests.total", "Total %s Requests"),
+ GENERIC_METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total",
"Succeed %s Requests"),
+ GENERIC_METRIC_REQUESTS_FAILED("dubbo.%s.requests.failed.total", "Failed
%s Requests"),
// subscribe metrics key
SUBSCRIBE_METRIC_NUM("dubbo.registry.subscribe.num.total", "Total
Subscribe Num"),
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
index 00351aedcc..ab38c121a5 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
@@ -19,7 +19,6 @@ package org.apache.dubbo.metrics;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
-import org.apache.dubbo.metrics.report.AbstractMetricsReporter;
public class DubboMetrics implements MeterBinder {
@@ -29,7 +28,7 @@ public class DubboMetrics implements MeterBinder {
@Override
public void bindTo(MeterRegistry registry) {
globalRegistry = registry;
- CompositeMeterRegistry compositeRegistry =
AbstractMetricsReporter.compositeRegistry;
+ CompositeMeterRegistry compositeRegistry =
MetricsGlobalRegistry.getCompositeRegistry();
if (compositeRegistry != null) {
compositeRegistry.add(registry);
}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsGlobalRegistry.java
similarity index 60%
copy from
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
copy to
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsGlobalRegistry.java
index 00351aedcc..cc6c824c18 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsGlobalRegistry.java
@@ -14,28 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.dubbo.metrics;
-import io.micrometer.core.instrument.MeterRegistry;
-import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
-import org.apache.dubbo.metrics.report.AbstractMetricsReporter;
-
-public class DubboMetrics implements MeterBinder {
+public class MetricsGlobalRegistry {
- private MeterRegistry globalRegistry = null;
+ private static final CompositeMeterRegistry compositeRegistry = new
CompositeMeterRegistry();
- @Override
- public void bindTo(MeterRegistry registry) {
- globalRegistry = registry;
- CompositeMeterRegistry compositeRegistry =
AbstractMetricsReporter.compositeRegistry;
- if (compositeRegistry != null) {
- compositeRegistry.add(registry);
- }
- }
-
- public void destroy() {
+ public static CompositeMeterRegistry getCompositeRegistry() {
+ return compositeRegistry;
}
}
-
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java
new file mode 100644
index 0000000000..9fc57059ac
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java
@@ -0,0 +1,88 @@
+/*
+ * 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.collector;
+
+import io.micrometer.core.instrument.Timer;
+import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.nested.HistogramConfig;
+import org.apache.dubbo.metrics.MetricsGlobalRegistry;
+import org.apache.dubbo.metrics.event.MetricsEvent;
+import org.apache.dubbo.metrics.event.RTEvent;
+import org.apache.dubbo.metrics.listener.MetricsListener;
+import org.apache.dubbo.metrics.model.MethodMetric;
+import org.apache.dubbo.metrics.model.MetricsKey;
+import org.apache.dubbo.metrics.register.HistogramMetricRegister;
+import org.apache.dubbo.metrics.sample.HistogramMetricSample;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.dubbo.metrics.model.MetricsCategory.RT;
+
+public class HistogramMetricsCollector implements MetricsListener {
+
+ private final ConcurrentHashMap<MethodMetric, Timer> rt = new
ConcurrentHashMap<>();
+ private HistogramMetricRegister metricRegister;
+ private final ApplicationModel applicationModel;
+
+ private static final Integer[] DEFAULT_BUCKETS_MS = new Integer[]{100,
300, 500, 1000, 3000, 5000, 10000};
+
+ public HistogramMetricsCollector(ApplicationModel applicationModel) {
+ this.applicationModel = applicationModel;
+
+ ConfigManager configManager =
applicationModel.getApplicationConfigManager();
+ MetricsConfig config = configManager.getMetrics().orElse(null);
+ if (config != null && config.getHistogram() != null &&
Boolean.TRUE.equals(config.getHistogram().getEnabled())) {
+ registerListener();
+
+ HistogramConfig histogram = config.getHistogram();
+ if (!Boolean.TRUE.equals(histogram.getEnabledPercentiles()) &&
histogram.getBucketsMs() == null) {
+ histogram.setBucketsMs(DEFAULT_BUCKETS_MS);
+ }
+
+ metricRegister = new
HistogramMetricRegister(MetricsGlobalRegistry.getCompositeRegistry(),
histogram);
+ }
+ }
+
+ private void registerListener() {
+
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class).addListener(this);
+ }
+
+ @Override
+ public void onEvent(MetricsEvent event) {
+ if (event instanceof RTEvent) {
+ onRTEvent((RTEvent) event);
+ }
+ }
+
+ private void onRTEvent(RTEvent event) {
+ if (metricRegister != null) {
+ MethodMetric metric = (MethodMetric) event.getSource();
+ Long responseTime = event.getRt();
+
+ HistogramMetricSample sample = new
HistogramMetricSample(MetricsKey.METRIC_RT_HISTOGRAM.getNameByType(metric.getSide()),
+ MetricsKey.METRIC_RT_HISTOGRAM.getDescription(),
metric.getTags(), RT);
+
+ Timer timer = ConcurrentHashMapUtils.computeIfAbsent(rt, metric, k
-> metricRegister.register(sample));
+ timer.record(responseTime, TimeUnit.MILLISECONDS);
+ }
+ }
+}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/HistogramMetricRegister.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/HistogramMetricRegister.java
new file mode 100644
index 0000000000..04a173cdee
--- /dev/null
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/HistogramMetricRegister.java
@@ -0,0 +1,81 @@
+/*
+ * 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.register;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.Timer;
+import org.apache.dubbo.config.nested.HistogramConfig;
+import org.apache.dubbo.metrics.sample.HistogramMetricSample;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class HistogramMetricRegister implements
MetricRegister<HistogramMetricSample, Timer> {
+
+ private final MeterRegistry registry;
+ private final HistogramConfig config;
+
+ public HistogramMetricRegister(MeterRegistry registry, HistogramConfig
config) {
+ this.registry = registry;
+ this.config = config;
+ }
+
+ @Override
+ public Timer register(HistogramMetricSample sample) {
+ List<Tag> tags = new ArrayList<>();
+ sample.getTags().forEach((k, v) -> {
+ if (v == null) {
+ v = "";
+ }
+
+ tags.add(Tag.of(k, v));
+ });
+
+ Timer.Builder builder =
Timer.builder(sample.getName()).description(sample.getDescription()).tags(tags);
+
+ if (Boolean.TRUE.equals(config.getEnabledPercentiles())) {
+ builder.publishPercentileHistogram(true);
+ }
+
+ if (config.getPercentiles() != null) {
+ builder.publishPercentiles(config.getPercentiles());
+ }
+
+ if (config.getBucketsMs() != null) {
+ builder.serviceLevelObjectives(Arrays.stream(config.getBucketsMs())
+ .map(Duration::ofMillis).toArray(Duration[]::new));
+ }
+
+ if (config.getMinExpectedMs() != null) {
+
builder.minimumExpectedValue(Duration.ofMillis(config.getMinExpectedMs()));
+ }
+
+ if (config.getMaxExpectedMs() != null) {
+
builder.maximumExpectedValue(Duration.ofMillis(config.getMaxExpectedMs()));
+ }
+
+ if (config.getDistributionStatisticExpiryMin() != null) {
+
builder.distributionStatisticExpiry(Duration.ofMinutes(config.getDistributionStatisticExpiryMin()));
+ }
+
+ return builder.register(registry);
+ }
+}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/MetricRegister.java
similarity index 53%
copy from
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
copy to
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/MetricRegister.java
index 00351aedcc..fbf6c5eeb0 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/register/MetricRegister.java
@@ -14,28 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.metrics;
-import io.micrometer.core.instrument.MeterRegistry;
-import io.micrometer.core.instrument.binder.MeterBinder;
-import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
-import org.apache.dubbo.metrics.report.AbstractMetricsReporter;
+package org.apache.dubbo.metrics.register;
+import io.micrometer.core.instrument.Meter;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
-public class DubboMetrics implements MeterBinder {
+public interface MetricRegister<S extends MetricSample, M extends Meter> {
- private MeterRegistry globalRegistry = null;
+ M register(S sample);
- @Override
- public void bindTo(MeterRegistry registry) {
- globalRegistry = registry;
- CompositeMeterRegistry compositeRegistry =
AbstractMetricsReporter.compositeRegistry;
- if (compositeRegistry != null) {
- compositeRegistry.add(registry);
- }
- }
-
- public void destroy() {
- }
}
-
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java
index 4a0558b387..78215624e9 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java
@@ -24,9 +24,11 @@ import org.apache.dubbo.common.constants.MetricsConstants;
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metrics.MetricsGlobalRegistry;
import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.metrics.collector.AggregateMetricsCollector;
import org.apache.dubbo.metrics.collector.MetricsCollector;
+import org.apache.dubbo.metrics.collector.HistogramMetricsCollector;
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -68,7 +70,7 @@ public abstract class AbstractMetricsReporter implements
MetricsReporter {
protected final List<MetricsCollector> collectors = new ArrayList<>();
// Avoid instances being gc due to weak references
protected final List<MeterBinder> instanceHolder = new ArrayList<>();
- public static final CompositeMeterRegistry compositeRegistry = new
CompositeMeterRegistry();
+ protected final CompositeMeterRegistry compositeRegistry;
private final ApplicationModel applicationModel;
@@ -80,6 +82,7 @@ public abstract class AbstractMetricsReporter implements
MetricsReporter {
protected AbstractMetricsReporter(URL url, ApplicationModel
applicationModel) {
this.url = url;
this.applicationModel = applicationModel;
+ this.compositeRegistry = MetricsGlobalRegistry.getCompositeRegistry();
}
@Override
@@ -134,6 +137,7 @@ public abstract class AbstractMetricsReporter implements
MetricsReporter {
private void initCollectors() {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.getOrRegisterBean(AggregateMetricsCollector.class);
+ beanFactory.getOrRegisterBean(HistogramMetricsCollector.class);
List<MetricsCollector> otherCollectors =
beanFactory.getBeansOfType(MetricsCollector.class);
collectors.addAll(otherCollectors);
}
diff --git
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/sample/HistogramMetricSample.java
similarity index 54%
copy from
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
copy to
dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/sample/HistogramMetricSample.java
index 00351aedcc..8f8149c1b5 100644
---
a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java
+++
b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/sample/HistogramMetricSample.java
@@ -14,28 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.metrics;
-import io.micrometer.core.instrument.MeterRegistry;
-import io.micrometer.core.instrument.binder.MeterBinder;
-import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
-import org.apache.dubbo.metrics.report.AbstractMetricsReporter;
+package org.apache.dubbo.metrics.sample;
+import org.apache.dubbo.metrics.model.MetricsCategory;
+import org.apache.dubbo.metrics.model.sample.MetricSample;
-public class DubboMetrics implements MeterBinder {
+import java.util.Map;
- private MeterRegistry globalRegistry = null;
+public class HistogramMetricSample extends MetricSample {
- @Override
- public void bindTo(MeterRegistry registry) {
- globalRegistry = registry;
- CompositeMeterRegistry compositeRegistry =
AbstractMetricsReporter.compositeRegistry;
- if (compositeRegistry != null) {
- compositeRegistry.add(registry);
- }
+ public HistogramMetricSample(String name, String description, Map<String,
String> tags, MetricsCategory category) {
+ super(name, description, tags, Type.TIMER, category);
}
- public void destroy() {
+ public HistogramMetricSample(String name, String description, Map<String,
String> tags, Type type, MetricsCategory category, String baseUnit) {
+ super(name, description, tags, type, category, baseUnit);
}
}
-