You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by wu...@apache.org on 2018/04/08 15:14:51 UTC
[incubator-servicecomb-java-chassis] 06/09: SCB-422 convert
threadPool measurements to publish model
This is an automated email from the ASF dual-hosted git repository.
wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit eb4de3fe627f5950aa8b41a4f8fa3155be5d72b1
Author: wujimin <wu...@huawei.com>
AuthorDate: Mon Apr 2 11:31:20 2018 +0800
SCB-422 convert threadPool measurements to publish model
---
.../metrics/publish/spectator/MeasurementTree.java | 3 +-
.../publish/spectator/TestMeasurementTree.java | 3 +-
.../ThreadPoolMonitorPublishModelFactory.java | 98 ++++++++++++++++++++++
.../metrics/core/publish/PublishModelFactory.java | 10 ++-
...java => TestInvocationPublishModelFactory.java} | 59 +++++++------
.../metrics/core/publish/TestPublishUtils.java | 15 +++-
.../publish/TestThreadPoolPublishModelFactory.java | 78 +++++++++++++++++
7 files changed, 232 insertions(+), 34 deletions(-)
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 056bba6..1a07720 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
@@ -45,12 +45,13 @@ public class MeasurementTree extends MeasurementNode {
public void from(Iterable<Measurement> measurements, MeasurementGroupConfig groupConfig) {
for (Measurement measurement : measurements) {
Id id = measurement.id();
+ MeasurementNode node = addChild(id.name(), measurement);
+
List<TagFinder> tagFinders = groupConfig.findTagFinders(id.name());
if (tagFinders == null) {
continue;
}
- MeasurementNode node = addChild(id.name(), measurement);
for (TagFinder tagFinder : tagFinders) {
Tag tag = tagFinder.find(id.tags());
if (tag == null) {
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 a3eb50d..e568c67 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
@@ -65,11 +65,12 @@ public class TestMeasurementTree {
MeasurementGroupConfig config = new MeasurementGroupConfig("id", "g1", "g2", Statistic.count.key());
tree.from(registry.iterator(), config);
- Assert.assertEquals(1, tree.getChildren().size());
+ Assert.assertEquals(2, tree.getChildren().size());
MeasurementNode node = tree.findChild("id", "g1v", "g2v");
Assert.assertEquals(2d, node.findChild(Statistic.count.value()).getMeasurements().get(0).value(), 0);
Assert.assertEquals(12d, node.findChild(Statistic.totalTime.value()).getMeasurements().get(0).value(), 0);
+ Assert.assertEquals(0d, tree.findChild("id_notCare").summary(), 0);
}
@Test
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
new file mode 100644
index 0000000..0ffb5a1
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/com/netflix/spectator/api/patterns/ThreadPoolMonitorPublishModelFactory.java
@@ -0,0 +1,98 @@
+/*
+ * 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.netflix.spectator.api.patterns;
+
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementNode;
+import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementTree;
+import org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;
+
+import com.netflix.spectator.api.Measurement;
+import com.netflix.spectator.api.Utils;
+
+public class ThreadPoolMonitorPublishModelFactory {
+ interface Setter {
+ void set(ThreadPoolPublishModel model, Measurement measurement);
+ }
+
+ private MeasurementTree tree;
+
+ private Map<String, ThreadPoolPublishModel> threadPools;
+
+ public ThreadPoolMonitorPublishModelFactory(MeasurementTree tree,
+ Map<String, ThreadPoolPublishModel> threadPools) {
+ this.tree = tree;
+ this.threadPools = threadPools;
+ }
+
+ public static void create(MeasurementTree tree,
+ Map<String, ThreadPoolPublishModel> threadPools) {
+ new ThreadPoolMonitorPublishModelFactory(tree, threadPools).create();
+ }
+
+ 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());
+ });
+ }
+
+ protected void readMeasurement(String name, Setter setter) {
+ MeasurementNode node = tree.findChild(name);
+ if (node == null) {
+ return;
+ }
+
+ for (Measurement measurement : node.getMeasurements()) {
+ String threadPoolName = Utils.getTagValue(measurement.id(), ThreadPoolMonitor.ID_TAG_NAME);
+ if (threadPoolName == null) {
+ continue;
+ }
+
+ ThreadPoolPublishModel model = threadPools.computeIfAbsent(threadPoolName, tpn -> {
+ return new ThreadPoolPublishModel();
+ });
+
+ setter.set(model, measurement);
+ }
+ }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishModelFactory.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishModelFactory.java
index 7d03573..8c311bf 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishModelFactory.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishModelFactory.java
@@ -27,6 +27,7 @@ import org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPer
import org.apache.servicecomb.swagger.invocation.InvocationType;
import com.netflix.spectator.api.Meter;
+import com.netflix.spectator.api.patterns.ThreadPoolMonitorPublishModelFactory;
public class PublishModelFactory {
private MeasurementTree tree;
@@ -52,6 +53,7 @@ public class PublishModelFactory {
MeterInvocationConst.TAG_STATUS,
MeterInvocationConst.TAG_STAGE,
MeterInvocationConst.TAG_STATISTIC);
+
return groupConfig;
}
@@ -80,13 +82,13 @@ public class PublishModelFactory {
public DefaultPublishModel createDefaultPublishModel() {
DefaultPublishModel model = new DefaultPublishModel();
- model
- .getConsumer()
+ model.getConsumer()
.setOperationPerfGroups(generateOperationPerfGroups(tree, InvocationType.CONSUMER.name()));
- model
- .getProducer()
+ model.getProducer()
.setOperationPerfGroups(generateOperationPerfGroups(tree, InvocationType.PRODUCER.name()));
+ ThreadPoolMonitorPublishModelFactory.create(tree, model.getThreadPools());
+
return model;
}
}
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishModelFactory.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
similarity index 56%
rename from metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishModelFactory.java
rename to metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
index 4135cf0..3452b02 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishModelFactory.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
@@ -16,14 +16,14 @@
*/
package org.apache.servicecomb.metrics.core.publish;
-import java.util.List;
-
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;
-import org.apache.servicecomb.metrics.core.DefaultMetricsInitializer;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.apache.servicecomb.foundation.metrics.MetricsInitializer;
+import org.apache.servicecomb.metrics.core.DefaultRegistryInitializer;
+import org.apache.servicecomb.metrics.core.InvocationMetersInitializer;
import org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;
import org.apache.servicecomb.swagger.invocation.InvocationType;
import org.apache.servicecomb.swagger.invocation.Response;
@@ -33,19 +33,25 @@ import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
-import com.netflix.spectator.api.CompositeRegistry;
import com.netflix.spectator.api.DefaultRegistry;
import com.netflix.spectator.api.ManualClock;
-import com.netflix.spectator.api.Meter;
import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.SpectatorUtils;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
-public class TestPublishModelFactory {
+public class TestInvocationPublishModelFactory {
+ EventBus eventBus = new EventBus();
+
+ Registry registry = new DefaultRegistry(new ManualClock());
+
+ @Mocked
+ DefaultRegistryInitializer defaultRegistryInitializer;
+
+ InvocationMetersInitializer invocationMetersInitializer = new InvocationMetersInitializer();
+
@Mocked
Invocation invocation;
@@ -56,28 +62,29 @@ public class TestPublishModelFactory {
@Test
public void createDefaultPublishModel() throws JsonProcessingException {
- Registry registry = prepareRegistry();
- List<Meter> meters = Lists.newArrayList(registry);
- PublishModelFactory factory = new PublishModelFactory(meters);
+ new Expectations(SPIServiceUtils.class) {
+ {
+ SPIServiceUtils.getTargetService(MetricsInitializer.class, DefaultRegistryInitializer.class);
+ result = defaultRegistryInitializer;
+ defaultRegistryInitializer.getRegistry();
+ result = registry;
+ }
+ };
+ invocationMetersInitializer.init(null, eventBus, null);
+ prepareInvocation();
+
+ PublishModelFactory factory = new PublishModelFactory(Lists.newArrayList(registry.iterator()));
DefaultPublishModel model = factory.createDefaultPublishModel();
Assert.assertEquals(
- "{\"consumer\":{\"operationPerfGroups\":{\"groups\":{\"rest\":{\"200\":{\"transport\":\"rest\",\"status\":\"200\",\"operationPerfs\":[{\"operation\":\"m.s.o\",\"stages\":{\"total\":{\"tps\":1,\"msTotalTime\":10000.0,\"msMaxLatency\":0.0}}}],\"summary\":{\"operation\":\"\",\"stages\":{\"total\":{\"tps\":1,\"msTotalTime\":10000.0,\"msMaxLatency\":0.0}}}}}}}},\"producer\":{\"operationPerfGroups\":{\"groups\":{\"rest\":{\"200\":{\"transport\":\"rest\",\"status\":\"200\",\"operationPe [...]
- JsonUtils.writeValueAsString(model));
+ "{\"operationPerfGroups\":{\"groups\":{\"rest\":{\"200\":{\"transport\":\"rest\",\"status\":\"200\",\"operationPerfs\":[{\"operation\":\"m.s.o\",\"stages\":{\"total\":{\"tps\":1,\"msTotalTime\":10000.0,\"msMaxLatency\":0.0}}}],\"summary\":{\"operation\":\"\",\"stages\":{\"total\":{\"tps\":1,\"msTotalTime\":10000.0,\"msMaxLatency\":0.0}}}}}}}}",
+ JsonUtils.writeValueAsString(model.getConsumer()));
+ Assert.assertEquals(
+ "{\"operationPerfGroups\":{\"groups\":{\"rest\":{\"200\":{\"transport\":\"rest\",\"status\":\"200\",\"operationPerfs\":[{\"operation\":\"m.s.o\",\"stages\":{\"execution\":{\"tps\":1,\"msTotalTime\":5000.0,\"msMaxLatency\":0.0},\"total\":{\"tps\":1,\"msTotalTime\":10000.0,\"msMaxLatency\":0.0},\"queue\":{\"tps\":1,\"msTotalTime\":5000.0,\"msMaxLatency\":0.0}}}],\"summary\":{\"operation\":\"\",\"stages\":{\"execution\":{\"tps\":1,\"msTotalTime\":5000.0,\"msMaxLatency\":0.0},\"total [...]
+ JsonUtils.writeValueAsString(model.getProducer()));
}
- protected Registry prepareRegistry() {
- CompositeRegistry globalRegistry = SpectatorUtils.createCompositeRegistry(null);
- Registry registry = new DefaultRegistry(new ManualClock());
- EventBus eventBus = new EventBus();
-
- DefaultMetricsInitializer metricsInitializer = new DefaultMetricsInitializer() {
- protected Registry createRegistry(MetricsBootstrapConfig config) {
- return registry;
- };
- };
- metricsInitializer.init(globalRegistry, eventBus, new MetricsBootstrapConfig());
-
+ protected void prepareInvocation() {
new MockUp<System>() {
@Mock
long nanoTime() {
@@ -125,7 +132,5 @@ public class TestPublishModelFactory {
invocationType = InvocationType.PRODUCER;
eventBus.post(finishEvent);
-
- return registry;
}
}
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishUtils.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishUtils.java
index 29ddcc6..68bd8f1 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishUtils.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishUtils.java
@@ -16,14 +16,16 @@
*/
package org.apache.servicecomb.metrics.core.publish;
+import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.Response.Status;
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementNode;
+import org.apache.servicecomb.foundation.metrics.publish.spectator.MeasurementTree;
import org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;
-import org.apache.servicecomb.metrics.core.publish.PublishUtils;
+import org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;
import org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;
import org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;
import org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;
@@ -32,6 +34,8 @@ import org.apache.servicecomb.metrics.core.publish.model.invocation.Utils;
import org.junit.Assert;
import org.junit.Test;
+import com.netflix.spectator.api.patterns.ThreadPoolMonitorPublishModelFactory;
+
public class TestPublishUtils {
String op = "op";
@@ -72,4 +76,13 @@ public class TestPublishUtils {
Assert.assertEquals(1000, perfInfo.calcMsLatency(), 0);
Assert.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);
}
+
+ @Test
+ public void createThreadPoolPublishModels_empty() {
+ Map<String, ThreadPoolPublishModel> threadPools = new HashMap<>();
+
+ ThreadPoolMonitorPublishModelFactory.create(new MeasurementTree(), threadPools);
+
+ Assert.assertTrue(threadPools.isEmpty());
+ }
}
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java
new file mode 100644
index 0000000..7f000f0
--- /dev/null
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java
@@ -0,0 +1,78 @@
+/*
+ * 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.servicecomb.metrics.core.publish;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.apache.servicecomb.foundation.common.utils.JsonUtils;
+import org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+import com.netflix.spectator.api.DefaultRegistry;
+import com.netflix.spectator.api.ManualClock;
+import com.netflix.spectator.api.Registry;
+import com.netflix.spectator.api.patterns.ThreadPoolMonitor;
+
+import mockit.Expectations;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestThreadPoolPublishModelFactory {
+ protected EventBus eventBus = new EventBus();
+
+ protected Registry registry = new DefaultRegistry(new ManualClock());
+
+ @Mocked
+ ThreadPoolExecutor threadPoolExecutor;
+
+ @Mocked
+ BlockingQueue<Runnable> queue;
+
+ @Test
+ public void createDefaultPublishModel() throws JsonProcessingException {
+ new Expectations() {
+ {
+ threadPoolExecutor.getQueue();
+ result = queue;
+ queue.size();
+ result = 10d;
+ }
+ };
+ new MockUp<ScheduledThreadPoolExecutor>() {
+ @Mock
+ void delayedExecute(RunnableScheduledFuture<?> task) {
+
+ }
+ };
+ ThreadPoolMonitor.attach(registry, threadPoolExecutor, "test");
+
+ PublishModelFactory factory = new PublishModelFactory(Lists.newArrayList(registry.iterator()));
+ DefaultPublishModel model = factory.createDefaultPublishModel();
+
+ Assert.assertEquals(
+ "{\"test\":{\"avgTaskCount\":0.0,\"avgCompletedTaskCount\":0.0,\"currentThreadsBusy\":0,\"maxThreads\":0,\"poolSize\":0,\"corePoolSize\":0,\"queueSize\":10}}",
+ JsonUtils.writeValueAsString(model.getThreadPools()));
+ }
+}
--
To stop receiving notification emails like this one, please contact
wujimin@apache.org.