diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
index 2efcdd1f87b..36c1739381b 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
@@ -189,7 +189,7 @@ protected void doInvoke() throws Throwable {
invocation.next(resp -> {
sendResponseQuietly(resp);
- invocation.triggerFinishedEvent();
+ invocation.triggerFinishedEvent(resp.getStatusCode(), resp.isSuccessed());
endMetrics();
});
}
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index ea5e8116778..81f25f83db3 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -202,12 +202,12 @@ public void triggerStartProcessingEvent() {
operationMeta.getMicroserviceQualifiedName(), this.invocationType, startProcessingTime - startTime));
}
- public void triggerFinishedEvent() {
+ public void triggerFinishedEvent(int statusCode, boolean success) {
long finishedTime = System.nanoTime();
EventUtils
.triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(),
this.invocationType, finishedTime - startProcessingTime,
- finishedTime - startTime));
+ finishedTime - startTime, statusCode, success));
}
public boolean isSync() {
diff --git a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
index 4ecf2adfcc2..4de6154e0d2 100644
--- a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
+++ b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationFinishedEvent.java
@@ -29,6 +29,10 @@ public class InvocationFinishedEvent implements Event {
private final long totalElapsedNanoTime;
+ private final int statusCode;
+
+ private final boolean success;
+
public String getOperationName() {
return operationName;
}
@@ -45,12 +49,21 @@ public long getTotalElapsedNanoTime() {
return totalElapsedNanoTime;
}
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
public InvocationFinishedEvent(String operationName, InvocationType invocationType,
- long processElapsedNanoTime,
- long totalElapsedNanoTime) {
+ long processElapsedNanoTime, long totalElapsedNanoTime, int statusCode, boolean success) {
this.operationName = operationName;
this.invocationType = invocationType;
this.processElapsedNanoTime = processElapsedNanoTime;
this.totalElapsedNanoTime = totalElapsedNanoTime;
+ this.statusCode = statusCode;
+ this.success = success;
}
}
diff --git a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
index cabc7fb2e6d..2635ac39248 100644
--- a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
+++ b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
@@ -62,6 +62,8 @@ public static Object syncInvoke(Invocation invocation) throws InvocationExceptio
}
public static Response innerSyncInvoke(Invocation invocation) {
+ boolean success = false;
+ int statusCode = 0;
try {
triggerStartedEvent(invocation);
SyncResponseExecutor respExecutor = new SyncResponseExecutor();
@@ -69,14 +71,17 @@ public static Response innerSyncInvoke(Invocation invocation) {
invocation.next(respExecutor::setResponse);
- return respExecutor.waitResponse();
+ Response response = respExecutor.waitResponse();
+ success = response.isSuccessed();
+ statusCode = response.getStatusCode();
+ return response;
} catch (Throwable e) {
String msg =
String.format("invoke failed, %s", invocation.getOperationMeta().getMicroserviceQualifiedName());
LOGGER.debug(msg, e);
return Response.createConsumerFail(e);
} finally {
- invocation.triggerFinishedEvent();
+ invocation.triggerFinishedEvent(statusCode, success);
}
}
@@ -89,12 +94,12 @@ public static void reactiveInvoke(Invocation invocation, AsyncResponse asyncResp
invocation.setResponseExecutor(respExecutor);
invocation.next(ar -> {
- invocation.triggerFinishedEvent();
+ invocation.triggerFinishedEvent(ar.getStatusCode(), ar.isSuccessed());
asyncResp.handle(ar);
});
-
} catch (Throwable e) {
- invocation.triggerFinishedEvent();
+ //if throw exception,we can use 500 for status code ?
+ invocation.triggerFinishedEvent(500, false);
LOGGER.error("invoke failed, {}", invocation.getOperationMeta().getMicroserviceQualifiedName());
asyncResp.consumerFail(e);
}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index 3e931043253..08eec9bebd1 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -29,6 +29,7 @@
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.JsonUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
import org.apache.servicecomb.metrics.common.MetricsPublisher;
import org.apache.servicecomb.metrics.common.RegistryMetric;
import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;
@@ -58,7 +59,7 @@ public static void main(String[] args) throws Exception {
TestMgr.summary();
}
- public static void run() throws Exception {
+ public static void run() {
templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());
restTemplate = RestTemplateBuilder.create();
controller = BeanUtils.getBean("controller");
@@ -125,7 +126,8 @@ public static void run() throws Exception {
.check(true, metric.getInstanceMetric().getSystemMetric().getHeapUsed() != 0);
TestMgr.check(true, metric.getProducerMetrics().size() > 0);
TestMgr.check(true,
- metric.getProducerMetrics().get("springmvc.codeFirst.saySomething").getProducerCall().getTotal() > 0);
+ metric.getProducerMetrics().get("springmvc.codeFirst.saySomething").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue() > 0);
} catch (Exception e) {
TestMgr.check("true", "false");
}
diff --git a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
index e2ac65ac821..f04fdcdbd95 100644
--- a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
+++ b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMetricsFilePublisher.java
@@ -19,6 +19,7 @@
import java.util.Map.Entry;
import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
import org.apache.servicecomb.metrics.common.RegistryMetric;
import org.apache.servicecomb.metrics.core.publish.DataSource;
@@ -54,8 +55,11 @@ public void onCycle() {
String opName = entry.getKey();
sb.append(String
.format(" %-16d%-16d%-16.3f%s\n",
- entry.getValue().getConsumerCall().getTotal(),
- (long) entry.getValue().getConsumerCall().getTps(),
+ entry.getValue().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(),
+ entry.getValue().getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue()
+ .longValue(),
entry.getValue().getConsumerLatency().getAverage(),
opName));
}
@@ -66,8 +70,11 @@ public void onCycle() {
String opName = entry.getKey();
sb.append(
String.format(" %-16d%-16d%-16.3f%-16.3f%-16.3f%s\n",
- entry.getValue().getProducerCall().getTotal(),
- (long) entry.getValue().getProducerCall().getTps(),
+ entry.getValue().getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(),
+ entry.getValue().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue()
+ .longValue(),
entry.getValue().getProducerLatency().getAverage(),
entry.getValue().getLifeTimeInQueue().getAverage(),
entry.getValue().getExecutionTime().getAverage(),
diff --git a/metrics/metrics-common/pom.xml b/metrics/metrics-common/pom.xml
index 21dddbd9949..3ac7fae605a 100644
--- a/metrics/metrics-common/pom.xml
+++ b/metrics/metrics-common/pom.xml
@@ -31,8 +31,8 @@
- com.fasterxml.jackson.core
- jackson-databind
+ org.apache.servicecomb
+ foundation-common
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java
index 5e0d63b5820..4c5c862dc2b 100644
--- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java
+++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java
@@ -17,7 +17,9 @@
package org.apache.servicecomb.metrics.common;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -25,37 +27,66 @@
public class CallMetric {
private final String prefix;
- private final long total;
+ private final List totalValues;
- private final double tps;
+ private final List tpsValues;
- public long getTotal() {
- return total;
+ public String getPrefix() {
+ return prefix;
}
- public double getTps() {
- return tps;
+ public List getTotalValues() {
+ return totalValues;
+ }
+
+ public LongMetricValue getTotalValue(String dimensionKey, String dimensionValue) {
+ for (LongMetricValue value : totalValues) {
+ if (value.containDimension(dimensionKey, dimensionValue)) {
+ return value;
+ }
+ }
+ return new LongMetricValue(dimensionValue, 0L, null);
+ }
+
+ public List getTpsValues() {
+ return tpsValues;
+ }
+
+ public DoubleMetricValue getTpsValue(String dimensionKey, String dimensionValue) {
+ for (DoubleMetricValue value : tpsValues) {
+ if (value.containDimension(dimensionKey, dimensionValue)) {
+ return value;
+ }
+ }
+ return new DoubleMetricValue(dimensionValue, 0.0, null);
}
public CallMetric(String prefix) {
- this(prefix, 0, 0);
+ this(prefix, new ArrayList<>(), new ArrayList<>());
}
- public CallMetric(@JsonProperty("prefix") String prefix, @JsonProperty("total") long total,
- @JsonProperty("tps") double tps) {
+ public CallMetric(@JsonProperty("prefix") String prefix,
+ @JsonProperty("totalValues") List totalValues,
+ @JsonProperty("tpsValues") List tpsValues) {
this.prefix = prefix;
- this.total = total;
- this.tps = tps;
+ this.totalValues = totalValues;
+ this.tpsValues = tpsValues;
}
public CallMetric merge(CallMetric metric) {
- return new CallMetric(this.prefix, this.total + metric.total, this.tps + metric.tps);
+ return new CallMetric(this.prefix,
+ LongMetricValue.merge(metric.getTotalValues(), this.getTotalValues()),
+ DoubleMetricValue.merge(metric.getTpsValues(), this.getTpsValues()));
}
public Map toMap() {
Map metrics = new HashMap<>();
- metrics.put(prefix + ".total", total);
- metrics.put(prefix + ".tps", tps);
+ for (MetricValue totalValue : totalValues) {
+ metrics.put(prefix + ".total." + totalValue.getKey(), totalValue.getValue());
+ }
+ for (MetricValue tpsValue : tpsValues) {
+ metrics.put(prefix + ".tps." + tpsValue.getKey(), tpsValue.getValue());
+ }
return metrics;
}
}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java
new file mode 100644
index 00000000000..e6ace957c9f
--- /dev/null
+++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java
@@ -0,0 +1,56 @@
+/*
+ * 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.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class DoubleMetricValue extends MetricValue {
+ public DoubleMetricValue(Double value, Map dimensions) {
+ super(value, dimensions);
+ }
+
+ public DoubleMetricValue(@JsonProperty("key") String key,
+ @JsonProperty("value") Double value,
+ @JsonProperty("dimensions") Map dimensions) {
+ super(key, value, dimensions);
+ }
+
+ private DoubleMetricValue merge(DoubleMetricValue value) {
+ return new DoubleMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions());
+ }
+
+ public static List merge(List source, List target) {
+ Map finalValues = new HashMap<>();
+ for (DoubleMetricValue t : target) {
+ finalValues.put(t.getKey(), t);
+ }
+ for (DoubleMetricValue s : source) {
+ if (finalValues.containsKey(s.getKey())) {
+ finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s));
+ } else {
+ finalValues.put(s.getKey(), s);
+ }
+ }
+ return new ArrayList<>(finalValues.values());
+ }
+}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java
new file mode 100644
index 00000000000..ff271349844
--- /dev/null
+++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java
@@ -0,0 +1,56 @@
+/*
+ * 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.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class LongMetricValue extends MetricValue {
+ public LongMetricValue(Long value, Map dimensions) {
+ super(value, dimensions);
+ }
+
+ public LongMetricValue(@JsonProperty("key") String key,
+ @JsonProperty("value") Long value,
+ @JsonProperty("dimensions") Map dimensions) {
+ super(key, value, dimensions);
+ }
+
+ private LongMetricValue merge(LongMetricValue value) {
+ return new LongMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions());
+ }
+
+ public static List merge(List source, List target) {
+ Map finalValues = new HashMap<>();
+ for (LongMetricValue t : target) {
+ finalValues.put(t.getKey(), t);
+ }
+ for (LongMetricValue s : source) {
+ if (finalValues.containsKey(s.getKey())) {
+ finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s));
+ } else {
+ finalValues.put(s.getKey(), s);
+ }
+ }
+ return new ArrayList<>(finalValues.values());
+ }
+}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java
new file mode 100644
index 00000000000..0a8d3642927
--- /dev/null
+++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java
@@ -0,0 +1,70 @@
+/*
+ * 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.common;
+
+import java.util.Arrays;
+import java.util.Map;
+
+public class MetricValue {
+ private final String key;
+
+ private final T value;
+
+ private final Map dimensions;
+
+ public String getKey() {
+ return key;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public Map getDimensions() {
+ return dimensions;
+ }
+
+ public MetricValue(T value, Map dimensions) {
+ String finalKey = "{}";
+ if (dimensions != null && dimensions.size() != 0) {
+ String[] keys = dimensions.keySet().toArray(new String[0]);
+ Arrays.sort(keys);
+ StringBuilder builder = new StringBuilder("{");
+ for (String key : keys) {
+ builder.append(String.format("%s=%s,", key, dimensions.get(key)));
+ }
+ builder.deleteCharAt(builder.length() - 1);
+ builder.append("}");
+ finalKey = builder.toString();
+ }
+ this.key = finalKey;
+ this.value = value;
+ this.dimensions = dimensions;
+ }
+
+ public MetricValue(String key, T value, Map dimensions) {
+ this.key = key;
+ this.value = value;
+ this.dimensions = dimensions;
+ }
+
+ public boolean containDimension(String dimensionKey, String dimensionValue) {
+ return this.getDimensions().containsKey(dimensionKey) &&
+ dimensionValue.equals(this.getDimensions().get(dimensionKey));
+ }
+}
diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java
new file mode 100644
index 00000000000..904cc25b8ed
--- /dev/null
+++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java
@@ -0,0 +1,46 @@
+/*
+ * 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.common;
+
+public class MetricsDimension {
+ public static final String DIMENSION_STATUS = "Status";
+
+ public static final String DIMENSION_STATUS_ALL = "all";
+
+ public static final String DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS = "success";
+
+ public static final String DIMENSION_STATUS_SUCCESS_FAILED_FAILED = "failed";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_1XX = "1xx";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_2XX = "2xx";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_3XX = "3xx";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_4XX = "4xx";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_5XX = "5xx";
+
+ public static final String DIMENSION_STATUS_CODE_GROUP_OTHER = "xxx";
+
+ public static final String DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED = "success_failed";
+
+ public static final String DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP = "code_group";
+
+ public static final String DIMENSION_STATUS_OUTPUT_LEVEL_CODE = "code";
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
index b903f158fca..cbf6455d857 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java
@@ -19,4 +19,6 @@
public class MetricsConfig {
public static final String METRICS_POLLING_TIME = "servicecomb.metrics.window_time";
+
+ public static final String METRICS_DIMENSION_STATUS_OUTPUT_LEVEL = "servicecomb.metrics.dimension.status.output_level";
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
index 42aa024b5d1..6dc6df4f442 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java
@@ -19,18 +19,31 @@
import org.apache.servicecomb.foundation.common.event.EventListener;
import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.metrics.core.MetricsConfig;
+import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import com.netflix.config.DynamicPropertyFactory;
+
@Component
public class DefaultEventListenerManager implements EventListenerManager {
@Autowired
- public DefaultEventListenerManager(RegistryMonitor registryMonitor) {
+ public DefaultEventListenerManager(RegistryMonitor registryMonitor, StatusConvertorFactory convertorFactory) {
+ this(registryMonitor, convertorFactory, DynamicPropertyFactory
+ .getInstance().getStringProperty(MetricsConfig.METRICS_DIMENSION_STATUS_OUTPUT_LEVEL,
+ MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED).get());
+ }
+
+ public DefaultEventListenerManager(RegistryMonitor registryMonitor, StatusConvertorFactory convertorFactory,
+ String outputLevel) {
this.registerEventListener(new InvocationStartedEventListener(registryMonitor));
this.registerEventListener(new InvocationStartProcessingEventListener(registryMonitor));
- this.registerEventListener(new InvocationFinishedEventListener(registryMonitor));
+ this.registerEventListener(
+ new InvocationFinishedEventListener(registryMonitor, convertorFactory.getConvertor(outputLevel)));
}
@Override
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
index ff356f998dd..5b886b6f099 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationFinishedEventListener.java
@@ -20,17 +20,21 @@
import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
import org.apache.servicecomb.foundation.common.event.Event;
import org.apache.servicecomb.foundation.common.event.EventListener;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertor;
import org.apache.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
import org.apache.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
import org.apache.servicecomb.swagger.invocation.InvocationType;
public class InvocationFinishedEventListener implements EventListener {
-
private final RegistryMonitor registryMonitor;
- public InvocationFinishedEventListener(RegistryMonitor registryMonitor) {
+ private final StatusConvertor convertor;
+
+ public InvocationFinishedEventListener(RegistryMonitor registryMonitor, StatusConvertor convertor) {
this.registryMonitor = registryMonitor;
+ this.convertor = convertor;
}
@Override
@@ -41,13 +45,16 @@ public Class extends Event> getConcernedEvent() {
@Override
public void process(Event data) {
InvocationFinishedEvent event = (InvocationFinishedEvent) data;
+ String statusDimensionValue = convertor.convert(event.isSuccess(), event.getStatusCode());
if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
monitor.getExecutionTime().update(event.getProcessElapsedNanoTime());
monitor.getProducerLatency().update(event.getTotalElapsedNanoTime());
+ monitor.getProducerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue);
} else {
ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime());
+ monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue);
}
}
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
index 166f5ce3b4c..c13d17327c4 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartedEventListener.java
@@ -20,6 +20,7 @@
import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
import org.apache.servicecomb.foundation.common.event.Event;
import org.apache.servicecomb.foundation.common.event.EventListener;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
import org.apache.servicecomb.metrics.core.monitor.ConsumerInvocationMonitor;
import org.apache.servicecomb.metrics.core.monitor.ProducerInvocationMonitor;
import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
@@ -44,10 +45,10 @@ public void process(Event data) {
if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
monitor.getWaitInQueue().increment();
- monitor.getProducerCall().increment();
+ monitor.getProducerCall().increment(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL);
} else {
ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName());
- monitor.getConsumerCall().increment();
+ monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL);
}
}
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java
new file mode 100644
index 00000000000..92b99d0bca2
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java
@@ -0,0 +1,45 @@
+/*
+ * 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.event.dimension;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status.Family;
+
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+
+public class CodeGroupStatusConvertor implements StatusConvertor {
+
+ private final Map families;
+
+ public CodeGroupStatusConvertor() {
+ this.families = new HashMap<>();
+ this.families.put(Family.INFORMATIONAL, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_1XX);
+ this.families.put(Family.SUCCESSFUL, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX);
+ this.families.put(Family.REDIRECTION, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_3XX);
+ this.families.put(Family.CLIENT_ERROR, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_4XX);
+ this.families.put(Family.SERVER_ERROR, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_5XX);
+ this.families.put(Family.OTHER, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_OTHER);
+ }
+
+ @Override
+ public String convert(boolean success, int statusCode) {
+ return families.get(Family.familyOf(statusCode));
+ }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java
new file mode 100644
index 00000000000..b01f5da674b
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.dimension;
+
+public class CodeStatusConvertor implements StatusConvertor {
+ @Override
+ public String convert(boolean success, int statusCode) {
+ return String.valueOf(statusCode);
+ }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java
new file mode 100644
index 00000000000..17023b66737
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java
@@ -0,0 +1,22 @@
+/*
+ * 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.event.dimension;
+
+public interface StatusConvertor {
+ String convert(boolean success, int statusCode);
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java
new file mode 100644
index 00000000000..369cda4eaf6
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.event.dimension;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.metrics.core.MetricsConfig;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StatusConvertorFactory {
+
+ private final Map> suppliers;
+
+ public StatusConvertorFactory() {
+ this.suppliers = new HashMap<>();
+ this.suppliers.put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE, CodeStatusConvertor::new);
+ this.suppliers.put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP, CodeGroupStatusConvertor::new);
+ this.suppliers
+ .put(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED, SuccessFailedStatusConvertor::new);
+ }
+
+ public StatusConvertor getConvertor(String outputLevel) {
+ if (suppliers.containsKey(outputLevel)) {
+ return suppliers.get(outputLevel).get();
+ }
+ LoggerFactory.getLogger(StatusConvertorFactory.class).error("unknown config value of " +
+ MetricsConfig.METRICS_DIMENSION_STATUS_OUTPUT_LEVEL + " : " + outputLevel
+ + ", use default level : " +
+ MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED + " replace it");
+ //return default
+ return suppliers.get(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED).get();
+ }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java
new file mode 100644
index 00000000000..c2cf9984be1
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java
@@ -0,0 +1,28 @@
+/*
+ * 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.event.dimension;
+
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+
+public class SuccessFailedStatusConvertor implements StatusConvertor {
+ @Override
+ public String convert(boolean success, int statusCode) {
+ return success ? MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS
+ : MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED;
+ }
+}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
index 1e682013f8a..2e61440c208 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java
@@ -17,7 +17,16 @@
package org.apache.servicecomb.metrics.core.monitor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
import org.apache.servicecomb.metrics.common.CallMetric;
+import org.apache.servicecomb.metrics.common.DoubleMetricValue;
+import org.apache.servicecomb.metrics.common.LongMetricValue;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.metrics.core.utils.MonitorUtils;
import com.netflix.servo.monitor.BasicCounter;
import com.netflix.servo.monitor.MonitorConfig;
@@ -26,30 +35,61 @@
public class CallMonitor {
private final String prefix;
- private final BasicCounter total;
-
- private final StepCounter tps;
+ private final Map> dimensionCounters;
public CallMonitor(String prefix) {
this.prefix = prefix;
- this.total = new BasicCounter(MonitorConfig.builder(prefix + ".total").build());
- this.tps = new StepCounter(MonitorConfig.builder(prefix + ".tps").build());
+ this.dimensionCounters = new ConcurrentHashMapEx<>();
+ this.dimensionCounters.put(MetricsDimension.DIMENSION_STATUS, new ConcurrentHashMapEx<>());
}
- public void increment() {
- total.increment();
- tps.increment();
+ public void increment(String dimensionKey, String... dimensionValues) {
+ for (String dimensionValue : dimensionValues) {
+ DimensionCounter counter = dimensionCounters.get(dimensionKey)
+ .computeIfAbsent(dimensionValue, d -> new DimensionCounter(
+ new BasicCounter(MonitorConfig.builder(prefix + ".total").withTag(dimensionKey, dimensionValue).build()),
+ new StepCounter(MonitorConfig.builder(prefix + ".tps").withTag(dimensionKey, dimensionValue).build())));
+ counter.increment();
+ }
}
public CallMetric toMetric(int windowTimeIndex) {
- return new CallMetric(this.prefix, total.getValue(windowTimeIndex).longValue(),
- this.adjustValue(tps.getValue(windowTimeIndex).doubleValue()));
+ List totalValues = new ArrayList<>();
+ List tpsValues = new ArrayList<>();
+ for (Map dimensionCounter : dimensionCounters.values()) {
+ for (DimensionCounter counter : dimensionCounter.values()) {
+ totalValues.add(new LongMetricValue(counter.getTotal().getValue(windowTimeIndex).longValue(),
+ MonitorUtils.convertTags(counter.getTotal())));
+ tpsValues.add(
+ new DoubleMetricValue(MonitorUtils.adjustValue(counter.getTps().getValue(windowTimeIndex).doubleValue()),
+ MonitorUtils.convertTags(counter.getTps())));
+ }
+ }
+
+ return new CallMetric(this.prefix, totalValues, tpsValues);
}
- //for time-related monitor type, if stop poll value over one window time,
- //the value may return -1 because servo can't known precise value of previous step
- //so must change to return 0
- public double adjustValue(double value) {
- return value < 0 ? 0 : value;
+ class DimensionCounter {
+ private final BasicCounter total;
+
+ private final StepCounter tps;
+
+ public BasicCounter getTotal() {
+ return total;
+ }
+
+ public StepCounter getTps() {
+ return tps;
+ }
+
+ public DimensionCounter(BasicCounter total, StepCounter tps) {
+ this.total = total;
+ this.tps = tps;
+ }
+
+ public void increment() {
+ total.increment();
+ tps.increment();
+ }
}
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
index 12caaaa461c..5977521327a 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/DefaultSystemMonitor.java
@@ -98,8 +98,7 @@ public long getNonHeapUsed() {
@Override
public SystemMetric toMetric() {
- return new SystemMetric(getCpuLoad(),
- getCpuRunningThreads(), getHeapInit(), getHeapMax(), getHeapCommit(), getHeapUsed(),
- getNonHeapInit(), getNonHeapMax(), getNonHeapCommit(), getNonHeapUsed());
+ return new SystemMetric(getCpuLoad(), getCpuRunningThreads(), getHeapInit(), getHeapMax(), getHeapCommit(),
+ getHeapUsed(), getNonHeapInit(), getNonHeapMax(), getNonHeapCommit(), getNonHeapUsed());
}
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
index 7d4fffe4687..a88a604557f 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/TimerMonitor.java
@@ -17,9 +17,8 @@
package org.apache.servicecomb.metrics.core.monitor;
-import java.util.concurrent.TimeUnit;
-
import org.apache.servicecomb.metrics.common.TimerMetric;
+import org.apache.servicecomb.metrics.core.utils.MonitorUtils;
import com.netflix.servo.monitor.MaxGauge;
import com.netflix.servo.monitor.MinGauge;
@@ -59,22 +58,9 @@ public TimerMonitor(String prefix) {
public TimerMetric toMetric(int windowTimeIndex) {
return new TimerMetric(this.prefix,
- this.convertNanosecondToMillisecond(this.adjustValue(total.getCount(windowTimeIndex))),
- this.adjustValue(count.getCount(windowTimeIndex)),
- this.convertNanosecondToMillisecond(this.adjustValue(min.getValue(windowTimeIndex))),
- this.convertNanosecondToMillisecond(this.adjustValue(max.getValue(windowTimeIndex))));
- }
-
- //for time-related monitor type, if stop poll value over one window time,
- //the value may return -1 because servo can't known precise value of previous step
- //so must change to return 0
- public long adjustValue(long value) {
- return value < 0 ? 0 : value;
- }
-
- //Counting use System.nano get more precise time
- //so we need change unit to millisecond when ouput
- public long convertNanosecondToMillisecond(long nanoValue) {
- return TimeUnit.NANOSECONDS.toMillis(nanoValue);
+ MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(total.getCount(windowTimeIndex))),
+ MonitorUtils.adjustValue(count.getCount(windowTimeIndex)),
+ MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(min.getValue(windowTimeIndex))),
+ MonitorUtils.convertNanosecondToMillisecond(MonitorUtils.adjustValue(max.getValue(windowTimeIndex))));
}
}
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java
new file mode 100644
index 00000000000..f2a816985e0
--- /dev/null
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/utils/MonitorUtils.java
@@ -0,0 +1,70 @@
+/*
+ * 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.utils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.netflix.servo.monitor.Monitor;
+import com.netflix.servo.tag.Tag;
+import com.netflix.servo.tag.TagList;
+
+public class MonitorUtils {
+
+ //for time-related monitor type, if stop poll value over one window time,
+ //the value may return -1 or NaN because servo can't known precise value of previous step
+ //so must change to return 0
+ public static double adjustValue(double value) {
+ return Double.isNaN(value) || value < 0 ? 0 : value;
+ }
+
+ //for time-related monitor type, if stop poll value over one window time,
+ //the value may return -1 because servo can't known precise value of previous step
+ //so must change to return 0
+ public static long adjustValue(long value) {
+ return value < 0 ? 0 : value;
+ }
+
+ public static boolean containsTagValue(Monitor monitor, String tagKey, String tagValue) {
+ TagList tags = monitor.getConfig().getTags();
+ return tags.containsKey(tagKey) && tagValue.equals(tags.getTag(tagKey).getValue());
+ }
+
+ public static Map convertTags(Monitor monitor) {
+ TagList tags = monitor.getConfig().getTags();
+ if (tags.size() != 0) {
+ Map tagMap = new HashMap<>();
+ for (Tag tag : tags) {
+ //we don't need servo internal type tag for metrics
+ if (!"type".equals(tag.getKey())) {
+ tagMap.put(tag.getKey(), tag.getValue());
+ }
+ }
+ return tagMap;
+ }
+ return Collections.emptyMap();
+ }
+
+ //Counting use System.nano get more precise time
+ //so we need change unit to millisecond when ouput
+ public static long convertNanosecondToMillisecond(long nanoValue) {
+ return TimeUnit.NANOSECONDS.toMillis(nanoValue);
+ }
+}
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
index 6edff5e07cf..85cf4634303 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestEventAndRunner.java
@@ -33,8 +33,10 @@
import org.apache.servicecomb.core.metrics.InvocationStartProcessingEvent;
import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
import org.apache.servicecomb.metrics.common.RegistryMetric;
import org.apache.servicecomb.metrics.core.event.DefaultEventListenerManager;
+import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor;
import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
import org.apache.servicecomb.metrics.core.publish.DefaultDataSource;
@@ -73,16 +75,18 @@ public void test() throws InterruptedException {
Assert.assertEquals(intervals.size(), 3);
Assert.assertThat(intervals, containsInAnyOrder(Arrays.asList(1000L, 2000L, 3000L).toArray()));
- new DefaultEventListenerManager(monitor);
+ new DefaultEventListenerManager(monitor, new StatusConvertorFactory(),
+ MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED);
- //fun1 is a PRODUCER invocation call twice and all is completed
+ //fun1 is a PRODUCER invocation call 2 time and all is completed
+ //two time success
EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
EventUtils.triggerEvent(
new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
TimeUnit.MILLISECONDS.toNanos(100)));
EventUtils
.triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
- TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300)));
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
EventUtils.triggerEvent(
@@ -90,7 +94,9 @@ public void test() throws InterruptedException {
TimeUnit.MILLISECONDS.toNanos(300)));
EventUtils
.triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
- TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700)));
+ TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500, false));
+
+ //==========================================================================
//fun3 is a PRODUCER invocation call uncompleted
EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime()));
@@ -98,6 +104,13 @@ public void test() throws InterruptedException {
new InvocationStartProcessingEvent("fun3", InvocationType.PRODUCER,
TimeUnit.MILLISECONDS.toNanos(500)));
+ //==========================================================================
+
+ //fun4 is a PRODUCER call only started and no processing start and finished
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
+
+ //==========================================================================
+
//fun2 is a CONSUMER invocation call once and completed
EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
EventUtils.triggerEvent(
@@ -105,10 +118,9 @@ public void test() throws InterruptedException {
TimeUnit.MILLISECONDS.toNanos(100)));
EventUtils
.triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER,
- TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300)));
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
- //fun4 is a invocation call only started and no processing start and finished
- EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime()));
+ //==========================================================================
//sim lease one window time
Thread.sleep(1000);
@@ -116,194 +128,196 @@ public void test() throws InterruptedException {
RegistryMetric model = dataSource.getRegistryMetric(1000);
//check InstanceMetric
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getWaitInQueue(), 1);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getCount(), 3);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getTotal(),
- 900,
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getWaitInQueue());
+ Assert.assertEquals(3, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getCount());
+ Assert.assertEquals(900, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getTotal(), 0);
+ Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getAverage(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getAverage(),
- 300,
+ Assert.assertEquals(500, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMax(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMax(),
- 500,
- 0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMin(),
- 100,
+ Assert.assertEquals(100, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMin(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getExecutionTime().getCount(), 2);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getExecutionTime().getTotal(),
- 600,
+ Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getExecutionTime().getCount());
+ Assert.assertEquals(600, model.getInstanceMetric().getProducerMetric().getExecutionTime().getTotal(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getExecutionTime().getAverage(),
- 300,
+ Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getExecutionTime().getAverage(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getExecutionTime().getMax(),
- 400,
+ Assert.assertEquals(400, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMax(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getExecutionTime().getMin(),
- 200,
+ Assert.assertEquals(200, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMin(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getCount(), 2);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getTotal(),
- 1000,
+ Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getProducerLatency().getCount());
+ Assert.assertEquals(1000, model.getInstanceMetric().getProducerMetric().getProducerLatency().getTotal(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getAverage(),
- 500,
+ Assert.assertEquals(500, model.getInstanceMetric().getProducerMetric().getProducerLatency().getAverage(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getMax(),
- 700,
+ Assert.assertEquals(700, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMax(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerLatency().getMin(),
- 300,
+ Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMin(),
0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTps(), 4, 0);
- Assert.assertEquals(model.getInstanceMetric().getProducerMetric().getProducerCall().getTotal(), 4);
+ Assert.assertEquals(4, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount(), 1);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(),
- 300,
- 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getAverage(),
- 300,
- 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMax(),
- 300,
- 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMin(),
- 300,
- 0);
+ Assert.assertEquals(4, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerCall().getTps(), 1, 0);
- Assert.assertEquals(model.getInstanceMetric().getConsumerMetric().getConsumerCall().getTotal(), 1);
-
- //check ProducerMetrics
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getWaitInQueue(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getCount(), 2);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getTotal(),
- 400,
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount());
+ Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(),
0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getAverage(),
- 200,
+ Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getAverage(),
0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMax(),
- 300,
+ Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMax(),
0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMin(),
- 100,
+ Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMin(),
0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getExecutionTime().getCount(), 2);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getExecutionTime().getTotal(),
- 600,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getExecutionTime().getAverage(),
- 300,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getExecutionTime().getMax(),
- 400,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getExecutionTime().getMin(),
- 200,
- 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerLatency().getCount(), 2);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerLatency().getTotal(),
- 1000,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerLatency().getAverage(),
- 500,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerLatency().getMax(),
- 700,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerLatency().getMin(),
- 300,
- 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerCall().getTps(), 2, 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun1").getProducerCall().getTotal(), 2);
+ //check ProducerMetrics
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun1").getWaitInQueue());
+ Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getCount());
+ Assert.assertEquals(400, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getTotal(), 0);
+ Assert.assertEquals(200, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getAverage(), 0);
+ Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMax(), 0);
+ Assert.assertEquals(100, model.getProducerMetrics().get("fun1").getLifeTimeInQueue().getMin(), 0);
+
+ Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getExecutionTime().getCount());
+ Assert.assertEquals(600, model.getProducerMetrics().get("fun1").getExecutionTime().getTotal(), 0);
+ Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getExecutionTime().getAverage(), 0);
+ Assert.assertEquals(400, model.getProducerMetrics().get("fun1").getExecutionTime().getMax(), 0);
+ Assert.assertEquals(200, model.getProducerMetrics().get("fun1").getExecutionTime().getMin(), 0);
+
+ Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerLatency().getCount());
+ Assert.assertEquals(1000, model.getProducerMetrics().get("fun1").getProducerLatency().getTotal(), 0);
+ Assert.assertEquals(500, model.getProducerMetrics().get("fun1").getProducerLatency().getAverage(), 0);
+ Assert.assertEquals(700, model.getProducerMetrics().get("fun1").getProducerLatency().getMax(), 0);
+ Assert.assertEquals(300, model.getProducerMetrics().get("fun1").getProducerLatency().getMin(), 0);
+
+ Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
+
+ Assert.assertEquals(2, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun1").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
//fun3
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getWaitInQueue(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getCount(), 1);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getTotal(),
- 500,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getAverage(),
- 500,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMax(),
- 500,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMin(),
- 500,
- 0);
-
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getExecutionTime().getCount(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getExecutionTime().getTotal(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getExecutionTime().getAverage(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getExecutionTime().getMax(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getExecutionTime().getMin(),
- 0,
- 0);
-
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerLatency().getCount(), 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerLatency().getTotal(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerLatency().getAverage(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerLatency().getMax(),
- 0,
- 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerLatency().getMin(),
- 0,
- 0);
-
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerCall().getTps(), 1, 0);
- Assert.assertEquals(model.getProducerMetrics().get("fun3").getProducerCall().getTotal(), 1);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getWaitInQueue());
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getCount());
+ Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getTotal(), 0);
+ Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getAverage(), 0);
+ Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMax(), 0);
+ Assert.assertEquals(500, model.getProducerMetrics().get("fun3").getLifeTimeInQueue().getMin(), 0);
+
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getCount());
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getTotal(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getAverage(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getMax(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getExecutionTime().getMin(), 0);
+
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getCount());
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getTotal(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getAverage(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getMax(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerLatency().getMin(), 0);
+
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
+
+ Assert.assertEquals(1, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getProducerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
//check ConsumerMetrics
//no need
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getCount(), 1);
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getTotal(),
- 300,
- 0);
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getAverage(),
- 300,
- 0);
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getMax(),
- 300,
- 0);
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerLatency().getMin(),
- 300,
- 0);
-
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerCall().getTps(), 1, 0);
- Assert.assertEquals(model.getConsumerMetrics().get("fun2").getConsumerCall().getTotal(), 1);
+ Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerLatency().getCount());
+ Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getTotal(), 0);
+ Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getAverage(), 0);
+ Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getMax(), 0);
+ Assert.assertEquals(300, model.getConsumerMetrics().get("fun2").getConsumerLatency().getMin(), 0);
+
+ Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
+
+ Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_SUCCESS)
+ .getValue(), 0);
+ Assert.assertEquals(0, model.getConsumerMetrics().get("fun2").getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED)
+ .getValue(), 0);
Map metrics = model.toMap();
- Assert.assertEquals(96, metrics.size());
-
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getCpuLoad(), 1.0, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getCpuRunningThreads(), 2, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getHeapCommit(), 100, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getHeapInit(), 200, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getHeapMax(), 300, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getHeapUsed(), 400, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getNonHeapCommit(), 500, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getNonHeapInit(), 600, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getNonHeapMax(), 700, 0);
- Assert.assertEquals(model.getInstanceMetric().getSystemMetric().getNonHeapUsed(), 800, 0);
+ Assert.assertEquals(108, metrics.size());
+
+ Assert.assertEquals(1.0, model.getInstanceMetric().getSystemMetric().getCpuLoad(), 0);
+ Assert.assertEquals(2, model.getInstanceMetric().getSystemMetric().getCpuRunningThreads(), 0);
+ Assert.assertEquals(100, model.getInstanceMetric().getSystemMetric().getHeapCommit(), 0);
+ Assert.assertEquals(200, model.getInstanceMetric().getSystemMetric().getHeapInit(), 0);
+ Assert.assertEquals(300, model.getInstanceMetric().getSystemMetric().getHeapMax(), 0);
+ Assert.assertEquals(400, model.getInstanceMetric().getSystemMetric().getHeapUsed(), 0);
+ Assert.assertEquals(500, model.getInstanceMetric().getSystemMetric().getNonHeapCommit(), 0);
+ Assert.assertEquals(600, model.getInstanceMetric().getSystemMetric().getNonHeapInit(), 0);
+ Assert.assertEquals(700, model.getInstanceMetric().getSystemMetric().getNonHeapMax(), 0);
+ Assert.assertEquals(800, model.getInstanceMetric().getSystemMetric().getNonHeapUsed(), 0);
}
-}
+}
\ No newline at end of file
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java
index ef44bc7ea13..55bd7058b19 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java
@@ -19,7 +19,6 @@
import static org.hamcrest.Matchers.containsInAnyOrder;
-import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -36,7 +35,7 @@
public class TestPublisher {
@Test
- public void test() throws IOException {
+ public void test() {
SystemMonitor systemMonitor = new DefaultSystemMonitor();
RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor);
DefaultDataSource dataSource = new DefaultDataSource(registryMonitor, "1000,2000,3000,3000,2000,1000");
@@ -44,11 +43,11 @@ public void test() throws IOException {
RegistryMetric registryMetric = publisher.metrics();
Map metricsMap = registryMetric.toMap();
- Assert.assertEquals(35, metricsMap.size());
+ Assert.assertEquals(31, metricsMap.size());
registryMetric = publisher.metricsWithWindowTime(1000);
metricsMap = registryMetric.toMap();
- Assert.assertEquals(35, metricsMap.size());
+ Assert.assertEquals(31, metricsMap.size());
List appliedWindowTime = publisher.getAppliedWindowTime();
Assert.assertEquals(appliedWindowTime.size(), 3);
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java
new file mode 100644
index 00000000000..0a113fb9a04
--- /dev/null
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java
@@ -0,0 +1,158 @@
+/*
+ * 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;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.servicecomb.core.metrics.InvocationFinishedEvent;
+import org.apache.servicecomb.core.metrics.InvocationStartProcessingEvent;
+import org.apache.servicecomb.core.metrics.InvocationStartedEvent;
+import org.apache.servicecomb.foundation.common.utils.EventUtils;
+import org.apache.servicecomb.metrics.common.MetricsDimension;
+import org.apache.servicecomb.metrics.common.RegistryMetric;
+import org.apache.servicecomb.metrics.core.event.DefaultEventListenerManager;
+import org.apache.servicecomb.metrics.core.event.dimension.StatusConvertorFactory;
+import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor;
+import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor;
+import org.apache.servicecomb.metrics.core.publish.DefaultDataSource;
+import org.apache.servicecomb.swagger.invocation.InvocationType;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestStatusDimension {
+
+ @Test
+ public void testCodeGroupDimension() throws InterruptedException {
+ RegistryMetric model = prepare(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP);
+
+ Assert.assertEquals(5, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_3XX)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_4XX)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_5XX)
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_OTHER)
+ .getValue(), 0);
+
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_CODE_GROUP_2XX)
+ .getValue(), 0);
+ }
+
+ @Test
+ public void testCodeDimension() throws InterruptedException {
+ RegistryMetric model = prepare(MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_CODE);
+
+ Assert.assertEquals(5, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, "222")
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, "333")
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, "444")
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, "555")
+ .getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getProducerMetric().getProducerCall()
+ .getTpsValue(MetricsDimension.DIMENSION_STATUS, "666")
+ .getValue(), 0);
+
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue(), 0);
+ Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerCall()
+ .getTotalValue(MetricsDimension.DIMENSION_STATUS, "200")
+ .getValue(), 0);
+ }
+
+ private RegistryMetric prepare(String outputLevel) throws InterruptedException {
+ DefaultSystemMonitor systemMonitor = new DefaultSystemMonitor();
+ RegistryMonitor monitor = new RegistryMonitor(systemMonitor);
+ DefaultDataSource dataSource = new DefaultDataSource(monitor, "1000,2000,3000");
+
+ new DefaultEventListenerManager(monitor, new StatusConvertorFactory(), outputLevel);
+
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 222, true));
+
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 333, false));
+
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 444, false));
+
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 555, false));
+
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 666, false));
+
+ //fun2 is a CONSUMER invocation call once and completed
+ EventUtils.triggerEvent(new InvocationStartedEvent("fun2", InvocationType.CONSUMER, System.nanoTime()));
+ EventUtils.triggerEvent(
+ new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER,
+ TimeUnit.MILLISECONDS.toNanos(100)));
+ EventUtils
+ .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER,
+ TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true));
+
+ //sim lease one window time
+ Thread.sleep(1000);
+
+ return dataSource.getRegistryMetric(1000);
+ }
+}
diff --git a/metrics/metrics-extension/pom.xml b/metrics/metrics-extension/pom.xml
index 1d642308d4e..ecd2f6e3a48 100644
--- a/metrics/metrics-extension/pom.xml
+++ b/metrics/metrics-extension/pom.xml
@@ -27,6 +27,7 @@
4.0.0
metrics-extension
+ Java Chassis::Metrics::Extension
pom
\ No newline at end of file
diff --git a/metrics/metrics-integration/metrics-prometheus/pom.xml b/metrics/metrics-integration/metrics-prometheus/pom.xml
index 684749a718c..0ff0beaaa94 100644
--- a/metrics/metrics-integration/metrics-prometheus/pom.xml
+++ b/metrics/metrics-integration/metrics-prometheus/pom.xml
@@ -27,6 +27,7 @@
4.0.0
metrics-prometheus
+ Java Chassis::Metrics::Prometheus Integration
diff --git a/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
index a17310b8205..932863ea152 100644
--- a/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
+++ b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsCollector.java
@@ -20,10 +20,12 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.stream.Collectors;
+import org.apache.servicecomb.metrics.common.CallMetric;
import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
+import org.apache.servicecomb.metrics.common.DoubleMetricValue;
+import org.apache.servicecomb.metrics.common.LongMetricValue;
import org.apache.servicecomb.metrics.common.ProducerInvocationMetric;
import org.apache.servicecomb.metrics.common.RegistryMetric;
import org.apache.servicecomb.metrics.core.publish.DataSource;
@@ -56,24 +58,79 @@ public List describe() {
private List load() {
RegistryMetric registryMetric = dataSource.getRegistryMetric();
List familySamples = new ArrayList<>();
- familySamples.add(getFamilySamples("Instance Level", registryMetric.getInstanceMetric().toMap()));
- for (Entry consumerMetric : registryMetric.getConsumerMetrics().entrySet()) {
+
+ List instanceSamples = new ArrayList<>();
+ instanceSamples.addAll(convertMetricValues(registryMetric.getInstanceMetric().getSystemMetric().toMap()));
+ instanceSamples.addAll(convertConsumerMetric(registryMetric.getInstanceMetric().getConsumerMetric()));
+ instanceSamples.addAll(convertCallMetric(registryMetric.getInstanceMetric().getConsumerMetric().getConsumerCall()));
+ instanceSamples.addAll(convertProducerMetric(registryMetric.getInstanceMetric().getProducerMetric()));
+ instanceSamples.addAll(convertCallMetric(registryMetric.getInstanceMetric().getProducerMetric().getProducerCall()));
+ familySamples
+ .add(new MetricFamilySamples("Instance Level", Type.UNTYPED, "Instance Level Metrics", instanceSamples));
+
+ if (registryMetric.getConsumerMetrics().size() != 0) {
+ List consumerSamples = new ArrayList<>();
+ for (ConsumerInvocationMetric metric : registryMetric.getConsumerMetrics().values()) {
+ consumerSamples.addAll(convertConsumerMetric(metric));
+ consumerSamples.addAll(convertCallMetric(metric.getConsumerCall()));
+ }
familySamples
- .add(getFamilySamples(consumerMetric.getKey() + " Consumer Side", consumerMetric.getValue().toMap()));
+ .add(new MetricFamilySamples("Consumer Side", Type.UNTYPED, "Consumer Side Metrics", consumerSamples));
}
- for (Entry producerMetric : registryMetric.getProducerMetrics().entrySet()) {
+
+ if (registryMetric.getProducerMetrics().size() != 0) {
+ List producerSamples = new ArrayList<>();
+ for (ProducerInvocationMetric metric : registryMetric.getProducerMetrics().values()) {
+ producerSamples.addAll(convertProducerMetric(metric));
+ producerSamples.addAll(convertCallMetric(metric.getProducerCall()));
+ }
familySamples
- .add(getFamilySamples(producerMetric.getKey() + " Producer Side", producerMetric.getValue().toMap()));
+ .add(new MetricFamilySamples("Producer Side", Type.UNTYPED, "Producer Side Metrics", producerSamples));
}
+
return familySamples;
}
- private MetricFamilySamples getFamilySamples(String name, Map metrics) {
- List samples = metrics.entrySet()
- .stream()
- .map((entry) -> new Sample(entry.getKey().replace(".", "_"),
- new ArrayList<>(), new ArrayList<>(), entry.getValue().doubleValue()))
- .collect(Collectors.toList());
- return new MetricFamilySamples(name, Type.UNTYPED, name + " Metrics", samples);
+ private List convertConsumerMetric(ConsumerInvocationMetric metric) {
+ return convertMetricValues(metric.getConsumerLatency().toMap());
+ }
+
+ private List convertProducerMetric(ProducerInvocationMetric metric) {
+ List samples = new ArrayList<>();
+ samples.addAll(convertMetricValues(metric.getExecutionTime().toMap()));
+ samples.addAll(convertMetricValues(metric.getLifeTimeInQueue().toMap()));
+ samples.addAll(convertMetricValues(metric.getProducerLatency().toMap()));
+ samples.add(
+ new Sample(formatMetricName(metric.getPrefix() + ".waitInQueue.count"), new ArrayList<>(), new ArrayList<>(),
+ (double) metric.getWaitInQueue()));
+ return samples;
+ }
+
+ private List convertMetricValues(Map metrics) {
+ return metrics.entrySet().stream().map((entry) ->
+ new Sample(formatMetricName(entry.getKey()), new ArrayList<>(), new ArrayList<>(),
+ entry.getValue().doubleValue())).collect(Collectors.toList());
+ }
+
+ private List convertCallMetric(CallMetric metric) {
+ List samples = new ArrayList<>();
+ String totalName = formatMetricName(metric.getPrefix() + ".total");
+ for (LongMetricValue value : metric.getTotalValues()) {
+ samples.add(new Sample(totalName,
+ new ArrayList<>(value.getDimensions().keySet()), new ArrayList<>(value.getDimensions().values()),
+ (double) value.getValue()));
+ }
+ String tpsName = formatMetricName(metric.getPrefix() + ".tps");
+ for (DoubleMetricValue value : metric.getTpsValues()) {
+ samples.add(new Sample(tpsName,
+ new ArrayList<>(value.getDimensions().keySet()), new ArrayList<>(value.getDimensions().values()),
+ value.getValue()));
+ }
+ return samples;
+ }
+
+ //convert name for match prometheus
+ private String formatMetricName(String name) {
+ return name.replace(".", "_");
}
}
diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java b/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java
index 6cf6ab2bb04..d550f77c7f8 100644
--- a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java
+++ b/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.samples.mwf;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -24,6 +26,8 @@
import org.apache.servicecomb.metrics.common.CallMetric;
import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric;
+import org.apache.servicecomb.metrics.common.DoubleMetricValue;
+import org.apache.servicecomb.metrics.common.LongMetricValue;
import org.apache.servicecomb.metrics.common.RegistryMetric;
import org.apache.servicecomb.metrics.common.SystemMetric;
import org.apache.servicecomb.metrics.common.TimerMetric;
@@ -134,20 +138,22 @@ public Features getFeatures() {
StringBuilder builder = new StringBuilder();
- MetricsFileWriter writer =
- (loggerName, filePrefix, content) -> builder.append(loggerName).append(filePrefix).append(content);
+ MetricsFileWriter writer = (loggerName, filePrefix, content) ->
+ builder.append(loggerName).append(filePrefix).append(content);
SystemMetric systemMetric = new SystemMetric(50, 10, 1, 2, 3,
4, 5, 6, 7, 8);
Map consumerInvocationMetricMap = new HashMap<>();
- consumerInvocationMetricMap.put("A",
- new ConsumerInvocationMetric("A", "A",
- new TimerMetric("A1", 1, 2, 3, 4), new CallMetric("A2", 100, 999.44444)));
-
- consumerInvocationMetricMap.put("B",
- new ConsumerInvocationMetric("B", "B",
- new TimerMetric("B1", 1, 2, 3, 4), new CallMetric("B2", 100, 888.66666)));
+ consumerInvocationMetricMap.put("A", new ConsumerInvocationMetric("A", "A",
+ new TimerMetric("A1", 1, 2, 3, 4),
+ new CallMetric("A2", Collections.singletonList(new LongMetricValue("A2", 100L, new HashMap<>())),
+ Collections.singletonList(new DoubleMetricValue("A2", 999.44444, new HashMap<>())))));
+
+ consumerInvocationMetricMap.put("B", new ConsumerInvocationMetric("B", "B",
+ new TimerMetric("B1", 1, 2, 3, 4),
+ new CallMetric("B2", Collections.singletonList(new LongMetricValue("B2", 100L, new HashMap<>())),
+ Collections.singletonList(new DoubleMetricValue("B2", 888.66666, new HashMap<>())))));
RegistryMetric metric = new RegistryMetric(systemMetric, consumerInvocationMetricMap, new HashMap<>());
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
index 4cebd3249f4..020c926a3fb 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
@@ -134,7 +134,7 @@ private void doRunInExecutor(QueueMetrics metricsData, InvocationStartedEvent st
invocation.next(response -> {
sendResponse(invocation.getContext(), response);
endMetrics(invocation);
- invocation.triggerFinishedEvent();
+ invocation.triggerFinishedEvent(response.getStatusCode(), response.isSuccessed());
});
}