This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit bd87a7240eb1eb73d854d689b7776079fc4c33c5 Author: zhengyangyong <[email protected]> AuthorDate: Wed Jan 17 15:36:37 2018 +0800 SCB-150 add Status Dimension output level support Signed-off-by: zhengyangyong <[email protected]> --- .../common/rest/AbstractRestInvocation.java | 2 +- .../org/apache/servicecomb/core/Invocation.java | 4 +- .../core/metrics/InvocationFinishedEvent.java | 11 +- .../core/provider/consumer/InvokerUtils.java | 9 +- .../servicecomb/metrics/common/CallMetric.java | 4 +- .../metrics/common/MetricsDimension.java | 31 ++-- .../servicecomb/metrics/core/MetricsConfig.java | 2 + .../core/event/DefaultEventListenerManager.java | 17 ++- .../event/InvocationFinishedEventListener.java | 14 +- .../event/dimension/CodeGroupStatusConvertor.java | 45 ++++++ .../dimension/CodeStatusConvertor.java} | 9 +- .../dimension/StatusConvertor.java} | 6 +- .../event/dimension/StatusConvertorFactory.java | 53 +++++++ .../dimension/SuccessFailedStatusConvertor.java} | 12 +- .../metrics/core/monitor/CallMonitor.java | 90 ++++++------ .../core/monitor/ConsumerInvocationMonitor.java | 3 +- .../core/monitor/ProducerInvocationMonitor.java | 3 +- .../metrics/core/TestEventAndRunner.java | 72 ++++++---- .../metrics/core/TestStatusDimension.java | 158 +++++++++++++++++++++ .../transport/highway/HighwayServerInvoke.java | 2 +- 20 files changed, 433 insertions(+), 114 deletions(-) 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 0ee7999..36c1739 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 @@ public abstract class AbstractRestInvocation { invocation.next(resp -> { sendResponseQuietly(resp); - invocation.triggerFinishedEvent(resp.isSuccessed()); + 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 19241b8..81f25f8 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 class Invocation extends SwaggerInvocation { operationMeta.getMicroserviceQualifiedName(), this.invocationType, startProcessingTime - startTime)); } - public void triggerFinishedEvent(boolean success) { + public void triggerFinishedEvent(int statusCode, boolean success) { long finishedTime = System.nanoTime(); EventUtils .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), this.invocationType, finishedTime - startProcessingTime, - finishedTime - startTime, success)); + 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 ea54d67..4de6154 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,8 @@ public class InvocationFinishedEvent implements Event { private final long totalElapsedNanoTime; + private final int statusCode; + private final boolean success; public String getOperationName() { @@ -47,18 +49,21 @@ public class InvocationFinishedEvent implements Event { return totalElapsedNanoTime; } + public int getStatusCode() { + return statusCode; + } + public boolean isSuccess() { return success; } public InvocationFinishedEvent(String operationName, InvocationType invocationType, - long processElapsedNanoTime, - long totalElapsedNanoTime, - boolean success) { + 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 e8b8247..2635ac3 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 @@ -63,6 +63,7 @@ public final class InvokerUtils { public static Response innerSyncInvoke(Invocation invocation) { boolean success = false; + int statusCode = 0; try { triggerStartedEvent(invocation); SyncResponseExecutor respExecutor = new SyncResponseExecutor(); @@ -72,6 +73,7 @@ public final class InvokerUtils { Response response = respExecutor.waitResponse(); success = response.isSuccessed(); + statusCode = response.getStatusCode(); return response; } catch (Throwable e) { String msg = @@ -79,7 +81,7 @@ public final class InvokerUtils { LOGGER.debug(msg, e); return Response.createConsumerFail(e); } finally { - invocation.triggerFinishedEvent(success); + invocation.triggerFinishedEvent(statusCode, success); } } @@ -92,11 +94,12 @@ public final class InvokerUtils { invocation.setResponseExecutor(respExecutor); invocation.next(ar -> { - invocation.triggerFinishedEvent(ar.isSuccessed()); + invocation.triggerFinishedEvent(ar.getStatusCode(), ar.isSuccessed()); asyncResp.handle(ar); }); } catch (Throwable e) { - invocation.triggerFinishedEvent(false); + //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/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 56d0f99..4c5c862 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 @@ -45,7 +45,7 @@ public class CallMetric { return value; } } - return null; + return new LongMetricValue(dimensionValue, 0L, null); } public List<DoubleMetricValue> getTpsValues() { @@ -58,7 +58,7 @@ public class CallMetric { return value; } } - return null; + return new DoubleMetricValue(dimensionValue, 0.0, null); } public CallMetric(String prefix) { 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 index 23f1f40..904cc25 100644 --- 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 @@ -17,23 +17,30 @@ package org.apache.servicecomb.metrics.common; -import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; - 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 = "success"; + 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_FAILED = "failed"; + public static final String DIMENSION_STATUS_OUTPUT_LEVEL_CODE_GROUP = "code_group"; - public static String[] getDimensionOptions(String dimension) { - if (DIMENSION_STATUS.equals(dimension)) { - return new String[] {MetricsDimension.DIMENSION_STATUS_ALL, - MetricsDimension.DIMENSION_STATUS_SUCCESS, - MetricsDimension.DIMENSION_STATUS_FAILED}; - } - throw new ServiceCombException("illegal dimension key : " + dimension); - } + 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 b903f15..cbf6455 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 @@ package org.apache.servicecomb.metrics.core; 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 42aa024..6dc6df4 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 @@ package org.apache.servicecomb.metrics.core.event; 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 8d15eac..5b886b6 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 @@ -21,17 +21,20 @@ 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 @@ -42,17 +45,16 @@ public class InvocationFinishedEventListener implements EventListener { @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, - event.isSuccess() ? MetricsDimension.DIMENSION_STATUS_SUCCESS : MetricsDimension.DIMENSION_STATUS_FAILED); + 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, - event.isSuccess() ? MetricsDimension.DIMENSION_STATUS_SUCCESS : MetricsDimension.DIMENSION_STATUS_FAILED); + monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue); } } } 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 0000000..92b99d0 --- /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<Family, String> 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/MetricsConfig.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java similarity index 77% copy from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java copy to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java index b903f15..b01f5da 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/event/dimension/CodeStatusConvertor.java @@ -15,8 +15,11 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.core; +package org.apache.servicecomb.metrics.core.event.dimension; -public class MetricsConfig { - public static final String METRICS_POLLING_TIME = "servicecomb.metrics.window_time"; +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/MetricsConfig.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java similarity index 83% copy from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java copy to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java index b903f15..17023b6 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/event/dimension/StatusConvertor.java @@ -15,8 +15,8 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.core; +package org.apache.servicecomb.metrics.core.event.dimension; -public class MetricsConfig { - public static final String METRICS_POLLING_TIME = "servicecomb.metrics.window_time"; +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 0000000..369cda4 --- /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<String, Supplier<StatusConvertor>> 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/MetricsConfig.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java similarity index 65% copy from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsConfig.java copy to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java index b903f15..c2cf998 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/event/dimension/SuccessFailedStatusConvertor.java @@ -15,8 +15,14 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.core; +package org.apache.servicecomb.metrics.core.event.dimension; -public class MetricsConfig { - public static final String METRICS_POLLING_TIME = "servicecomb.metrics.window_time"; +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 068776e..2e61440 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 @@ -19,7 +19,9 @@ 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; @@ -33,61 +35,61 @@ import com.netflix.servo.monitor.StepCounter; public class CallMonitor { private final String prefix; - private final List<BasicCounter> totalCounters; + private final Map<String, Map<String, DimensionCounter>> dimensionCounters; - private final List<StepCounter> tpsCounters; - - public CallMonitor(String prefix, String... dimensionKeys) { + public CallMonitor(String prefix) { this.prefix = prefix; - this.totalCounters = new ArrayList<>(); - this.tpsCounters = new ArrayList<>(); - if (dimensionKeys.length == 0) { - this.totalCounters.add(new BasicCounter(MonitorConfig.builder(prefix + ".total").build())); - this.tpsCounters.add(new StepCounter(MonitorConfig.builder(prefix + ".tps").build())); - } else { - for (String dimensionKey : dimensionKeys) { - for (String option : MetricsDimension.getDimensionOptions(dimensionKey)) { - this.totalCounters - .add(new BasicCounter(MonitorConfig.builder(prefix + ".total").withTag(dimensionKey, option).build())); - this.tpsCounters - .add(new StepCounter(MonitorConfig.builder(prefix + ".tps").withTag(dimensionKey, option).build())); - } - } - } + this.dimensionCounters = new ConcurrentHashMapEx<>(); + this.dimensionCounters.put(MetricsDimension.DIMENSION_STATUS, new ConcurrentHashMapEx<>()); } - public void increment() { - for (int i = 0; i < totalCounters.size(); i++) { - totalCounters.get(i).increment(); - tpsCounters.get(i).increment(); - } - } - - public void increment(String dimensionKey, String dimensionValue) { - for (int i = 0; i < totalCounters.size(); i++) { - BasicCounter totalCounter = totalCounters.get(i); - if (MonitorUtils.containsTagValue(totalCounter, dimensionKey, dimensionValue)) { - totalCounter.increment(); - } - StepCounter tpsCounter = tpsCounters.get(i); - if (MonitorUtils.containsTagValue(tpsCounter, dimensionKey, dimensionValue)) { - tpsCounter.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) { List<LongMetricValue> totalValues = new ArrayList<>(); List<DoubleMetricValue> tpsValues = new ArrayList<>(); - for (int i = 0; i < totalCounters.size(); i++) { - BasicCounter totalCounter = totalCounters.get(i); - totalValues.add(new LongMetricValue(totalCounter.getValue(windowTimeIndex).longValue(), - MonitorUtils.convertTags(totalCounter))); - StepCounter tpsCounter = tpsCounters.get(i); - tpsValues.add( - new DoubleMetricValue(MonitorUtils.adjustValue(tpsCounter.getValue(windowTimeIndex).doubleValue()), - MonitorUtils.convertTags(tpsCounter))); + for (Map<String, DimensionCounter> 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); } + + 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/ConsumerInvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java index 9a09551..1f2f247 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ConsumerInvocationMonitor.java @@ -20,7 +20,6 @@ package org.apache.servicecomb.metrics.core.monitor; import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric; import org.apache.servicecomb.metrics.common.MetricsConst; -import org.apache.servicecomb.metrics.common.MetricsDimension; public class ConsumerInvocationMonitor extends InvocationMonitor { private final TimerMonitor consumerLatency; @@ -38,7 +37,7 @@ public class ConsumerInvocationMonitor extends InvocationMonitor { public ConsumerInvocationMonitor(String operationName) { super(operationName, String.format(MetricsConst.CONSUMER_PREFIX_TEMPLATE, operationName)); this.consumerLatency = new TimerMonitor(this.getPrefix() + ".consumerLatency"); - this.consumerCall = new CallMonitor(this.getPrefix() + ".consumerCall", MetricsDimension.DIMENSION_STATUS); + this.consumerCall = new CallMonitor(this.getPrefix() + ".consumerCall"); } public ConsumerInvocationMetric toMetric(int windowTimeIndex) { diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java index 50a508c..9c77ec8 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/ProducerInvocationMonitor.java @@ -18,7 +18,6 @@ package org.apache.servicecomb.metrics.core.monitor; import org.apache.servicecomb.metrics.common.MetricsConst; -import org.apache.servicecomb.metrics.common.MetricsDimension; import org.apache.servicecomb.metrics.common.ProducerInvocationMetric; import com.netflix.servo.monitor.BasicCounter; @@ -61,7 +60,7 @@ public class ProducerInvocationMonitor extends InvocationMonitor { this.lifeTimeInQueue = new TimerMonitor(this.getPrefix() + ".lifeTimeInQueue"); this.executionTime = new TimerMonitor(this.getPrefix() + ".executionTime"); this.producerLatency = new TimerMonitor(this.getPrefix() + ".producerLatency"); - this.producerCall = new CallMonitor(this.getPrefix() + ".producerCall", MetricsDimension.DIMENSION_STATUS); + this.producerCall = new CallMonitor(this.getPrefix() + ".producerCall"); } public ProducerInvocationMetric toMetric(int windowTimeIndex) { 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 8e87439..85cf463 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 @@ -36,6 +36,7 @@ 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; @@ -74,7 +75,8 @@ public class TestEventAndRunner { 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 2 time and all is completed //two time success @@ -84,7 +86,7 @@ public class TestEventAndRunner { TimeUnit.MILLISECONDS.toNanos(100))); EventUtils .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, - TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), true)); + TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true)); EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime())); EventUtils.triggerEvent( @@ -92,7 +94,7 @@ public class TestEventAndRunner { TimeUnit.MILLISECONDS.toNanos(300))); EventUtils .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, - TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), false)); + TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500, false)); //========================================================================== @@ -116,7 +118,7 @@ public class TestEventAndRunner { TimeUnit.MILLISECONDS.toNanos(100))); EventUtils .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER, - TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), true)); + TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true)); //========================================================================== @@ -159,16 +161,20 @@ public class TestEventAndRunner { 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 0); Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount()); Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(), @@ -183,16 +189,20 @@ public class TestEventAndRunner { 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTpsValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .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_SUCCESS).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 0); //check ProducerMetrics Assert.assertEquals(0, model.getProducerMetrics().get("fun1").getWaitInQueue()); @@ -217,16 +227,20 @@ public class TestEventAndRunner { 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 0); //fun3 Assert.assertEquals(0, model.getProducerMetrics().get("fun3").getWaitInQueue()); @@ -251,16 +265,20 @@ public class TestEventAndRunner { 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 0); //check ConsumerMetrics //no need @@ -273,19 +291,23 @@ public class TestEventAndRunner { 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).getValue(), 0); + .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_FAILED).getValue(), 0); + .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).getValue(), 0); + .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_FAILED).getValue(), 0); + .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_SUCCESS_FAILED_FAILED) + .getValue(), 0); Map<String, Number> metrics = model.toMap(); - Assert.assertEquals(120, metrics.size()); + Assert.assertEquals(108, metrics.size()); Assert.assertEquals(1.0, model.getInstanceMetric().getSystemMetric().getCpuLoad(), 0); Assert.assertEquals(2, model.getInstanceMetric().getSystemMetric().getCpuRunningThreads(), 0); 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 0000000..0a113fb --- /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/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 ba8c126..020c926 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 @@ public class HighwayServerInvoke { invocation.next(response -> { sendResponse(invocation.getContext(), response); endMetrics(invocation); - invocation.triggerFinishedEvent(response.isSuccessed()); + invocation.triggerFinishedEvent(response.getStatusCode(), response.isSuccessed()); }); } -- To stop receiving notification emails like this one, please contact [email protected].
