This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit 1ac6afbfe8baa2b07a521e4d38dfb99fac324c3e Author: liubao <[email protected]> AuthorDate: Mon Nov 27 17:36:30 2023 +0800 [SCB-2838]using micrometer to replace spectator part3: ThreadPool --- .../metrics/publish/spectator/MeasurementNode.java | 21 +++++++-- .../metrics/publish/spectator/MeasurementTree.java | 10 ++-- .../publish/spectator/TestDefaultTagFinder.java | 10 ++-- .../publish/spectator/TestMeasurementNode.java | 28 ++++++----- .../publish/spectator/TestMeasurementTree.java | 35 +++++++------- .../ThreadPoolMonitorPublishModelFactory.java | 35 +++++++------- .../metrics/core/ThreadPoolMetersInitializer.java | 55 ++++++++++++++++------ 7 files changed, 119 insertions(+), 75 deletions(-) diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementNode.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementNode.java index 272f6b87e..6cace285b 100644 --- a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementNode.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementNode.java @@ -22,21 +22,29 @@ import java.util.List; import java.util.Map; import io.micrometer.core.instrument.Measurement; +import io.micrometer.core.instrument.Meter.Id; public class MeasurementNode implements Comparable<MeasurementNode> { private final String name; + private final Id id; + private final List<Measurement> measurements = new ArrayList<>(); private Map<String, MeasurementNode> children; - public MeasurementNode(String name, Map<String, MeasurementNode> children) { + public MeasurementNode(String name, Id id, Map<String, MeasurementNode> children) { this.name = name; + this.id = id; this.children = children; } public String getName() { - return name; + return id.getName(); + } + + public Id getId() { + return id; } public Map<String, MeasurementNode> getChildren() { @@ -62,13 +70,16 @@ public class MeasurementNode implements Comparable<MeasurementNode> { return node; } - public MeasurementNode addChild(String childName, Measurement measurement) { + public MeasurementNode addChild(String childName, Id id, Measurement measurement) { if (children == null) { children = new LinkedHashMap<>(); } - MeasurementNode node = children.computeIfAbsent(childName, name -> new MeasurementNode(name, null)); - node.addMeasurement(measurement); + MeasurementNode node = children.computeIfAbsent(childName, name -> new MeasurementNode(name, id, null)); + + if (measurement != null) { + node.addMeasurement(measurement); + } return node; } diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java index e2dbd268b..a165ca935 100644 --- a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/spectator/MeasurementTree.java @@ -28,7 +28,7 @@ import io.micrometer.core.instrument.Tag; // but output a tree not a table public class MeasurementTree extends MeasurementNode { public MeasurementTree() { - super(null, null); + super(null, null, null); } // groupConfig: @@ -44,7 +44,7 @@ public class MeasurementTree extends MeasurementNode { public void from(Id id, Iterable<Measurement> measurements, MeasurementGroupConfig groupConfig) { for (Measurement measurement : measurements) { - MeasurementNode node = addChild(id.getName(), measurement); + MeasurementNode node = addChild(id.getName(), id, null); List<TagFinder> tagFinders = groupConfig.findTagFinders(id.getName()); if (tagFinders == null) { @@ -60,11 +60,13 @@ public class MeasurementTree extends MeasurementNode { throw new IllegalStateException( String.format("tag key \"%s\" not exist in %s", tagFinder.getTagKey(), - measurement)); + id)); } - node = node.addChild(tag.getValue(), measurement); + node = node.addChild(tag.getValue(), id, null); } + + node.addChild(measurement.getStatistic().name(), id, measurement); } } } diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestDefaultTagFinder.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestDefaultTagFinder.java index c892b6a8b..cc9dcadcc 100644 --- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestDefaultTagFinder.java +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestDefaultTagFinder.java @@ -19,11 +19,11 @@ package org.apache.servicecomb.foundation.metrics.publish.spectator; import java.util.Arrays; import java.util.List; -import com.netflix.spectator.api.BasicTag; -import com.netflix.spectator.api.Tag; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import io.micrometer.core.instrument.Tag; + public class TestDefaultTagFinder { TagFinder finder = new DefaultTagFinder("key"); @@ -34,8 +34,8 @@ public class TestDefaultTagFinder { @Test public void readSucc() { - Tag tag = new BasicTag("key", "value"); - List<Tag> tags = Arrays.asList(new BasicTag("t1", "t1v"), + Tag tag = Tag.of("key", "value"); + List<Tag> tags = Arrays.asList(Tag.of("t1", "t1v"), tag); Assertions.assertSame(tag, finder.find(tags)); @@ -43,7 +43,7 @@ public class TestDefaultTagFinder { @Test public void readFail() { - List<Tag> tags = Arrays.asList(new BasicTag("t1", "t1v")); + List<Tag> tags = Arrays.asList(Tag.of("t1", "t1v")); Assertions.assertNull(finder.find(tags)); } diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementNode.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementNode.java index 7c5691f92..a366cee54 100644 --- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementNode.java +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementNode.java @@ -22,15 +22,19 @@ import java.util.Map; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Test; +import org.junit.jupiter.api.Assertions; -import com.netflix.spectator.api.Measurement; - +import io.micrometer.core.instrument.Measurement; +import io.micrometer.core.instrument.Meter.Id; +import io.micrometer.core.instrument.Meter.Type; +import io.micrometer.core.instrument.Tags; import mockit.Expectations; import mockit.Mocked; -import org.junit.jupiter.api.Assertions; public class TestMeasurementNode { - MeasurementNode node = new MeasurementNode("name", null); + Id id = new Id("name", Tags.empty(), null, null, Type.OTHER); + + MeasurementNode node = new MeasurementNode("name", id, null); @Test public void getName() { @@ -40,7 +44,7 @@ public class TestMeasurementNode { @Test public void getChildren() { Map<String, MeasurementNode> children = new HashMap<>(); - node = new MeasurementNode("name", children); + node = new MeasurementNode("name", id, children); Assertions.assertSame(children, node.getChildren()); } @@ -52,24 +56,24 @@ public class TestMeasurementNode { @Test public void findChild_multiLevel_noMiddleChildren(@Mocked Measurement measurement) { - MeasurementNode c1 = node.addChild("c1", measurement); - c1.addChild("c2", measurement); + MeasurementNode c1 = node.addChild("c1", id, measurement); + c1.addChild("c2", id, measurement); Assertions.assertNull(node.findChild("c1_notExist", "c2")); } @Test public void findChild_multiLevel_ok(@Mocked Measurement measurement) { - MeasurementNode c1 = node.addChild("c1", measurement); - MeasurementNode c2 = c1.addChild("c2", measurement); + MeasurementNode c1 = node.addChild("c1", id, measurement); + MeasurementNode c2 = c1.addChild("c2", id, measurement); Assertions.assertSame(c2, node.findChild("c1", "c2")); } @Test public void addChild(@Mocked Measurement measurement) { - MeasurementNode c1 = node.addChild("c1", measurement); - MeasurementNode c2 = node.addChild("c2", measurement); + MeasurementNode c1 = node.addChild("c1", id, measurement); + MeasurementNode c2 = node.addChild("c2", id, measurement); Assertions.assertSame(c1, node.findChild("c1")); Assertions.assertSame(c2, node.findChild("c2")); @@ -86,7 +90,7 @@ public class TestMeasurementNode { public void summary(@Mocked Measurement measurement) { new Expectations() { { - measurement.value(); + measurement.getValue(); result = 10; } }; diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementTree.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementTree.java index 108831d0b..44037f7a3 100644 --- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementTree.java +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementTree.java @@ -22,18 +22,15 @@ import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Assertions; -import com.netflix.spectator.api.DefaultRegistry; -import com.netflix.spectator.api.ManualClock; -import com.netflix.spectator.api.Registry; -import com.netflix.spectator.api.Statistic; -import com.netflix.spectator.api.Timer; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Statistic; +import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; public class TestMeasurementTree { MeasurementTree tree = new MeasurementTree(); - ManualClock clock = new ManualClock(); - - Registry registry = new DefaultRegistry(clock); + MeterRegistry registry = new SimpleMeterRegistry(); Timer timer; @@ -53,17 +50,19 @@ public class TestMeasurementTree { @Test public void from() { - timer.record(10, TimeUnit.NANOSECONDS); - timer.record(2, TimeUnit.NANOSECONDS); + timer.record(10, TimeUnit.SECONDS); + timer.record(2, TimeUnit.SECONDS); - MeasurementGroupConfig config = new MeasurementGroupConfig("id", "g1", "g2", Statistic.count.key()); - tree.from(registry.iterator(), config); + MeasurementGroupConfig config = new MeasurementGroupConfig("id", "g1", "g2"); + tree.from(registry.getMeters().iterator(), config); Assertions.assertEquals(2, tree.getChildren().size()); MeasurementNode node = tree.findChild("id", "g1v", "g2v"); - Assertions.assertEquals(2d, node.findChild(Statistic.count.value()).getMeasurements().get(0).value(), 0); - Assertions.assertEquals(12d, node.findChild(Statistic.totalTime.value()).getMeasurements().get(0).value(), 0); + Assertions.assertEquals(2d, + node.findChild(Statistic.COUNT.name()).getMeasurements().get(0).getValue(), 0); + Assertions.assertEquals(12d, + node.findChild(Statistic.TOTAL_TIME.name()).getMeasurements().get(0).getValue(), 0); Assertions.assertEquals(0d, tree.findChild("id_notCare").summary(), 0); } @@ -71,7 +70,7 @@ public class TestMeasurementTree { public void from_withSkipOnNull() { try { MeasurementGroupConfig config = new MeasurementGroupConfig("id", new DefaultTagFinder("notExist", true)); - tree.from(registry.iterator(), config); + tree.from(registry.getMeters().iterator(), config); } catch (Exception e) { Assertions.fail("should not throw exception"); } @@ -81,8 +80,10 @@ public class TestMeasurementTree { public void from_failed() { IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> { MeasurementGroupConfig config = new MeasurementGroupConfig("id", "notExist"); - tree.from(registry.iterator(), config); + tree.from(registry.getMeters().iterator(), config); }); - Assertions.assertEquals("tag key \"notExist\" not exist in Measurement(id:g1=g1v:g2=g2v:statistic=count:t3=t3v:t4=t4v,0,0.0)", exception.getMessage()); + Assertions.assertEquals( + "tag key \"notExist\" not exist in MeterId{name='id', tags=[tag(g1=g1v),tag(g2=g2v),tag(t3=t3v),tag(t4=t4v)]}", + exception.getMessage()); } } diff --git a/metrics/metrics-core/src/main/java/com/netflix/spectator/api/patterns/ThreadPoolMonitorPublishModelFactory.java b/metrics/metrics-core/src/main/java/com/netflix/spectator/api/patterns/ThreadPoolMonitorPublishModelFactory.java index 3b8ba946f..c631defb7 100644 --- a/metrics/metrics-core/src/main/java/com/netflix/spectator/api/patterns/ThreadPoolMonitorPublishModelFactory.java +++ b/metrics/metrics-core/src/main/java/com/netflix/spectator/api/patterns/ThreadPoolMonitorPublishModelFactory.java @@ -23,8 +23,7 @@ import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementTr import org.apache.servicecomb.metrics.core.ThreadPoolMetersInitializer; import org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel; -import com.netflix.spectator.api.Measurement; -import com.netflix.spectator.api.Utils; +import io.micrometer.core.instrument.Measurement; public class ThreadPoolMonitorPublishModelFactory { interface Setter { @@ -47,22 +46,22 @@ public class ThreadPoolMonitorPublishModelFactory { } public void create() { - readMeasurement(ThreadPoolMonitor.TASK_COUNT, - (model, measurement) -> model.setAvgTaskCount(measurement.value())); - readMeasurement(ThreadPoolMonitor.COMPLETED_TASK_COUNT, - (model, measurement) -> model.setAvgCompletedTaskCount(measurement.value())); - readMeasurement(ThreadPoolMonitor.CURRENT_THREADS_BUSY, - (model, measurement) -> model.setCurrentThreadsBusy((int) measurement.value())); - readMeasurement(ThreadPoolMonitor.MAX_THREADS, - (model, measurement) -> model.setMaxThreads((int) measurement.value())); - readMeasurement(ThreadPoolMonitor.POOL_SIZE, - (model, measurement) -> model.setPoolSize((int) measurement.value())); - readMeasurement(ThreadPoolMonitor.CORE_POOL_SIZE, - (model, measurement) -> model.setCorePoolSize((int) measurement.value())); - readMeasurement(ThreadPoolMonitor.QUEUE_SIZE, - (model, measurement) -> model.setQueueSize((int) measurement.value())); + readMeasurement(ThreadPoolMetersInitializer.TASK_COUNT, + (model, measurement) -> model.setAvgTaskCount(measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.COMPLETED_TASK_COUNT, + (model, measurement) -> model.setAvgCompletedTaskCount(measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.CURRENT_THREADS_BUSY, + (model, measurement) -> model.setCurrentThreadsBusy((int) measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.MAX_THREADS, + (model, measurement) -> model.setMaxThreads((int) measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.POOL_SIZE, + (model, measurement) -> model.setPoolSize((int) measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.CORE_POOL_SIZE, + (model, measurement) -> model.setCorePoolSize((int) measurement.getValue())); + readMeasurement(ThreadPoolMetersInitializer.QUEUE_SIZE, + (model, measurement) -> model.setQueueSize((int) measurement.getValue())); readMeasurement(ThreadPoolMetersInitializer.REJECTED_COUNT, - (model, measurement) -> model.setRejected(measurement.value())); + (model, measurement) -> model.setRejected(measurement.getValue())); } protected void readMeasurement(String name, Setter setter) { @@ -72,7 +71,7 @@ public class ThreadPoolMonitorPublishModelFactory { } for (Measurement measurement : node.getMeasurements()) { - String threadPoolName = Utils.getTagValue(measurement.id(), ThreadPoolMonitor.ID_TAG_NAME); + String threadPoolName = node.getId().getTag(ThreadPoolMetersInitializer.ID); if (threadPoolName == null) { continue; } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/ThreadPoolMetersInitializer.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/ThreadPoolMetersInitializer.java index 1c30f3951..ebe0c019a 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/ThreadPoolMetersInitializer.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/ThreadPoolMetersInitializer.java @@ -26,16 +26,34 @@ import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.core.definition.MicroserviceMeta; import org.apache.servicecomb.core.definition.OperationMeta; import org.apache.servicecomb.core.executor.GroupExecutor; +import org.apache.servicecomb.core.executor.ThreadPoolExecutorEx; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig; import org.apache.servicecomb.foundation.metrics.MetricsInitializer; import com.google.common.eventbus.EventBus; +import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; public class ThreadPoolMetersInitializer implements MetricsInitializer { - public static String REJECTED_COUNT = "threadpool.rejectedCount"; + public static final String ID = "id"; + + public static final String REJECTED_COUNT = "threadpool.rejectedCount"; + + public static final String TASK_COUNT = "threadpool.taskCount"; + + public static final String COMPLETED_TASK_COUNT = "threadpool.completedTaskCount"; + + public static final String CURRENT_THREADS_BUSY = "threadpool.currentThreadsBusy"; + + public static final String MAX_THREADS = "threadpool.maxThreads"; + + public static final String POOL_SIZE = "threadpool.poolSize"; + + public static final String CORE_POOL_SIZE = "threadpool.corePoolSize"; + + public static final String QUEUE_SIZE = "threadpool.queueSize"; private MeterRegistry meterRegistry; @@ -57,7 +75,7 @@ public class ThreadPoolMetersInitializer implements MetricsInitializer { continue; } - if (GroupExecutor.class.isInstance(executor)) { + if (executor instanceof GroupExecutor) { createThreadPoolMeters(entry.getKey(), (GroupExecutor) executor); continue; } @@ -84,20 +102,29 @@ public class ThreadPoolMetersInitializer implements MetricsInitializer { } protected void createThreadPoolMeters(String threadPoolName, Executor executor) { - if (!ThreadPoolExecutor.class.isInstance(executor)) { + if (!(executor instanceof ThreadPoolExecutor threadPoolExecutor)) { return; } - // TODO: add thread pool meter -// ThreadPoolMonitor.attach(registry, (ThreadPoolExecutor) executor, threadPoolName); -// -// if (executor instanceof ThreadPoolExecutorEx) { -// Tag idTag = new BasicTag("id", threadPoolName); -// -// PolledMeter.using(registry) -// .withName(REJECTED_COUNT) -// .withTag(idTag) -// .monitorMonotonicCounter((ThreadPoolExecutorEx) executor, ThreadPoolExecutorEx::getRejectedCount); -// } + Gauge.builder(TASK_COUNT, threadPoolExecutor::getTaskCount).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(COMPLETED_TASK_COUNT, threadPoolExecutor::getCompletedTaskCount).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(CURRENT_THREADS_BUSY, threadPoolExecutor::getActiveCount).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(MAX_THREADS, threadPoolExecutor::getMaximumPoolSize).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(POOL_SIZE, threadPoolExecutor::getPoolSize).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(CORE_POOL_SIZE, threadPoolExecutor::getCorePoolSize).tags(ID, threadPoolName) + .register(meterRegistry); + Gauge.builder(QUEUE_SIZE, () -> threadPoolExecutor.getQueue().size()).tags(ID, threadPoolName) + .register(meterRegistry); + + if (executor instanceof ThreadPoolExecutorEx) { + Gauge.builder(REJECTED_COUNT, () -> ((ThreadPoolExecutorEx) (executor)).getRejectedCount()) + .tags(ID, threadPoolName) + .register(meterRegistry); + } } }
