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 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()); }); }