From c2c4b63ac9593c3801804e909554d95518012b0c Mon Sep 17 00:00:00 2001 From: robertohuang Date: Wed, 12 Jun 2019 17:22:19 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9BufferPoolMetricSet?= =?UTF-8?q?=E6=94=AF=E6=8C=81JMX=E9=87=87=E9=9B=86=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E6=8C=87=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改MetricRegistryImpl添加取消所有已注册指标的方法 --- .../alibaba/metrics/MetricRegistryImpl.java | 13 ++++ .../metrics/jvm/BufferPoolMetricSet.java | 17 ++--- .../metrics/jvm/JmxRemoteMetricsTest.java | 62 +++++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 metrics-openjdk/src/test/java/com/alibaba/metrics/jvm/JmxRemoteMetricsTest.java diff --git a/metrics-core-impl/src/main/java/com/alibaba/metrics/MetricRegistryImpl.java b/metrics-core-impl/src/main/java/com/alibaba/metrics/MetricRegistryImpl.java index d0511cb..c2178e3 100644 --- a/metrics-core-impl/src/main/java/com/alibaba/metrics/MetricRegistryImpl.java +++ b/metrics-core-impl/src/main/java/com/alibaba/metrics/MetricRegistryImpl.java @@ -65,6 +65,19 @@ public T register(String name, T metric) throws IllegalArgume return register(MetricName.build(name), metric); } + /** + * 〈unRegister all metrics.〉 + * + * eg: + * When collecting remote machine JVM metrics through the JMX port, May be due to network jitter or + * remote process restart, Need to cancel the previously collected metrics and re-register. + * + * @date 2019.06.06 14:35:45 + */ + public void unRegisterAll() { + metrics.clear(); + } + /** * Given a {@link Metric}, registers it under the given name. * diff --git a/metrics-openjdk/src/main/java/com/alibaba/metrics/jvm/BufferPoolMetricSet.java b/metrics-openjdk/src/main/java/com/alibaba/metrics/jvm/BufferPoolMetricSet.java index bb8bc6f..49ef238 100644 --- a/metrics-openjdk/src/main/java/com/alibaba/metrics/jvm/BufferPoolMetricSet.java +++ b/metrics-openjdk/src/main/java/com/alibaba/metrics/jvm/BufferPoolMetricSet.java @@ -25,8 +25,9 @@ import org.slf4j.LoggerFactory; import javax.management.JMException; -import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; import javax.management.ObjectName; +import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -42,10 +43,10 @@ public class BufferPoolMetricSet implements MetricSet { private static final String[] NAMES = { "count", "used", "capacity" }; private static final String[] POOLS = { "direct", "mapped" }; - private final MBeanServer mBeanServer; + private final MBeanServerConnection mBeanServerConnection; - public BufferPoolMetricSet(MBeanServer mBeanServer) { - this.mBeanServer = mBeanServer; + public BufferPoolMetricSet(MBeanServerConnection mBeanServerConnection) { + this.mBeanServerConnection = mBeanServerConnection; } @Override @@ -55,14 +56,14 @@ public Map getMetrics() { for (int i = 0; i < ATTRIBUTES.length; i++) { final String attribute = ATTRIBUTES[i]; final String name = NAMES[i]; - try { final ObjectName on = new ObjectName("java.nio:type=BufferPool,name=" + pool); - mBeanServer.getMBeanInfo(on); - gauges.put(MetricRegistry.name(pool, name), - new JmxAttributeGauge(mBeanServer, on, attribute)); + mBeanServerConnection.getMBeanInfo(on); + gauges.put(MetricRegistry.name(pool, name), new JmxAttributeGauge(mBeanServerConnection, on, attribute)); } catch (JMException ignored) { LOGGER.debug("Unable to load buffer pool MBeans, possibly running on Java 6"); + } catch (IOException ioException) { + LOGGER.debug("Unable to load buffer pool MBeans, an exception occur, cause of", ioException); } } } diff --git a/metrics-openjdk/src/test/java/com/alibaba/metrics/jvm/JmxRemoteMetricsTest.java b/metrics-openjdk/src/test/java/com/alibaba/metrics/jvm/JmxRemoteMetricsTest.java new file mode 100644 index 0000000..ad84276 --- /dev/null +++ b/metrics-openjdk/src/test/java/com/alibaba/metrics/jvm/JmxRemoteMetricsTest.java @@ -0,0 +1,62 @@ +/* + * 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 com.alibaba.metrics.jvm; + +import com.alibaba.metrics.Gauge; +import com.alibaba.metrics.MetricName; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Before; +import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; + +/** + * 〈jmx remote metrics test.〉 + * + * @create 2019/6/6 + */ +public class JmxRemoteMetricsTest { + private ObjectName mapped; + private final MetricName MAPPED = MetricName.build("mapped"); + private final MetricName MAPPED_USED = MAPPED.resolve("used"); + + /** + * You can get the MBeanServerConnection in the following way: + * + * Map environment = new HashMap(); + * environment.put(JMXConnector.CREDENTIALS, new String[]{USERNAME, PASSWORD}); + * JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); + * MBeanServerConnection mBeanServerConnection = JMXConnectorFactory.connect(jmxServiceURL, environment).getMBeanServerConnection(); + **/ + private final MBeanServerConnection mBeanServerConnection = mock(MBeanServerConnection.class); + + @Before + public void setUp() throws Exception { + this.mapped = new ObjectName("java.nio:type=BufferPool,name=mapped"); + } + + @Test + public void testCollectionRemoteMetrics() throws Exception { + BufferPoolMetricSet bufferPoolMetricSet = new BufferPoolMetricSet(mBeanServerConnection); + final Gauge gauge = (Gauge) bufferPoolMetricSet.getMetrics().get(MAPPED_USED); + when(mBeanServerConnection.getAttribute(mapped, "MemoryUsed")).thenReturn(100); + assertThat(gauge.getValue()).isEqualTo(100); + } +} \ No newline at end of file From 00a525a3cf7fe5d0685fecd906818671a6edc7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=A4=AA=E6=B4=AA?= Date: Thu, 9 Apr 2020 21:20:44 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E7=9B=91=E6=8E=A7=E6=9E=84=E9=80=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E5=8F=AF=E9=80=89=E7=9A=84Histogram?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InstrumentedExecutorService.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java index a89c98d..9f47d95 100644 --- a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java +++ b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java @@ -19,6 +19,7 @@ import com.alibaba.metrics.Counter; import com.alibaba.metrics.Meter; import com.alibaba.metrics.MetricRegistry; +import com.alibaba.metrics.ReservoirType; import com.alibaba.metrics.Timer; import java.util.ArrayList; @@ -77,6 +78,23 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi this.rejected = registry.meter(MetricRegistry.name(name, "rejected")); } + /** + * Wraps an {@link ExecutorService} with an explicit name. + * + * @param delegate {@link ExecutorService} to wrap. + * @param registry {@link MetricRegistry} that will contain the metrics. + * @param name name for this executor service. + * @param reservoirType reservoirType for timer inner Histogram metric. + */ + public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry registry, String name, ReservoirType reservoirType) { + this.delegate = delegate; + this.submitted = registry.meter(MetricRegistry.name(name, "submitted")); + this.running = registry.counter(MetricRegistry.name(name, "running")); + this.completed = registry.meter(MetricRegistry.name(name, "completed")); + this.duration = registry.timer(MetricRegistry.name(name, "duration"), reservoirType); + this.rejected = registry.meter(MetricRegistry.name(name, "rejected")); + } + /** * {@inheritDoc} */ From 435c63914324f9efe80ca92d42dddfb777b65087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=A4=AA=E6=B4=AA?= Date: Fri, 10 Apr 2020 15:29:26 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E7=9B=91=E6=8E=A7=E9=87=8D=E8=BD=BD=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InstrumentedExecutorService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java index 9f47d95..64aa73e 100644 --- a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java +++ b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java @@ -18,6 +18,8 @@ import com.alibaba.metrics.Counter; import com.alibaba.metrics.Meter; +import com.alibaba.metrics.MetricLevel; +import com.alibaba.metrics.MetricName; import com.alibaba.metrics.MetricRegistry; import com.alibaba.metrics.ReservoirType; import com.alibaba.metrics.Timer; @@ -25,6 +27,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -95,6 +98,25 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi this.rejected = registry.meter(MetricRegistry.name(name, "rejected")); } + /** + * Wraps an {@link ExecutorService} with an explicit name. + * + * @param delegate {@link ExecutorService} to wrap. + * @param registry {@link MetricRegistry} that will contain the metrics. + * @param name name for this executor service. + * @param metricLevel metricLevel of metric. + * @param metricTags metricTags of metric. + * @param reservoirType reservoirType of metric. + */ + public InstrumentedExecutorService(final ExecutorService delegate, final MetricRegistry registry, final String name, final Map metricTags, final MetricLevel metricLevel, final ReservoirType reservoirType) { + this.delegate = delegate; + this.submitted = registry.meter(new MetricName(name + MetricName.SEPARATOR + "submitted", metricTags, metricLevel)); + this.running = registry.counter(new MetricName(name + MetricName.SEPARATOR + "running", metricTags, metricLevel)); + this.completed = registry.meter(new MetricName(name + MetricName.SEPARATOR + "completed", metricTags, metricLevel)); + this.duration = registry.timer(new MetricName(name + MetricName.SEPARATOR + "duration", metricTags, metricLevel), reservoirType); + this.rejected = registry.meter(new MetricName(name + MetricName.SEPARATOR + "rejected", metricTags, metricLevel)); + } + /** * {@inheritDoc} */ From d7d43ea344abd2a51a0d02bfe715df06ed497ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=A4=AA=E6=B4=AA?= Date: Wed, 22 Apr 2020 17:12:33 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=B1=A0=E6=8C=87=E6=A0=87=E7=9B=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InstrumentedExecutorService.java | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java index 64aa73e..a457a31 100644 --- a/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java +++ b/metrics-core-impl/src/main/java/com/alibaba/metrics/instrument/InstrumentedExecutorService.java @@ -21,11 +21,13 @@ import com.alibaba.metrics.MetricLevel; import com.alibaba.metrics.MetricName; import com.alibaba.metrics.MetricRegistry; +import com.alibaba.metrics.PersistentGauge; import com.alibaba.metrics.ReservoirType; import com.alibaba.metrics.Timer; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; @@ -33,6 +35,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; @@ -73,12 +76,7 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi * @param name name for this executor service. */ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry registry, String name) { - this.delegate = delegate; - this.submitted = registry.meter(MetricRegistry.name(name, "submitted")); - this.running = registry.counter(MetricRegistry.name(name, "running")); - this.completed = registry.meter(MetricRegistry.name(name, "completed")); - this.duration = registry.timer(MetricRegistry.name(name, "duration")); - this.rejected = registry.meter(MetricRegistry.name(name, "rejected")); + this(delegate, registry, name, ReservoirType.EXPONENTIALLY_DECAYING); } /** @@ -90,12 +88,7 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi * @param reservoirType reservoirType for timer inner Histogram metric. */ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry registry, String name, ReservoirType reservoirType) { - this.delegate = delegate; - this.submitted = registry.meter(MetricRegistry.name(name, "submitted")); - this.running = registry.counter(MetricRegistry.name(name, "running")); - this.completed = registry.meter(MetricRegistry.name(name, "completed")); - this.duration = registry.timer(MetricRegistry.name(name, "duration"), reservoirType); - this.rejected = registry.meter(MetricRegistry.name(name, "rejected")); + this(delegate, registry, name, new HashMap(), MetricLevel.CRITICAL, reservoirType); } /** @@ -110,6 +103,43 @@ public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry regi */ public InstrumentedExecutorService(final ExecutorService delegate, final MetricRegistry registry, final String name, final Map metricTags, final MetricLevel metricLevel, final ReservoirType reservoirType) { this.delegate = delegate; + if (delegate instanceof ThreadPoolExecutor) { + final ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) delegate; + registry.register(new MetricName(name + MetricName.SEPARATOR + "maxThreadPoolSize", metricTags, metricLevel), new PersistentGauge() { + @Override + public Object getValue() { + return threadPoolExecutor.getMaximumPoolSize(); + } + }); + + registry.register(new MetricName(name + MetricName.SEPARATOR + "coreThreadPoolSize", metricTags, metricLevel), new PersistentGauge() { + @Override + public Object getValue() { + return threadPoolExecutor.getCorePoolSize(); + } + }); + + registry.register(new MetricName(name + MetricName.SEPARATOR + "currentThreadPoolSize", metricTags, metricLevel), new PersistentGauge() { + @Override + public Object getValue() { + return threadPoolExecutor.getPoolSize(); + } + }); + + registry.register(new MetricName(name + MetricName.SEPARATOR + "activeThreadPoolSize", metricTags, metricLevel), new PersistentGauge() { + @Override + public Object getValue() { + return threadPoolExecutor.getActiveCount(); + } + }); + + registry.register(new MetricName(name + MetricName.SEPARATOR + "threadPoolQueueSize", metricTags, metricLevel), new PersistentGauge() { + @Override + public Object getValue() { + return threadPoolExecutor.getQueue().size(); + } + }); + } this.submitted = registry.meter(new MetricName(name + MetricName.SEPARATOR + "submitted", metricTags, metricLevel)); this.running = registry.counter(new MetricName(name + MetricName.SEPARATOR + "running", metricTags, metricLevel)); this.completed = registry.meter(new MetricName(name + MetricName.SEPARATOR + "completed", metricTags, metricLevel));