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 5e874367891..3cef7206ea2 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(resp.getStatusCode(), resp.isSuccessed()); + invocation.triggerFinishedEvent(resp.getStatusCode()); }); } 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 96a84b901c8..882b9e680d1 100644 --- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java +++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java @@ -188,15 +188,16 @@ public String getMicroserviceQualifiedName() { public void triggerStartProcessingEvent() { this.startProcessingTime = System.nanoTime(); EventUtils.triggerEvent(new InvocationStartProcessingEvent( - operationMeta.getMicroserviceQualifiedName(), this.invocationType, startProcessingTime - startTime)); + operationMeta.getMicroserviceQualifiedName(), this.invocationType)); } - public void triggerFinishedEvent(int statusCode, boolean success) { + public void triggerFinishedEvent(int statusCode) { long finishedTime = System.nanoTime(); EventUtils - .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), - this.invocationType, finishedTime - startProcessingTime, - finishedTime - startTime, statusCode, success)); + .triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), this.invocationType, + startProcessingTime - startTime, + finishedTime - startProcessingTime, + finishedTime - startTime, statusCode)); } 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 4de6154e0d2..ee7c6849cfa 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 @@ -25,14 +25,14 @@ public class InvocationFinishedEvent implements Event { private final InvocationType invocationType; + private final long inQueueNanoTime; + private final long processElapsedNanoTime; private final long totalElapsedNanoTime; private final int statusCode; - private final boolean success; - public String getOperationName() { return operationName; } @@ -41,6 +41,10 @@ public InvocationType getInvocationType() { return invocationType; } + public long getInQueueNanoTime() { + return inQueueNanoTime; + } + public long getProcessElapsedNanoTime() { return processElapsedNanoTime; } @@ -53,17 +57,13 @@ public int getStatusCode() { return statusCode; } - public boolean isSuccess() { - return success; - } - public InvocationFinishedEvent(String operationName, InvocationType invocationType, - long processElapsedNanoTime, long totalElapsedNanoTime, int statusCode, boolean success) { + long inQueueNanoTime, long processElapsedNanoTime, long totalElapsedNanoTime, int statusCode) { this.operationName = operationName; this.invocationType = invocationType; + this.inQueueNanoTime = inQueueNanoTime; this.processElapsedNanoTime = processElapsedNanoTime; this.totalElapsedNanoTime = totalElapsedNanoTime; this.statusCode = statusCode; - this.success = success; } } diff --git a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java index dd579e8899a..3e7ed6badbd 100644 --- a/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java +++ b/core/src/main/java/org/apache/servicecomb/core/metrics/InvocationStartProcessingEvent.java @@ -25,8 +25,6 @@ public class InvocationStartProcessingEvent implements Event { private final InvocationType invocationType; - private final long inQueueNanoTime; - public String getOperationName() { return operationName; } @@ -35,14 +33,9 @@ public InvocationType getInvocationType() { return invocationType; } - public long getInQueueNanoTime() { - return inQueueNanoTime; - } - public InvocationStartProcessingEvent(String operationName, InvocationType invocationType, - long inQueueNanoTime) { + public InvocationStartProcessingEvent(String operationName, InvocationType invocationType) { this.operationName = operationName; this.invocationType = invocationType; - this.inQueueNanoTime = inQueueNanoTime; } } 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 2504ab00d48..8977e87f450 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 @@ -34,9 +34,6 @@ public final class InvokerUtils { private static final Logger LOGGER = LoggerFactory.getLogger(InvokerUtils.class); - private InvokerUtils() { - } - public static Object syncInvoke(String microserviceName, String schemaId, String operationName, Object[] args) { ReferenceConfig referenceConfig = ReferenceConfigUtils.getForInvoke(microserviceName); SchemaMeta schemaMeta = referenceConfig.getMicroserviceMeta().ensureFindSchemaMeta(schemaId); @@ -59,7 +56,7 @@ public static Object syncInvoke(Invocation invocation) throws InvocationExceptio return response.getResult(); } - throw ExceptionFactory.convertConsumerException((Throwable) response.getResult()); + throw ExceptionFactory.convertConsumerException(response.getResult()); } public static Response innerSyncInvoke(Invocation invocation) { @@ -73,7 +70,6 @@ public static Response innerSyncInvoke(Invocation invocation) { invocation.next(respExecutor::setResponse); Response response = respExecutor.waitResponse(); - success = response.isSuccessed(); statusCode = response.getStatusCode(); return response; } catch (Throwable e) { @@ -82,7 +78,7 @@ public static Response innerSyncInvoke(Invocation invocation) { LOGGER.debug(msg, e); return Response.createConsumerFail(e); } finally { - invocation.triggerFinishedEvent(statusCode, success); + invocation.triggerFinishedEvent(statusCode); } } @@ -97,7 +93,7 @@ public static void reactiveInvoke(Invocation invocation, AsyncResponse asyncResp invocation.next(ar -> { ContextUtils.setInvocationContext(invocation.getParentContext()); try { - invocation.triggerFinishedEvent(ar.getStatusCode(), ar.isSuccessed()); + invocation.triggerFinishedEvent(ar.getStatusCode()); asyncResp.handle(ar); } finally { ContextUtils.removeInvocationContext(); @@ -105,7 +101,7 @@ public static void reactiveInvoke(Invocation invocation, AsyncResponse asyncResp }); } catch (Throwable e) { //if throw exception,we can use 500 for status code ? - invocation.triggerFinishedEvent(500, false); + invocation.triggerFinishedEvent(500); LOGGER.error("invoke failed, {}", invocation.getOperationMeta().getMicroserviceQualifiedName()); asyncResp.consumerFail(e); } diff --git a/demo/demo-springmvc/springmvc-client/pom.xml b/demo/demo-springmvc/springmvc-client/pom.xml index 884d0c667eb..1ec0e9b6312 100644 --- a/demo/demo-springmvc/springmvc-client/pom.xml +++ b/demo/demo-springmvc/springmvc-client/pom.xml @@ -41,12 +41,6 @@ org.apache.servicecomb provider-pojo - - - org.apache.servicecomb - metrics-common - - 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 f2fc0d77a30..55f4b219736 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 @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.Map; + import org.apache.servicecomb.core.CseContext; import org.apache.servicecomb.demo.DemoConst; import org.apache.servicecomb.demo.TestMgr; @@ -26,9 +27,6 @@ import org.apache.servicecomb.demo.controller.Person; import org.apache.servicecomb.foundation.common.utils.BeanUtils; 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; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; import org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory; @@ -45,8 +43,6 @@ public class SpringmvcClient { private static Controller controller; - private static MetricsPublisher metricsPublisher; - public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); @@ -60,7 +56,6 @@ public static void run() { templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory()); restTemplate = RestTemplateBuilder.create(); controller = BeanUtils.getBean("controller"); - metricsPublisher = BeanUtils.getBean("metricsPublisher"); String prefix = "cse://springmvc"; @@ -88,14 +83,15 @@ public static void run() { //0.5.0 later version metrics integration test try { - RegistryMetric metric = metricsPublisher.metrics(); + Thread.sleep(1000); + Map metrics = restTemplate.getForObject(prefix + "/metrics", Map.class); TestMgr - .check(true, metric.getInstanceMetric().getSystemMetric().getHeapUsed() != 0); - TestMgr.check(true, metric.getProducerMetrics().size() > 0); - TestMgr.check(true, - metric.getProducerMetrics().get("springmvc.codeFirst.saySomething").getProducerCall() - .getTotalValue(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL).getValue() > 0); + .check(true, metrics.get("jvm(statistic=gauge,name=heapUsed)") != 0); + TestMgr.check(true, metrics.size() > 0); + TestMgr.check(true, metrics.get( + "servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=producer,stage=whole,statistic=count,status=200)") + >= 0); } catch (Exception e) { TestMgr.check("true", "false"); } @@ -104,20 +100,20 @@ public static void run() { try { String content = restTemplate.getForObject("cse://springmvc/codeFirstSpringmvc/prometheusForTest", String.class); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_addDate")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_sayHello")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_fallbackFromCache")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_isTrue_producer")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_add")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_sayHi2")); - TestMgr.check(true, content.contains("servicecomb_springmvc_codeFirst_saySomething")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_addDate")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_sayHello")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_fallbackFromCache")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_isTrue")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_add")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_sayHi2")); + TestMgr.check(true, content.contains("servicecomb_invocation_springmvc_codeFirst_saySomething")); String[] metricLines = content.split("\n"); if (metricLines.length > 0) { for (String metricLine : metricLines) { if (!metricLine.startsWith("#")) { String[] metricKeyAndValue = metricLine.split(" "); - if (!metricKeyAndValue[0].startsWith("servicecomb_instance_system")) { + if (!metricKeyAndValue[0].startsWith("jvm")) { if (Double.parseDouble(metricKeyAndValue[1]) < 0) { TestMgr.check("true", "false"); break; diff --git a/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml b/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml index 23ba32bccaa..d5836eff6b3 100644 --- a/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml +++ b/demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml @@ -17,18 +17,14 @@ --> - - - - - + + diff --git a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml index d7a69d82602..311765ca650 100644 --- a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml +++ b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml @@ -73,3 +73,7 @@ ssl.keyStoreType: PKCS12 ssl.keyStoreValue: Changeme_123 ssl.crl: revoke.crl ssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom + +servicecomb: + metrics: + window_time: 1000 diff --git a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMain.java b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMain.java index 5c6a38c3c3c..16a0bed53c3 100644 --- a/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMain.java +++ b/demo/perf/src/main/java/org/apache/servicecomb/demo/perf/PerfMain.java @@ -24,7 +24,7 @@ import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.vertx.VertxUtils; -import org.apache.servicecomb.metrics.core.publish.DataSource; +import org.apache.servicecomb.metrics.core.MetricsDataSource; public class PerfMain { @@ -35,8 +35,8 @@ public static void main(String[] args) throws Exception { RedisClientUtils.init(VertxUtils.getOrCreateVertxByName("transport", null)); // metrics - DataSource dataSource = BeanUtils.getContext().getBean(DataSource.class); - PerfMetricsFilePublisher metricsLog = new PerfMetricsFilePublisher(dataSource); + //DataSource dataSource = BeanUtils.getContext().getBean(Def.class); + PerfMetricsFilePublisher metricsLog = new PerfMetricsFilePublisher(MetricsDataSource.getInstance()); Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(metricsLog::onCycle, 0, 1, TimeUnit.SECONDS); List argList = Arrays.asList(args); @@ -45,5 +45,4 @@ public static void main(String[] args) throws Exception { consumer.runConsumer(); } } - } 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 1f00bc248c5..f17b04dde78 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 @@ -16,44 +16,46 @@ */ package org.apache.servicecomb.demo.perf; +import java.util.Map; import java.util.Map.Entry; +import org.apache.servicecomb.foundation.metrics.MetricsConst; +import org.apache.servicecomb.foundation.metrics.publish.MetricNode; +import org.apache.servicecomb.foundation.metrics.publish.MetricsLoader; import org.apache.servicecomb.foundation.vertx.VertxUtils; -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; +import org.apache.servicecomb.metrics.core.MetricsDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; + import io.vertx.core.impl.VertxImplEx; public class PerfMetricsFilePublisher { private static final Logger LOGGER = LoggerFactory.getLogger(PerfMetricsFilePublisher.class); - private DataSource dataSource; + private MetricsDataSource dataSource; - public PerfMetricsFilePublisher(DataSource dataSource) { + public PerfMetricsFilePublisher(MetricsDataSource dataSource) { this.dataSource = dataSource; } public void onCycle() { - RegistryMetric metric = dataSource.getRegistryMetric(); + Map metrics = dataSource.measure(dataSource.getAppliedWindowTime().get(0), true); + MetricsLoader loader = new MetricsLoader(metrics); StringBuilder sb = new StringBuilder(); sb.append("\n"); - collectSystemMetrics(metric, sb); - collectVertxMetrics(metric, sb); - collectConsumerMetrics(metric, sb); - collectProducerMetrics(metric, sb); + collectSystemMetrics(loader, sb); + collectVertxMetrics(loader, sb); + collectMetrics(loader, sb); LOGGER.info(sb.toString()); } - protected void collectSystemMetrics(RegistryMetric metric, StringBuilder sb) { - double cpu = metric.getInstanceMetric().getSystemMetric().getCpuLoad(); + private void collectSystemMetrics(MetricsLoader loader, StringBuilder sb) { + double cpu = loader.getFirstMatchMetricValue(MetricsConst.JVM, MetricsConst.TAG_NAME, "cpuLoad"); // can not get cpu usage in windows, so skip this information if (cpu >= 0) { sb.append("cpu: ") @@ -62,7 +64,7 @@ protected void collectSystemMetrics(RegistryMetric metric, StringBuilder sb) { } } - protected void collectVertxMetrics(RegistryMetric metric, StringBuilder sb) { + private void collectVertxMetrics(MetricsLoader loader, StringBuilder sb) { sb.append("vertx:\n") .append(" name eventLoopContext-created\n"); for (Entry entry : VertxUtils.getVertxMap().entrySet()) { @@ -72,55 +74,55 @@ protected void collectVertxMetrics(RegistryMetric metric, StringBuilder sb) { } } - protected void collectProducerMetrics(RegistryMetric metric, StringBuilder sb) { - if (metric.getProducerMetrics().isEmpty()) { - return; - } - - sb.append("producer:\n" - + " total tps latency(ms) queue(ms) execute(ms) name\n"); - for (Entry entry : metric.getProducerMetrics().entrySet()) { - String opName = entry.getKey(); - sb.append( - String.format(" %-19d %-7d %-11.3f %-9.3f %-11.3f %s\n", - 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(), - opName)); - } - } - - protected void collectConsumerMetrics(RegistryMetric metric, StringBuilder sb) { - if (metric.getConsumerMetrics().isEmpty()) { - return; - } - - sb.append("consumer:\n" - + " total tps latency(ms) name\n"); - for (Entry entry : metric.getConsumerMetrics().entrySet()) { - String opName = entry.getKey(); - sb.append(String - .format(" %-19d %-7d %-11.3f %s\n", - 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)); + private void collectMetrics(MetricsLoader loader, StringBuilder sb) { + MetricNode treeNode = loader + .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_ROLE, MetricsConst.TAG_OPERATION, + MetricsConst.TAG_STATUS); + + if (treeNode != null && treeNode.getChildren().size() != 0) { + MetricNode consumerNode = treeNode.getChildren().get(MetricsConst.ROLE_CONSUMER); + if (consumerNode != null) { + sb.append("consumer:\n"); + sb.append(" tps latency(ms) status operation\n"); + for (Entry operationNode : consumerNode.getChildren().entrySet()) { + for (Entry statusNode : operationNode.getValue().getChildren().entrySet()) { + sb.append(String.format(" %-7.0f %-11.3f %-9s %s\n", + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_WHOLE, "tps")), + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_WHOLE, "latency")), + statusNode.getKey(), + operationNode.getKey())); + } + } + } + + MetricNode producerNode = treeNode.getChildren().get(MetricsConst.ROLE_PRODUCER); + if (producerNode != null) { + sb.append("producer:\n"); + sb.append(" tps latency(ms) queue(ms) execute(ms) status operation\n"); + for (Entry operationNode : producerNode.getChildren().entrySet()) { + for (Entry statusNode : operationNode.getValue().getChildren().entrySet()) { + sb.append(String.format(" %-7.0f %-11.3f %-9.3f %-11.3f %-7s %s\n", + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_WHOLE, "tps")), + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_WHOLE, "latency")), + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_QUEUE, "latency")), + statusNode.getValue() + .getFirstMatchMetricValue(Lists.newArrayList(MetricsConst.TAG_STAGE, MetricsConst.TAG_STATISTIC), + Lists.newArrayList(MetricsConst.STAGE_EXECUTION, "latency")), + statusNode.getKey(), + operationNode.getKey())); + } + } + } } } } diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java similarity index 51% rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java index a47b055cd4d..7bb019825ed 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsConst.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsConst.java @@ -15,14 +15,32 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.common; +package org.apache.servicecomb.foundation.metrics; public class MetricsConst { - public static final String CONSUMER_PREFIX_TEMPLATE = "servicecomb.%s.consumer"; + public static final String JVM = "jvm"; - public static final String PRODUCER_PREFIX_TEMPLATE = "servicecomb.%s.producer"; + public static final String SERVICECOMB_INVOCATION = "servicecomb.invocation"; - public static final String INSTANCE_CONSUMER_PREFIX = String.format(CONSUMER_PREFIX_TEMPLATE, "instance"); + public static final String TAG_NAME = "name"; - public static final String INSTANCE_PRODUCER_PREFIX = String.format(PRODUCER_PREFIX_TEMPLATE, "instance"); + public static final String TAG_OPERATION = "operation"; + + public static final String TAG_STATUS = "status"; + + public static final String TAG_STAGE = "stage"; + + public static final String TAG_ROLE = "role"; + + public static final String TAG_STATISTIC = "statistic"; + + public static final String STAGE_WHOLE = "whole"; + + public static final String STAGE_QUEUE = "queue"; + + public static final String STAGE_EXECUTION = "execution"; + + public static final String ROLE_CONSUMER = "consumer"; + + public static final String ROLE_PRODUCER = "producer"; } diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckResult.java similarity index 96% rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckResult.java index 880bdc356cd..fc147fbd643 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckResult.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckResult.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.common; +package org.apache.servicecomb.foundation.metrics.health; public class HealthCheckResult { private boolean healthy; diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthChecker.java similarity index 93% rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthChecker.java index 3ae1d8c2c07..4dd016f3ad5 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthChecker.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthChecker.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.common; +package org.apache.servicecomb.foundation.metrics.health; public interface HealthChecker { String getName(); diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckerManager.java similarity index 60% rename from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java rename to foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckerManager.java index 6327dffa70d..249f1299f8f 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckerManager.java @@ -15,52 +15,33 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.core.publish; +package org.apache.servicecomb.foundation.metrics.health; -import static javax.ws.rs.core.Response.Status.BAD_REQUEST; - -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; -import org.apache.servicecomb.swagger.invocation.exception.InvocationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class DefaultHealthCheckerManager implements HealthCheckerManager { +public class HealthCheckerManager { private final Map healthCheckers; - @Autowired(required = false) - public DefaultHealthCheckerManager(List springHealthCheckers) { + public HealthCheckerManager() { this.healthCheckers = new ConcurrentHashMap<>(); - if (springHealthCheckers != null && !springHealthCheckers.isEmpty()) { - for (HealthChecker checker : springHealthCheckers) { - this.healthCheckers.put(checker.getName(), checker); - } - } } - @Override public void register(HealthChecker checker) { healthCheckers.put(checker.getName(), checker); } - @Override public Map check() { return healthCheckers.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> e.getValue().check())); } - @Override public HealthCheckResult check(String name) { HealthChecker checker = healthCheckers.get(name); if (checker != null) { return checker.check(); } - throw new InvocationException(BAD_REQUEST, "HealthChecker name : " + name + " unregister"); + return null; } } diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java new file mode 100644 index 00000000000..3a01644b323 --- /dev/null +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/Metric.java @@ -0,0 +1,66 @@ +/* + * 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.foundation.metrics.publish; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Metric { + private final String name; + + private final Map tags; + + private double value; + + public String getName() { + return name; + } + + public Map getTags() { + return tags; + } + + public double getValue() { + return value; + } + + public Metric(String id, double value) { + String[] nameAndTag = id.split("\\("); + this.tags = new HashMap<>(); + String[] tagAnValues = nameAndTag[1].split("[=,)]"); + for (int i = 0; i < tagAnValues.length; i += 2) { + this.tags.put(tagAnValues[i], tagAnValues[i + 1]); + } + this.name = nameAndTag[0]; + this.value = value; + } + + public boolean containTag(List tagKeys, List tagValues) { + for (int i = 0; i < tagKeys.size(); i++) { + if (!containTag(tagKeys.get(i), tagValues.get(i))) { + return false; + } + } + return true; + } + + public boolean containTag(String tagKey, String tagValue) { + return tags.containsKey(tagKey) && tagValue.equals(tags.get(tagKey)); + } +} diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.java new file mode 100644 index 00000000000..c23d9e22f39 --- /dev/null +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricNode.java @@ -0,0 +1,108 @@ +/* + * 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.foundation.metrics.publish; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.servicecomb.foundation.metrics.MetricsConst; + +public class MetricNode { + private final String tagKey; + + private final List metrics; + + private final Map children; + + public List getMetrics() { + return metrics; + } + + public Map getChildren() { + return children; + } + + public MetricNode getChildrenNode(String tagValue) { + return children.get(tagValue); + } + + public Double getFirstMatchMetricValue(String tagKey, String tagValue) { + for (Metric metric : this.metrics) { + if (metric.containTag(tagKey, tagValue)) { + return metric.getValue(); + } + } + return Double.NaN; + } + + public Double getFirstMatchMetricValue(List tagKeys, List tagValues) { + for (Metric metric : this.metrics) { + if (metric.containTag(tagKeys, tagValues)) { + return metric.getValue(); + } + } + return Double.NaN; + } + + public double getMatchStatisticMetricValue(String statisticValue) { + return getFirstMatchMetricValue(MetricsConst.TAG_STATISTIC, statisticValue); + } + + public MetricNode(List metrics, String... groupTagKeys) { + if (groupTagKeys == null || groupTagKeys.length == 0) { + this.tagKey = null; + this.metrics = metrics; + this.children = null; + } else { + this.tagKey = groupTagKeys[0]; + this.metrics = null; + this.children = new HashMap<>(); + Map> groups = groupByTag(metrics, this.tagKey); + if (groupTagKeys.length == 1) { + for (Entry> group : groups.entrySet()) { + this.children.put(group.getKey(), new MetricNode(null, group.getValue(), null)); + } + } else { + for (Entry> group : groups.entrySet()) { + this.children.put(group.getKey(), + new MetricNode(group.getValue(), Arrays.copyOfRange(groupTagKeys, 1, groupTagKeys.length))); + } + } + } + } + + private MetricNode(String tagKey, List metrics, Map children) { + this.tagKey = tagKey; + this.metrics = metrics; + this.children = children; + } + + private Map> groupByTag(List metrics, String tagKey) { + Map> groups = new HashMap<>(); + for (Metric metric : metrics) { + if (metric.getTags().containsKey(tagKey)) { + groups.computeIfAbsent(metric.getTags().get(tagKey), g -> new ArrayList<>()).add(metric); + } + } + return groups; + } +} diff --git a/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.java b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.java new file mode 100644 index 00000000000..073eaf6cead --- /dev/null +++ b/foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MetricsLoader.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.foundation.metrics.publish; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +//load origin metrics value and publish tree +public class MetricsLoader { + + private final Map> metrics; + + public MetricsLoader(Map metrics) { + this.metrics = new HashMap<>(); + for (Entry entry : metrics.entrySet()) { + Metric metric = new Metric(entry.getKey(), entry.getValue()); + this.metrics.computeIfAbsent(metric.getName(), m -> new ArrayList<>()).add(metric); + } + } + + public MetricNode getMetricTree(String id, String... groupTagKeys) { + if (metrics.containsKey(id)) { + return new MetricNode(metrics.get(id), groupTagKeys); + } + return null; + } + + public double getFirstMatchMetricValue(String name, String tagKey, String tagValue) { + if (metrics.containsKey(name)) { + for (Metric metric : this.metrics.get(name)) { + if (metric.containTag(tagKey, tagValue)) { + return metric.getValue(); + } + } + } + return Double.NaN; + } +} diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/health/TestHealthCheckerManager.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/health/TestHealthCheckerManager.java new file mode 100644 index 00000000000..c37d7c7461a --- /dev/null +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/health/TestHealthCheckerManager.java @@ -0,0 +1,57 @@ +/* + * 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.foundation.metrics.health; + +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class TestHealthCheckerManager { + + @Test + public void testRegistry() { + HealthCheckerManager manager = new HealthCheckerManager(); + + manager.register(new HealthChecker() { + @Override + public String getName() { + return "test"; + } + + @Override + public HealthCheckResult check() { + return new HealthCheckResult(false, "bad", "bad call"); + } + }); + + Map results = manager.check(); + + Assert.assertEquals(1, results.size()); + + HealthCheckResult result = manager.check().get("test"); + Assert.assertEquals(false, result.isHealthy()); + Assert.assertEquals("bad", result.getInformation()); + Assert.assertEquals("bad call", result.getExtraData()); + + result = manager.check("test"); + Assert.assertEquals(false, result.isHealthy()); + Assert.assertEquals("bad", result.getInformation()); + Assert.assertEquals("bad call", result.getExtraData()); + } +} diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java new file mode 100644 index 00000000000..9d5254ab5d6 --- /dev/null +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/TestMetricsLoader.java @@ -0,0 +1,62 @@ +/* + * 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.foundation.metrics.publish; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.Lists; + +public class TestMetricsLoader { + @Test + public void test() { + Map metrics = new HashMap<>(); + metrics.put("X(K1=1,K2=2,K3=3)", 100.0); + metrics.put("X(K1=1,K2=20,K3=30)", 200.0); + metrics.put("X(K1=2,K2=200,K3=300)", 300.0); + metrics.put("X(K1=2,K2=2000,K3=3000)", 400.0); + + metrics.put("Y(K1=1,K2=2,K3=3)", 500.0); + metrics.put("Y(K1=10,K2=20,K3=30)", 600.0); + metrics.put("Y(K1=100,K2=200,K3=300)", 700.0); + metrics.put("Y(K1=1000,K2=2000,K3=3000)", 800.0); + + MetricsLoader loader = new MetricsLoader(metrics); + + Assert.assertEquals(200.0, loader.getFirstMatchMetricValue("X", "K3", "30"), 0); + + MetricNode node = loader.getMetricTree("X", "K1"); + + Assert.assertEquals(2, node.getChildren().size()); + + MetricNode node_k1 = node.getChildrenNode("1"); + + Assert.assertEquals(200, node_k1.getFirstMatchMetricValue( + Lists.newArrayList("K2", "K3"), + Lists.newArrayList("20", "30")), 0); + + Assert.assertEquals(100, node_k1.getFirstMatchMetricValue("K2", "2"), 0); + + MetricNode newGroup = new MetricNode(node_k1.getMetrics(), "K2", "K3"); + + Assert.assertEquals(1, newGroup.getChildrenNode("2").getChildrenNode("3").getMetrics().size(), 0); + } +} diff --git a/java-chassis-dependencies/pom.xml b/java-chassis-dependencies/pom.xml index 7e8aae0354e..851689d6002 100644 --- a/java-chassis-dependencies/pom.xml +++ b/java-chassis-dependencies/pom.xml @@ -978,11 +978,6 @@ metrics-core 0.6.0-SNAPSHOT - - org.apache.servicecomb - metrics-common - 0.6.0-SNAPSHOT - org.apache.servicecomb metrics-prometheus diff --git a/metrics/metrics-common/pom.xml b/metrics/metrics-common/pom.xml deleted file mode 100644 index 3ac7fae605a..00000000000 --- a/metrics/metrics-common/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - metrics - org.apache.servicecomb - 0.6.0-SNAPSHOT - - 4.0.0 - - metrics-common - Java Chassis::Metrics::Common - - - - 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 deleted file mode 100644 index 36e1d49bf7b..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 CallMetric { - private final String prefix; - - private final List totalValues; - - private final List tpsValues; - - public String getPrefix() { - return prefix; - } - - 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, new ArrayList<>(), new ArrayList<>()); - } - - public CallMetric(@JsonProperty("prefix") String prefix, - @JsonProperty("totalValues") List totalValues, - @JsonProperty("tpsValues") List tpsValues) { - this.prefix = prefix; - this.totalValues = totalValues; - this.tpsValues = tpsValues; - } - - public CallMetric merge(CallMetric metric) { - return new CallMetric(this.prefix, - LongMetricValue.merge(metric.getTotalValues(), this.getTotalValues()), - DoubleMetricValue.merge(metric.getTpsValues(), this.getTpsValues())); - } - - public Map toMap() { - Map metrics = new HashMap<>(); - for (LongMetricValue totalValue : totalValues) { - metrics.put(prefix + ".total." + totalValue.getKey(), totalValue.getValue()); - } - for (DoubleMetricValue 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/ConsumerInvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ConsumerInvocationMetric.java deleted file mode 100644 index 681e1d4891b..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ConsumerInvocationMetric.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ConsumerInvocationMetric extends InvocationMetric { - private final TimerMetric consumerLatency; - - private final CallMetric consumerCall; - - public TimerMetric getConsumerLatency() { - return consumerLatency; - } - - public CallMetric getConsumerCall() { - return consumerCall; - } - - public ConsumerInvocationMetric(@JsonProperty("operationName") String operationName, - @JsonProperty("prefix") String prefix, - @JsonProperty("consumerLatency") TimerMetric consumerLatency, - @JsonProperty("consumerCall") CallMetric consumerCall) { - super(operationName, prefix); - this.consumerLatency = consumerLatency; - this.consumerCall = consumerCall; - } - - public ConsumerInvocationMetric merge(ConsumerInvocationMetric metric) { - return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(), - consumerLatency.merge(metric.getConsumerLatency()), - consumerCall.merge(metric.getConsumerCall())); - } - - public Map toMap() { - Map metrics = new HashMap<>(); - metrics.putAll(consumerLatency.toMap()); - metrics.putAll(consumerCall.toMap()); - 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 deleted file mode 100644 index e6ace957c9f..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DoubleMetricValue.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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/InstanceMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InstanceMetric.java deleted file mode 100644 index 58ae2cd4d85..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InstanceMetric.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class InstanceMetric { - private final SystemMetric systemMetric; - - private final ConsumerInvocationMetric consumerMetric; - - private final ProducerInvocationMetric producerMetric; - - public SystemMetric getSystemMetric() { - return systemMetric; - } - - public ConsumerInvocationMetric getConsumerMetric() { - return consumerMetric; - } - - public ProducerInvocationMetric getProducerMetric() { - return producerMetric; - } - - public InstanceMetric(@JsonProperty("systemMetric") SystemMetric systemMetric, - @JsonProperty("consumerMetric") ConsumerInvocationMetric consumerMetric, - @JsonProperty("producerMetric") ProducerInvocationMetric producerMetric) { - this.systemMetric = systemMetric; - this.consumerMetric = consumerMetric; - this.producerMetric = producerMetric; - } - - public Map toMap() { - Map metrics = new HashMap<>(); - metrics.putAll(systemMetric.toMap()); - metrics.putAll(consumerMetric.toMap()); - metrics.putAll(producerMetric.toMap()); - return metrics; - } -} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java deleted file mode 100644 index 234ccece4ab..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/InvocationMetric.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 InvocationMetric { - private final String operationName; - - private final String prefix; - - public String getOperationName() { - return operationName; - } - - public String getPrefix() { - return prefix; - } - - public InvocationMetric(String operationName, String prefix) { - this.operationName = operationName; - this.prefix = prefix; - } -} 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 deleted file mode 100644 index ff271349844..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/LongMetricValue.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0a8d3642927..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricValue.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 deleted file mode 100644 index 904cc25b8ed..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsDimension.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java deleted file mode 100644 index 029ddb3839a..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/MetricsPublisher.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.List; - -public interface MetricsPublisher { - /** What's the WindowTime ? - We all know there are two major type of metric : - 1.Time-unrelated,you can get the latest value any time immediately: - Counter -> increase or decrease - Guage -> set a certain one value - 2.Time-related,only after a centain time pass you can compute the right value,"a centain time" called WindowTime - Max & Min -> the max value or min value in a centain time - Average -> average value, the simplest algorithm is f = sum / count - Rate -> like TPS,algorithm is f = sum / second - - Will be return "servicecomb.metrics.window_time" setting in microservice.yaml - */ - List getAppliedWindowTime(); - - //same as getRegistryMetric({first setting windowTime}) - RegistryMetric metrics(); - - /** - * windowTime usage example: - * if there is two window time set in "servicecomb.metrics.window_time" like 1000,2000 - * then windowTime = 1000 will return result of the setting 1000(1 second) - * windowTime = 2000 will return result of the setting 2000(2 second) - * - * there are three monitor of max,min,total - * 0----------1----------2----------3---------- <-time line (second) - * 100,200 300,400 <-value record - * - * ↑ getRegistryMetric(1000) will return max=200 min=100 total=300 - * getRegistryMetric(2000) will return max=0 min=0 total=0 - * ↑ getRegistryMetric(1000) will return max=300 min=400 total=700 - * getRegistryMetric(2000) will return max=400 min=100 total=1000 - * - * @param windowTime getAppliedWindowTime() item - * @return RegistryMetric - */ - RegistryMetric metricsWithWindowTime(long windowTime); -} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java deleted file mode 100644 index eb8c4988388..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/ProducerInvocationMetric.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ProducerInvocationMetric extends InvocationMetric { - private final long waitInQueue; - - private final TimerMetric lifeTimeInQueue; - - private final TimerMetric executionTime; - - private final TimerMetric producerLatency; - - private final CallMetric producerCall; - - public long getWaitInQueue() { - return waitInQueue; - } - - public TimerMetric getLifeTimeInQueue() { - return lifeTimeInQueue; - } - - public TimerMetric getExecutionTime() { - return executionTime; - } - - public TimerMetric getProducerLatency() { - return producerLatency; - } - - public CallMetric getProducerCall() { - return producerCall; - } - - public ProducerInvocationMetric(@JsonProperty("operationName") String operationName, - @JsonProperty("prefix") String prefix, - @JsonProperty("waitInQueue") long waitInQueue, - @JsonProperty("lifeTimeInQueue") TimerMetric lifeTimeInQueue, - @JsonProperty("executionTime") TimerMetric executionTime, - @JsonProperty("producerLatency") TimerMetric producerLatency, - @JsonProperty("producerCall") CallMetric producerCall) { - super(operationName, prefix); - this.waitInQueue = waitInQueue; - this.lifeTimeInQueue = lifeTimeInQueue; - this.executionTime = executionTime; - this.producerLatency = producerLatency; - this.producerCall = producerCall; - } - - public ProducerInvocationMetric merge(ProducerInvocationMetric metric) { - return new ProducerInvocationMetric(this.getOperationName(), this.getPrefix(), - this.getWaitInQueue() + metric.getWaitInQueue(), - lifeTimeInQueue.merge(metric.getLifeTimeInQueue()), - executionTime.merge(metric.getExecutionTime()), - producerLatency.merge(metric.getProducerLatency()), - producerCall.merge(metric.getProducerCall())); - } - - public Map toMap() { - Map metrics = new HashMap<>(); - metrics.put(getPrefix() + ".waitInQueue.count", getWaitInQueue()); - metrics.putAll(lifeTimeInQueue.toMap()); - metrics.putAll(executionTime.toMap()); - metrics.putAll(producerLatency.toMap()); - metrics.putAll(producerCall.toMap()); - return metrics; - } -} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java deleted file mode 100644 index b9a919edf71..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/RegistryMetric.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class RegistryMetric { - private final InstanceMetric instanceMetric; - - private final Map consumerMetrics; - - private final Map producerMetrics; - - public InstanceMetric getInstanceMetric() { - return instanceMetric; - } - - public Map getConsumerMetrics() { - return consumerMetrics; - } - - public Map getProducerMetrics() { - return producerMetrics; - } - - public RegistryMetric(@JsonProperty("instanceMetric") InstanceMetric instanceMetric, - @JsonProperty("consumerMetrics") Map consumerMetrics, - @JsonProperty("producerMetrics") Map producerMetrics) { - this.consumerMetrics = consumerMetrics; - this.producerMetrics = producerMetrics; - this.instanceMetric = instanceMetric; - } - - public RegistryMetric(SystemMetric systemMetric, - Map consumerMetrics, - Map producerMetrics) { - this.consumerMetrics = consumerMetrics; - this.producerMetrics = producerMetrics; - - ConsumerInvocationMetric instanceConsumerInvocationMetric = new ConsumerInvocationMetric("instance", - MetricsConst.INSTANCE_CONSUMER_PREFIX, - new TimerMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerLatency"), - new CallMetric(MetricsConst.INSTANCE_CONSUMER_PREFIX + ".consumerCall")); - ProducerInvocationMetric instanceProducerInvocationMetric = new ProducerInvocationMetric("instance", - MetricsConst.INSTANCE_PRODUCER_PREFIX, 0, - new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".lifeTimeInQueue"), - new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".executionTime"), - new TimerMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerLatency"), - new CallMetric(MetricsConst.INSTANCE_PRODUCER_PREFIX + ".producerCall")); - - //sum instance level metric - for (ConsumerInvocationMetric metric : consumerMetrics.values()) { - instanceConsumerInvocationMetric = instanceConsumerInvocationMetric.merge(metric); - } - for (ProducerInvocationMetric metric : producerMetrics.values()) { - instanceProducerInvocationMetric = instanceProducerInvocationMetric.merge(metric); - } - - this.instanceMetric = new InstanceMetric(systemMetric, - instanceConsumerInvocationMetric, instanceProducerInvocationMetric); - } - - public Map toMap() { - Map metrics = new HashMap<>(instanceMetric.toMap()); - for (ConsumerInvocationMetric metric : consumerMetrics.values()) { - metrics.putAll(metric.toMap()); - } - for (ProducerInvocationMetric metric : producerMetrics.values()) { - metrics.putAll(metric.toMap()); - } - return metrics; - } -} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java deleted file mode 100644 index 001518d928d..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/SystemMetric.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class SystemMetric { - private final double cpuLoad; - - private final int cpuRunningThreads; - - private final long heapInit; - - private final long heapMax; - - private final long heapCommit; - - private final long heapUsed; - - private final long nonHeapInit; - - private final long nonHeapMax; - - private final long nonHeapCommit; - - private final long nonHeapUsed; - - public double getCpuLoad() { - return cpuLoad; - } - - public int getCpuRunningThreads() { - return cpuRunningThreads; - } - - public long getHeapInit() { - return heapInit; - } - - public long getHeapMax() { - return heapMax; - } - - public long getHeapCommit() { - return heapCommit; - } - - public long getHeapUsed() { - return heapUsed; - } - - public long getNonHeapInit() { - return nonHeapInit; - } - - public long getNonHeapMax() { - return nonHeapMax; - } - - public long getNonHeapCommit() { - return nonHeapCommit; - } - - public long getNonHeapUsed() { - return nonHeapUsed; - } - - public SystemMetric(@JsonProperty("cpuLoad") double cpuLoad, - @JsonProperty("cpuRunningThreads") int cpuRunningThreads, - @JsonProperty("heapInit") long heapInit, @JsonProperty("heapMax") long heapMax, - @JsonProperty("heapCommit") long heapCommit, @JsonProperty("heapUsed") long heapUsed, - @JsonProperty("nonHeapInit") long nonHeapInit, @JsonProperty("nonHeapMax") long nonHeapMax, - @JsonProperty("nonHeapCommit") long nonHeapCommit, @JsonProperty("nonHeapUsed") long nonHeapUsed) { - this.cpuLoad = cpuLoad; - this.cpuRunningThreads = cpuRunningThreads; - this.heapInit = heapInit; - this.heapMax = heapMax; - this.heapCommit = heapCommit; - this.heapUsed = heapUsed; - this.nonHeapInit = nonHeapInit; - this.nonHeapMax = nonHeapMax; - this.nonHeapCommit = nonHeapCommit; - this.nonHeapUsed = nonHeapUsed; - } - - public Map toMap() { - String prefix = "servicecomb.instance.system"; - Map metrics = new HashMap<>(); - metrics.put(prefix + ".cpu.load", cpuLoad); - metrics.put(prefix + ".cpu.runningThreads", cpuRunningThreads); - metrics.put(prefix + ".heap.init", heapInit); - metrics.put(prefix + ".heap.max", heapMax); - metrics.put(prefix + ".heap.commit", heapCommit); - metrics.put(prefix + ".heap.used", heapUsed); - metrics.put(prefix + ".nonHeap.init", nonHeapInit); - metrics.put(prefix + ".nonHeap.max", nonHeapMax); - metrics.put(prefix + ".nonHeap.commit", nonHeapCommit); - metrics.put(prefix + ".nonHeap.used", nonHeapUsed); - return metrics; - } -} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java deleted file mode 100644 index 01f3b70f342..00000000000 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/TimerMetric.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class TimerMetric { - private final String prefix; - - private final long total; - - private final long count; - - private final double average; - - private final long min; - - private final long max; - - public long getTotal() { - return total; - } - - public long getCount() { - return count; - } - - public double getAverage() { - return average; - } - - public long getMin() { - return min; - } - - public long getMax() { - return max; - } - - public TimerMetric(String prefix) { - this(prefix, 0, 0, 0, 0); - } - - public TimerMetric(@JsonProperty("prefix") String prefix, - @JsonProperty("total") long total, @JsonProperty("count") long count, - @JsonProperty("min") long min, @JsonProperty("max") long max) { - this.prefix = prefix; - this.total = total; - this.count = count; - if (count != 0) { - this.average = total / (double) count; - } else { - this.average = 0; - } - this.min = min; - this.max = max; - } - - public TimerMetric merge(TimerMetric metric) { - return new TimerMetric(this.prefix, this.total + metric.total, this.count + metric.count, - getMin(this.min, metric.min), getMax(this.max, metric.max)); - } - - private long getMin(long value1, long value2) { - return value1 == 0 || (value2 != 0 && value2 < value1) ? value2 : value1; - } - - private long getMax(long value1, long value2) { - return value2 > value1 ? value2 : value1; - } - - public Map toMap() { - Map metrics = new HashMap<>(); - metrics.put(prefix + ".total", total); - metrics.put(prefix + ".count", count); - metrics.put(prefix + ".average", average); - metrics.put(prefix + ".max", max); - metrics.put(prefix + ".min", min); - return metrics; - } -} diff --git a/metrics/metrics-core/pom.xml b/metrics/metrics-core/pom.xml index b59b07f7bae..6916c78fe8f 100644 --- a/metrics/metrics-core/pom.xml +++ b/metrics/metrics-core/pom.xml @@ -36,7 +36,7 @@ org.apache.servicecomb - metrics-common + foundation-metrics org.apache.servicecomb 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 cbf6455d857..b903f158fca 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,6 +19,4 @@ 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/MetricsDataSource.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsDataSource.java new file mode 100644 index 00000000000..3854456aa18 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsDataSource.java @@ -0,0 +1,137 @@ +/* + * 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 static javax.ws.rs.core.Response.Status.BAD_REQUEST; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; +import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor; +import org.apache.servicecomb.swagger.invocation.exception.InvocationException; + +import com.google.common.collect.Lists; +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.servo.util.Strings; + +public class MetricsDataSource { + private RegistryMonitor registryMonitor; + + private Map appliedWindowTimes = new HashMap<>(); + + private static final MetricsDataSource INSTANCE = new MetricsDataSource(); + + public static MetricsDataSource getInstance() { + return INSTANCE; + } + + private MetricsDataSource() { + this.init(RegistryMonitor.getInstance(), DynamicPropertyFactory + .getInstance().getStringProperty(MetricsConfig.METRICS_POLLING_TIME, "5000").get()); + } + + public MetricsDataSource(RegistryMonitor registryMonitor, String pollingSettings) { + this.init(registryMonitor, pollingSettings); + } + + private void init(RegistryMonitor registryMonitor, String pollingSettings) { + this.registryMonitor = registryMonitor; + + String[] pollingSettingStrings = pollingSettings.split(","); + Set parsePollingSettings = new HashSet<>(); + for (String singlePollingSetting : pollingSettingStrings) { + try { + long settingValue = Long.parseLong(singlePollingSetting); + if (settingValue > 0) { + parsePollingSettings.add(settingValue); + } else { + throw new ServiceCombException( + "bad format servicecomb.metrics.window_time : " + String.valueOf(settingValue)); + } + } catch (NumberFormatException e) { + throw new ServiceCombException("bad format servicecomb.metrics.window_time", e); + } + } + + List sortedPollingSettings = Lists.newArrayList(parsePollingSettings); + System.getProperties().setProperty("servo.pollers", Strings.join(",", sortedPollingSettings.iterator())); + for (int i = 0; i < sortedPollingSettings.size(); i++) { + this.appliedWindowTimes.put(sortedPollingSettings.get(i), i); + } + } + + + /** What's the WindowTime ? + We all know there are two major type of metric : + 1.Time-unrelated,you can get the latest value any time immediately: + Counter -> increase or decrease + Guage -> set a certain one value + 2.Time-related,only after a centain time pass you can compute the right value,"a centain time" called WindowTime + Max & Min -> the max value or min value in a centain time + Average -> average value, the simplest algorithm is f = sum / count + Rate -> like TPS,algorithm is f = sum / second + + Will be return "servicecomb.metrics.window_time" setting in microservice.yaml + */ + public List getAppliedWindowTime() { + return Lists.newArrayList(appliedWindowTimes.keySet()); + } + + //same as call measure(getAppliedWindowTime().get(0),false) + public Map measure() { + return measure(getAppliedWindowTime().get(0)); + } + + //same as call measure(windowTime,false) + public Map measure(long windowTime) { + return measure(windowTime, false); + } + + /** + * windowTime usage example: + * if there is two window time set in "servicecomb.metrics.window_time" like 1000,2000 + * then windowTime = 1000 will return result of the setting 1000(1 second) + * windowTime = 2000 will return result of the setting 2000(2 second) + * + * there are three monitor of max,min,total + * 0----------1----------2----------3---------- <-time line (second) + * 100,200 300,400 <-value record + * + * ↑ measure(1000) will return max=200 min=100 total=300 + * measure(2000) will return max=0 min=0 total=0 + * ↑ measure(1000) will return max=300 min=400 total=700 + * measure(2000) will return max=400 min=100 total=1000 + * + * @param windowTime getAppliedWindowTime() item + * @param calculateLatency need output latency + * @return Map + */ + public Map measure(long windowTime, boolean calculateLatency) { + Integer index = appliedWindowTimes.get(windowTime); + if (index != null) { + return registryMonitor.measure(index, calculateLatency); + } + throw new InvocationException(BAD_REQUEST, + "windowTime : " + windowTime + " unset in servicecomb.metrics.window_time,current available are : " + + Strings.join(",", getAppliedWindowTime().iterator())); + } +} 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 deleted file mode 100644 index 6dc6df4f442..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/DefaultEventListenerManager.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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; - -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, 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, convertorFactory.getConvertor(outputLevel))); - } - - @Override - public void registerEventListener(EventListener listener) { - EventUtils.registerEventListener(listener); - } -} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/EventListenerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/EventListenerManager.java index a381b47d381..da4af45f2b9 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/EventListenerManager.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/EventListenerManager.java @@ -18,7 +18,17 @@ 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.core.monitor.RegistryMonitor; -public interface EventListenerManager { - void registerEventListener(EventListener listener); +public class EventListenerManager { + public EventListenerManager(RegistryMonitor registryMonitor) { + this.registerEventListener(new InvocationStartedEventListener(registryMonitor)); + this.registerEventListener(new InvocationStartProcessingEventListener(registryMonitor)); + this.registerEventListener(new InvocationFinishedEventListener(registryMonitor)); + } + + public void registerEventListener(EventListener listener) { + EventUtils.registerEventListener(listener); + } } 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 5b886b6f099..948b6317560 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,8 +20,6 @@ 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; @@ -30,11 +28,8 @@ public class InvocationFinishedEventListener implements EventListener { private final RegistryMonitor registryMonitor; - private final StatusConvertor convertor; - - public InvocationFinishedEventListener(RegistryMonitor registryMonitor, StatusConvertor convertor) { + public InvocationFinishedEventListener(RegistryMonitor registryMonitor) { this.registryMonitor = registryMonitor; - this.convertor = convertor; } @Override @@ -45,16 +40,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); + monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime(), String.valueOf(event.getStatusCode())); + monitor.getExecutionTime().update(event.getProcessElapsedNanoTime(), String.valueOf(event.getStatusCode())); + monitor.getProducerLatency().update(event.getTotalElapsedNanoTime(), String.valueOf(event.getStatusCode())); + monitor.getProducerCall().increment(String.valueOf(event.getStatusCode())); } else { ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName()); - monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime()); - monitor.getConsumerCall().increment(MetricsDimension.DIMENSION_STATUS, statusDimensionValue); + monitor.getConsumerLatency().update(event.getTotalElapsedNanoTime(), String.valueOf(event.getStatusCode())); + monitor.getConsumerCall().increment(String.valueOf(event.getStatusCode())); } } } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java index 3d83b2c0d08..771810d8b82 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/InvocationStartProcessingEventListener.java @@ -43,7 +43,6 @@ public void process(Event data) { if (InvocationType.PRODUCER.equals(event.getInvocationType())) { ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName()); monitor.getWaitInQueue().increment(-1); - monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime()); } } } 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 c13d17327c4..68defae9922 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,8 +20,6 @@ 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; import org.apache.servicecomb.swagger.invocation.InvocationType; @@ -45,10 +43,6 @@ public void process(Event data) { if (InvocationType.PRODUCER.equals(event.getInvocationType())) { ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName()); monitor.getWaitInQueue().increment(); - monitor.getProducerCall().increment(MetricsDimension.DIMENSION_STATUS, MetricsDimension.DIMENSION_STATUS_ALL); - } else { - ConsumerInvocationMonitor monitor = registryMonitor.getConsumerInvocationMonitor(event.getOperationName()); - 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 deleted file mode 100644 index 92b99d0bca2..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeGroupStatusConvertor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 deleted file mode 100644 index b01f5da674b..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/CodeStatusConvertor.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 deleted file mode 100644 index 17023b66737..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertor.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 deleted file mode 100644 index 369cda4eaf6..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/StatusConvertorFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 deleted file mode 100644 index c2cf9984be1..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/event/dimension/SuccessFailedStatusConvertor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultHealthCheckExtraData.java similarity index 97% rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java rename to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultHealthCheckExtraData.java index 00f7736e911..8a78fd19d9f 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/DefaultHealthCheckExtraData.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultHealthCheckExtraData.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.common; +package org.apache.servicecomb.metrics.core.health; public class DefaultHealthCheckExtraData { private String instanceId; diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java index 301bf157b5f..03e2913f01c 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java @@ -20,18 +20,15 @@ import javax.ws.rs.core.Response.Status; import org.apache.servicecomb.foundation.common.utils.JsonUtils; -import org.apache.servicecomb.metrics.common.DefaultHealthCheckExtraData; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckResult; +import org.apache.servicecomb.foundation.metrics.health.HealthChecker; import org.apache.servicecomb.serviceregistry.RegistryUtils; import org.apache.servicecomb.serviceregistry.api.registry.Microservice; import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -@Component public class DefaultMicroserviceHealthChecker implements HealthChecker { private static Logger logger = LoggerFactory.getLogger(DefaultMicroserviceHealthChecker.class); 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 2e61440c208..93a39039b12 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,79 +17,76 @@ package org.apache.servicecomb.metrics.core.monitor; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; 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.foundation.metrics.MetricsConst; import org.apache.servicecomb.metrics.core.utils.MonitorUtils; import com.netflix.servo.monitor.BasicCounter; import com.netflix.servo.monitor.MonitorConfig; import com.netflix.servo.monitor.StepCounter; +import com.netflix.servo.tag.Tags; public class CallMonitor { - private final String prefix; + private final Map statusCounters; - private final Map> dimensionCounters; + private final String operation; - public CallMonitor(String prefix) { - this.prefix = prefix; - this.dimensionCounters = new ConcurrentHashMapEx<>(); - this.dimensionCounters.put(MetricsDimension.DIMENSION_STATUS, new ConcurrentHashMapEx<>()); + private final String stage; + + private final String role; + + public CallMonitor(String operation, String stage, String role) { + this.operation = operation; + this.stage = stage; + this.role = role; + + this.statusCounters = new ConcurrentHashMapEx<>(); } - 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 void increment(String statusCode) { + StatusCounter counter = statusCounters + .computeIfAbsent(statusCode, d -> new StatusCounter(operation, stage, role, statusCode)); + counter.increment(); } - public CallMetric toMetric(int windowTimeIndex) { - 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()))); - } + public Map measure(int windowTimeIndex) { + Map metrics = new HashMap<>(); + for (StatusCounter counter : statusCounters.values()) { + metrics.putAll(counter.measure(windowTimeIndex)); } - - return new CallMetric(this.prefix, totalValues, tpsValues); + return metrics; } - class DimensionCounter { - private final BasicCounter total; + class StatusCounter { + private final BasicCounter totalCount; private final StepCounter tps; - public BasicCounter getTotal() { - return total; - } - - public StepCounter getTps() { - return tps; - } + public StatusCounter(String operation, String stage, String role, String statusCode) { + MonitorConfig config = MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION) + .withTag(MetricsConst.TAG_STATUS, statusCode).withTag(MetricsConst.TAG_OPERATION, operation) + .withTag(MetricsConst.TAG_STAGE, stage).withTag(MetricsConst.TAG_ROLE, role).build(); - public DimensionCounter(BasicCounter total, StepCounter tps) { - this.total = total; - this.tps = tps; + this.totalCount = new BasicCounter( + config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "totalCount"))); + this.tps = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "tps"))); } public void increment() { - total.increment(); + totalCount.increment(); tps.increment(); } + + public Map measure(int windowTimeIndex) { + Map measurements = new HashMap<>(); + measurements.put(MonitorUtils.getMonitorName(this.totalCount.getConfig()), + this.totalCount.getValue(windowTimeIndex).doubleValue()); + measurements.put(MonitorUtils.getMonitorName(this.tps.getConfig()), + this.tps.getValue(windowTimeIndex).doubleValue()); + return measurements; + } } } 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 1f2f2477550..eb1819888f9 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 @@ -17,11 +17,12 @@ package org.apache.servicecomb.metrics.core.monitor; +import java.util.HashMap; +import java.util.Map; -import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric; -import org.apache.servicecomb.metrics.common.MetricsConst; +import org.apache.servicecomb.foundation.metrics.MetricsConst; -public class ConsumerInvocationMonitor extends InvocationMonitor { +public class ConsumerInvocationMonitor { private final TimerMonitor consumerLatency; private final CallMonitor consumerCall; @@ -34,14 +35,15 @@ public CallMonitor getConsumerCall() { return consumerCall; } - 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"); + public ConsumerInvocationMonitor(String operation) { + this.consumerLatency = new TimerMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_CONSUMER); + this.consumerCall = new CallMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_CONSUMER); } - public ConsumerInvocationMetric toMetric(int windowTimeIndex) { - return new ConsumerInvocationMetric(this.getOperationName(), this.getPrefix(), - consumerLatency.toMetric(windowTimeIndex), consumerCall.toMetric(windowTimeIndex)); + public Map measure(int windowTimeIndex, boolean calculateLatency) { + Map measurements = new HashMap<>(); + measurements.putAll(consumerCall.measure(windowTimeIndex)); + measurements.putAll(consumerLatency.measure(windowTimeIndex, calculateLatency)); + return measurements; } } 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 5977521327a..e38a143dfb4 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 @@ -21,8 +21,10 @@ import java.lang.management.MemoryMXBean; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadMXBean; +import java.util.HashMap; +import java.util.Map; -import org.apache.servicecomb.metrics.common.SystemMetric; +import org.apache.servicecomb.foundation.metrics.MetricsConst; import org.springframework.stereotype.Component; @Component @@ -97,8 +99,28 @@ public long getNonHeapUsed() { } @Override - public SystemMetric toMetric() { - return new SystemMetric(getCpuLoad(), getCpuRunningThreads(), getHeapInit(), getHeapMax(), getHeapCommit(), - getHeapUsed(), getNonHeapInit(), getNonHeapMax(), getNonHeapCommit(), getNonHeapUsed()); + public Map measure() { + Map measurements = new HashMap<>(); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "cpuLoad"), getCpuLoad()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "cpuRunningThreads"), (double) getCpuRunningThreads()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "heapInit"), (double) getHeapInit()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "heapMax"), (double) getHeapMax()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "heapCommit"), (double) getHeapCommit()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "heapUsed"), (double) getHeapUsed()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "nonHeapInit"), (double) getNonHeapInit()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "nonHeapMax"), (double) getNonHeapMax()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "nonHeapCommit"), (double) getNonHeapCommit()); + measurements.put(String.format(MetricsConst.JVM + "(%s=%s,%s=%s)", MetricsConst.TAG_STATISTIC, "gauge", + MetricsConst.TAG_NAME, "nonHeapUsed"), (double) getNonHeapUsed()); + return measurements; } } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java deleted file mode 100644 index 229aa221b2d..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/InvocationMonitor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.monitor; - -public class InvocationMonitor { - private final String operationName; - - private final String prefix; - - public String getOperationName() { - return operationName; - } - - public String getPrefix() { - return prefix; - } - - public InvocationMonitor(String operationName, String prefix) { - this.operationName = operationName; - this.prefix = prefix; - } -} 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 9c77ec8ced2..cb75e57fda1 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 @@ -17,13 +17,16 @@ package org.apache.servicecomb.metrics.core.monitor; -import org.apache.servicecomb.metrics.common.MetricsConst; -import org.apache.servicecomb.metrics.common.ProducerInvocationMetric; +import java.util.HashMap; +import java.util.Map; + +import org.apache.servicecomb.foundation.metrics.MetricsConst; +import org.apache.servicecomb.metrics.core.utils.MonitorUtils; import com.netflix.servo.monitor.BasicCounter; import com.netflix.servo.monitor.MonitorConfig; -public class ProducerInvocationMonitor extends InvocationMonitor { +public class ProducerInvocationMonitor { private final BasicCounter waitInQueue; private final TimerMonitor lifeTimeInQueue; @@ -54,21 +57,28 @@ public CallMonitor getProducerCall() { return producerCall; } - public ProducerInvocationMonitor(String operationName) { - super(operationName, String.format(MetricsConst.PRODUCER_PREFIX_TEMPLATE, operationName)); - this.waitInQueue = new BasicCounter(MonitorConfig.builder(this.getPrefix() + ".waitInQueue.count").build()); - 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"); + public ProducerInvocationMonitor(String operation) { + this.waitInQueue = new BasicCounter(MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION) + .withTag(MetricsConst.TAG_OPERATION, operation) + .withTag(MetricsConst.TAG_STAGE, MetricsConst.STAGE_QUEUE) + .withTag(MetricsConst.TAG_ROLE, MetricsConst.ROLE_PRODUCER) + .withTag(MetricsConst.TAG_STATISTIC, "waitInQueue") + .build()); + + this.lifeTimeInQueue = new TimerMonitor(operation, MetricsConst.STAGE_QUEUE, MetricsConst.ROLE_PRODUCER); + this.executionTime = new TimerMonitor(operation, MetricsConst.STAGE_EXECUTION, MetricsConst.ROLE_PRODUCER); + this.producerLatency = new TimerMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_PRODUCER); + this.producerCall = new CallMonitor(operation, MetricsConst.STAGE_WHOLE, MetricsConst.ROLE_PRODUCER); } - public ProducerInvocationMetric toMetric(int windowTimeIndex) { - return new ProducerInvocationMetric(this.getOperationName(), this.getPrefix(), - this.getWaitInQueue().getValue(windowTimeIndex).longValue(), - lifeTimeInQueue.toMetric(windowTimeIndex), - executionTime.toMetric(windowTimeIndex), - producerLatency.toMetric(windowTimeIndex), - producerCall.toMetric(windowTimeIndex)); + public Map measure(int windowTimeIndex, boolean calculateLatency) { + Map measurements = new HashMap<>(); + measurements.put(MonitorUtils.getMonitorName(waitInQueue.getConfig()), + waitInQueue.getValue(windowTimeIndex).doubleValue()); + measurements.putAll(lifeTimeInQueue.measure(windowTimeIndex, calculateLatency)); + measurements.putAll(executionTime.measure(windowTimeIndex, calculateLatency)); + measurements.putAll(producerLatency.measure(windowTimeIndex, calculateLatency)); + measurements.putAll(producerCall.measure(windowTimeIndex)); + return measurements; } } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java index 78be2827e6c..4607d59ba0e 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/RegistryMonitor.java @@ -21,23 +21,31 @@ import java.util.Map; import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; -import org.apache.servicecomb.metrics.common.ConsumerInvocationMetric; -import org.apache.servicecomb.metrics.common.ProducerInvocationMetric; -import org.apache.servicecomb.metrics.common.RegistryMetric; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; +import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; -@Component public class RegistryMonitor { - private final SystemMonitor systemMonitor; + private SystemMonitor systemMonitor; - private final Map consumerInvocationMonitors; + private Map consumerInvocationMonitors; - private final Map producerInvocationMonitors; + private Map producerInvocationMonitors; + + private static final RegistryMonitor INSTANCE = new RegistryMonitor(); + + public static RegistryMonitor getInstance() { + return INSTANCE; + } + + private RegistryMonitor() { + init(SPIServiceUtils.getTargetService(SystemMonitor.class)); + } - @Autowired public RegistryMonitor(SystemMonitor systemMonitor) { + init(systemMonitor); + } + + private void init(SystemMonitor systemMonitor) { this.systemMonitor = systemMonitor; this.consumerInvocationMonitors = new ConcurrentHashMapEx<>(); this.producerInvocationMonitors = new ConcurrentHashMapEx<>(); @@ -51,16 +59,14 @@ public ProducerInvocationMonitor getProducerInvocationMonitor(String operationNa return producerInvocationMonitors.computeIfAbsent(operationName, i -> new ProducerInvocationMonitor(operationName)); } - public RegistryMetric toRegistryMetric(int windowTimeIndex) { - Map consumerInvocationMetrics = new HashMap<>(); + public Map measure(int windowTimeIndex, boolean calculateLatency) { + Map measurements = new HashMap<>(systemMonitor.measure()); for (ConsumerInvocationMonitor monitor : this.consumerInvocationMonitors.values()) { - consumerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex)); + measurements.putAll(monitor.measure(windowTimeIndex, calculateLatency)); } - Map producerInvocationMetrics = new HashMap<>(); for (ProducerInvocationMonitor monitor : this.producerInvocationMonitors.values()) { - producerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex)); + measurements.putAll(monitor.measure(windowTimeIndex, calculateLatency)); } - - return new RegistryMetric(systemMonitor.toMetric(), consumerInvocationMetrics, producerInvocationMetrics); + return measurements; } } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java index 43bc165f035..098d6852c25 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/SystemMonitor.java @@ -17,7 +17,7 @@ package org.apache.servicecomb.metrics.core.monitor; -import org.apache.servicecomb.metrics.common.SystemMetric; +import java.util.Map; public interface SystemMonitor { double getCpuLoad(); @@ -40,5 +40,5 @@ public interface SystemMonitor { long getNonHeapUsed(); - SystemMetric toMetric(); + Map measure(); } 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 a88a604557f..6c63bfe28ed 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,50 +17,92 @@ package org.apache.servicecomb.metrics.core.monitor; -import org.apache.servicecomb.metrics.common.TimerMetric; +import java.util.HashMap; +import java.util.Map; + +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.apache.servicecomb.foundation.metrics.MetricsConst; import org.apache.servicecomb.metrics.core.utils.MonitorUtils; import com.netflix.servo.monitor.MaxGauge; -import com.netflix.servo.monitor.MinGauge; import com.netflix.servo.monitor.MonitorConfig; import com.netflix.servo.monitor.StepCounter; +import com.netflix.servo.tag.Tags; public class TimerMonitor { - private final String prefix; + private final Map statusCounters; - //nanosecond sum - private final StepCounter total; + private final String operation; - private final StepCounter count; + private final String stage; - //nanosecond min - private final MinGauge min; + private final String role; - //nanosecond max - private final MaxGauge max; + public TimerMonitor(String operation, String stage, String role) { + this.operation = operation; + this.stage = stage; + this.role = role; - public void update(long value) { - if (value > 0) { - total.increment(value); - count.increment(); - max.update(value); - min.update(value); - } + this.statusCounters = new ConcurrentHashMapEx<>(); + } + + public void update(long value, String statusCode) { + StatusCounter counter = statusCounters + .computeIfAbsent(statusCode, d -> new StatusCounter(operation, stage, role, statusCode)); + counter.update(value); } - public TimerMonitor(String prefix) { - this.prefix = prefix; - total = new StepCounter(MonitorConfig.builder(prefix + ".total").build()); - count = new StepCounter(MonitorConfig.builder(prefix + ".count").build()); - min = new MinGauge(MonitorConfig.builder(prefix + ".min").build()); - max = new MaxGauge(MonitorConfig.builder(prefix + ".max").build()); + public Map measure(int windowTimeIndex, boolean calculateLatency) { + Map measurements = new HashMap<>(); + for (StatusCounter counter : statusCounters.values()) { + measurements.putAll(counter.measure(windowTimeIndex, calculateLatency)); + } + return measurements; } - public TimerMetric toMetric(int windowTimeIndex) { - return new TimerMetric(this.prefix, - 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)))); + class StatusCounter { + //nanosecond sum + private final StepCounter totalTime; + + private final StepCounter count; + + //nanosecond max + private final MaxGauge max; + + private final MonitorConfig latency; + + public StatusCounter(String operation, String stage, String role, String statusCode) { + MonitorConfig config = MonitorConfig.builder(MetricsConst.SERVICECOMB_INVOCATION) + .withTag(MetricsConst.TAG_STATUS, statusCode).withTag(MetricsConst.TAG_OPERATION, operation) + .withTag(MetricsConst.TAG_STAGE, stage).withTag(MetricsConst.TAG_ROLE, role).build(); + + this.latency = config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "latency")); + this.totalTime = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "totalTime"))); + this.count = new StepCounter(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "count"))); + this.max = new MaxGauge(config.withAdditionalTag(Tags.newTag(MetricsConst.TAG_STATISTIC, "max"))); + } + + public void update(long value) { + if (value > 0) { + totalTime.increment(value); + count.increment(); + max.update(value); + } + } + + public Map measure(int windowTimeIndex, boolean calculateLatency) { + Map measurements = new HashMap<>(); + double totalTime = (double) MonitorUtils.convertNanosecondToMillisecond( + MonitorUtils.adjustValue(this.totalTime.getCount(windowTimeIndex))); + double count = (double) MonitorUtils.adjustValue(this.count.getCount(windowTimeIndex)); + measurements.put(MonitorUtils.getMonitorName(this.totalTime.getConfig()), totalTime); + measurements.put(MonitorUtils.getMonitorName(this.count.getConfig()), count); + measurements.put(MonitorUtils.getMonitorName(this.max.getConfig()), (double) MonitorUtils + .convertNanosecondToMillisecond(MonitorUtils.adjustValue(this.max.getValue(windowTimeIndex)))); + if (calculateLatency) { + measurements.put(MonitorUtils.getMonitorName(latency), totalTime / count); + } + return measurements; + } } } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java deleted file mode 100644 index 0f5d889333f..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DataSource.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.metrics.core.publish; - -import java.util.List; - -import org.apache.servicecomb.metrics.common.RegistryMetric; - -public interface DataSource { - - /** What's the WindowTime ? - We all know there are two major type of metric : - 1.Time-unrelated,you can get the latest value any time immediately: - Counter -> increase or decrease - Guage -> set a certain one value - 2.Time-related,only after a centain time pass you can compute the right value,"a centain time" called WindowTime - Max & Min -> the max value or min value in a centain time - Average -> average value, the simplest algorithm is f = sum / count - Rate -> like TPS,algorithm is f = sum / second - - Will be return "servicecomb.metrics.window_time" setting in microservice.yaml - */ - List getAppliedWindowTime(); - - //same as getRegistryMetric({first setting windowTime}) - RegistryMetric getRegistryMetric(); - - /** - * windowTime usage example: - * if there is two window time set in "servicecomb.metrics.window_time" like 1000,2000 - * then windowTime = 1000 will return result of the setting 1000(1 second) - * windowTime = 2000 will return result of the setting 2000(2 second) - * - * there are three monitor of max,min,total - * 0----------1----------2----------3---------- <-time line (second) - * 100,200 300,400 <-value record - * - * ↑ getRegistryMetric(1000) will return max=200 min=100 total=300 - * getRegistryMetric(2000) will return max=0 min=0 total=0 - * ↑ getRegistryMetric(1000) will return max=300 min=400 total=700 - * getRegistryMetric(2000) will return max=400 min=100 total=1000 - * - * @param windowTime getAppliedWindowTime() item - * @return RegistryMetric - */ - RegistryMetric getRegistryMetric(long windowTime); -} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java deleted file mode 100644 index 6bb3357ce68..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultDataSource.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.metrics.core.publish; - -import static javax.ws.rs.core.Response.Status.BAD_REQUEST; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; -import org.apache.servicecomb.metrics.common.RegistryMetric; -import org.apache.servicecomb.metrics.core.MetricsConfig; -import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor; -import org.apache.servicecomb.swagger.invocation.exception.InvocationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.servo.monitor.Pollers; -import com.netflix.servo.util.Strings; - -@Component -public class DefaultDataSource implements DataSource { - private final RegistryMonitor registryMonitor; - - private final Map appliedWindowTimes = new HashMap<>(); - - @Autowired - public DefaultDataSource(RegistryMonitor registryMonitor) { - this(registryMonitor, - DynamicPropertyFactory.getInstance().getStringProperty(MetricsConfig.METRICS_POLLING_TIME, "5000").get()); - } - - public DefaultDataSource(RegistryMonitor registryMonitor, String pollingSettings) { - this.registryMonitor = registryMonitor; - - String[] singlePollingSettings = pollingSettings.split(","); - Set parsePollingSettings = new HashSet<>(); - for (String singlePollingSetting : singlePollingSettings) { - try { - long settingValue = Long.parseLong(singlePollingSetting); - if (settingValue > 0) { - parsePollingSettings.add(settingValue); - } else { - throw new ServiceCombException( - "bad format servicecomb.metrics.window_time : " + String.valueOf(settingValue)); - } - } catch (NumberFormatException e) { - throw new ServiceCombException("bad format servicecomb.metrics.window_time", e); - } - } - String finalPollingSettings = Strings.join(",", parsePollingSettings.iterator()); - System.getProperties().setProperty("servo.pollers", finalPollingSettings); - List appliedWindowTimes = getAppliedWindowTime(); - for (int i = 0; i < appliedWindowTimes.size(); i++) { - this.appliedWindowTimes.put(appliedWindowTimes.get(i), i); - } - } - - @Override - public RegistryMetric getRegistryMetric() { - return getRegistryMetric(getAppliedWindowTime().get(0)); - } - - @Override - public RegistryMetric getRegistryMetric(long windowTime) { - Integer index = appliedWindowTimes.get(windowTime); - if (index != null) { - return registryMonitor.toRegistryMetric(index); - } - throw new InvocationException(BAD_REQUEST, - "windowTime : " + windowTime + " unset in servicecomb.metrics.window_time,current available are : " + - Strings.join(",", getAppliedWindowTime().iterator())); - } - - @Override - public List getAppliedWindowTime() { - return Pollers.getPollingIntervals(); - } -} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java deleted file mode 100644 index 7bcc5fea102..00000000000 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerManager.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.metrics.core.publish; - -import java.util.Map; - -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; - -public interface HealthCheckerManager { - void register(HealthChecker checker); - - Map check(); - - HealthCheckResult check(String name); -} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java similarity index 66% rename from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java rename to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java index 5ef5f9c6e02..792eb36b9d6 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/HealthCheckerPublisher.java @@ -17,10 +17,14 @@ package org.apache.servicecomb.metrics.core.publish; +import java.util.List; import java.util.Map; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthCheckerPublisher; +import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckResult; +import org.apache.servicecomb.foundation.metrics.health.HealthChecker; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckerManager; +import org.apache.servicecomb.metrics.core.health.DefaultMicroserviceHealthChecker; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; @@ -32,17 +36,30 @@ @RestSchema(schemaId = "healthEndpoint") @RequestMapping(path = "/health") -public class DefaultHealthCheckerPublisher implements HealthCheckerPublisher { +public class HealthCheckerPublisher { - private final HealthCheckerManager manager; + private HealthCheckerManager manager; - public DefaultHealthCheckerPublisher(HealthCheckerManager manager) { + public HealthCheckerPublisher() { + init(new HealthCheckerManager()); + } + + public HealthCheckerPublisher(HealthCheckerManager manager) { + init(manager); + } + + private void init(HealthCheckerManager manager) { this.manager = manager; + + this.manager.register(new DefaultMicroserviceHealthChecker()); + List checkers = SPIServiceUtils.getAllService(HealthChecker.class); + for (HealthChecker checker : checkers) { + this.manager.register(checker); + } } @RequestMapping(path = "/", method = RequestMethod.GET) @CrossOrigin - @Override public Map health() { return manager.check(); } @@ -52,7 +69,6 @@ public Map health() { }) @RequestMapping(path = "/{name}", method = RequestMethod.GET) @CrossOrigin - @Override public HealthCheckResult healthWithName(@PathVariable(name = "name") String name) { return manager.check(name); } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java similarity index 60% rename from metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java rename to metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java index fc7e3978129..1369323a95e 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultMetricsPublisher.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/MetricsPublisher.java @@ -17,13 +17,13 @@ package org.apache.servicecomb.metrics.core.publish; -import java.util.List; +import java.util.Map; -import org.apache.servicecomb.metrics.common.MetricsPublisher; -import org.apache.servicecomb.metrics.common.RegistryMetric; +import org.apache.servicecomb.metrics.core.MetricsDataSource; +import org.apache.servicecomb.metrics.core.event.EventListenerManager; +import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -32,35 +32,18 @@ @RestSchema(schemaId = "metricsEndpoint") @RequestMapping(path = "/metrics") -public class DefaultMetricsPublisher implements MetricsPublisher { +public class MetricsPublisher { - private final DataSource dataSource; - - public DefaultMetricsPublisher(DataSource dataSource) { - this.dataSource = dataSource; - } - - @RequestMapping(path = "/appliedWindowTime", method = RequestMethod.GET) - @CrossOrigin - @Override - public List getAppliedWindowTime() { - return dataSource.getAppliedWindowTime(); - } - - @RequestMapping(path = "/", method = RequestMethod.GET) - @CrossOrigin - @Override - public RegistryMetric metrics() { - return dataSource.getRegistryMetric(); + public MetricsPublisher() { + new EventListenerManager(RegistryMonitor.getInstance()); } @ApiResponses({ @ApiResponse(code = 400, response = String.class, message = "illegal request content"), }) - @RequestMapping(path = "/{windowTime}", method = RequestMethod.GET) + @RequestMapping(path = "/", method = RequestMethod.GET) @CrossOrigin - @Override - public RegistryMetric metricsWithWindowTime(@PathVariable(name = "windowTime") long windowTime) { - return dataSource.getRegistryMetric(windowTime); + public Map metrics() { + return MetricsDataSource.getInstance().measure(); } } 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 index 20bfe4e7a71..26183db848b 100644 --- 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 @@ -17,24 +17,14 @@ 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.monitor.MonitorConfig; 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 @@ -42,29 +32,22 @@ 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); } + + public static String getMonitorName(MonitorConfig config) { + TagList tags = config.getTags(); + StringBuilder tagPart = new StringBuilder("("); + for (Tag tag : tags) { + if (!"type".equals(tag.getKey())) { + tagPart.append(String.format("%s=%s,", tag.getKey(), tag.getValue())); + } + } + tagPart.deleteCharAt(tagPart.length() - 1); + tagPart.append(")"); + return config.getName() + tagPart.toString(); + } } diff --git a/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.metrics.core.monitor.SystemMonitor b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.metrics.core.monitor.SystemMonitor new file mode 100644 index 00000000000..792668d3790 --- /dev/null +++ b/metrics/metrics-core/src/main/resources/META-INF/services/org.apache.servicecomb.metrics.core.monitor.SystemMonitor @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor \ No newline at end of file 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 85cf4634303..00e02fd99ef 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,13 +33,12 @@ 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.foundation.metrics.MetricsConst; +import org.apache.servicecomb.foundation.metrics.publish.MetricNode; +import org.apache.servicecomb.foundation.metrics.publish.MetricsLoader; +import org.apache.servicecomb.metrics.core.event.EventListenerManager; 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; @@ -69,255 +68,143 @@ public void test() throws InterruptedException { DefaultSystemMonitor systemMonitor = new DefaultSystemMonitor(systemMXBean, threadMXBean, memoryMXBean); RegistryMonitor monitor = new RegistryMonitor(systemMonitor); - DefaultDataSource dataSource = new DefaultDataSource(monitor, "1000,2000,3000"); + MetricsDataSource dataSource = new MetricsDataSource(monitor, "1000,2000,4000"); List intervals = dataSource.getAppliedWindowTime(); Assert.assertEquals(intervals.size(), 3); - Assert.assertThat(intervals, containsInAnyOrder(Arrays.asList(1000L, 2000L, 3000L).toArray())); + Assert.assertThat(intervals, containsInAnyOrder(Arrays.asList(1000L, 2000L, 4000L).toArray())); - new DefaultEventListenerManager(monitor, new StatusConvertorFactory(), - MetricsDimension.DIMENSION_STATUS_OUTPUT_LEVEL_SUCCESS_FAILED); + new EventListenerManager(monitor); + //========================================================================== //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))); + new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER)); EventUtils - .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, - TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true)); + .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(100), + TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200)); EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime())); EventUtils.triggerEvent( - new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER, - TimeUnit.MILLISECONDS.toNanos(300))); + new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER)); EventUtils - .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, - TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500, false)); - - //========================================================================== + .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(300), + TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 200)); - //fun3 is a PRODUCER invocation call uncompleted - EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime())); + EventUtils.triggerEvent(new InvocationStartedEvent("fun1", InvocationType.PRODUCER, System.nanoTime())); EventUtils.triggerEvent( - 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())); + new InvocationStartProcessingEvent("fun1", InvocationType.PRODUCER)); + EventUtils + .triggerEvent(new InvocationFinishedEvent("fun1", InvocationType.PRODUCER, TimeUnit.MILLISECONDS.toNanos(300), + TimeUnit.MILLISECONDS.toNanos(400), TimeUnit.MILLISECONDS.toNanos(700), 500)); //========================================================================== - //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))); + new InvocationStartProcessingEvent("fun2", InvocationType.CONSUMER)); EventUtils - .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER, - TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200, true)); + .triggerEvent(new InvocationFinishedEvent("fun2", InvocationType.CONSUMER, TimeUnit.MILLISECONDS.toNanos(100), + TimeUnit.MILLISECONDS.toNanos(200), TimeUnit.MILLISECONDS.toNanos(300), 200)); //========================================================================== + //fun3 is a PRODUCER invocation call uncompleted + EventUtils.triggerEvent(new InvocationStartedEvent("fun3", InvocationType.PRODUCER, System.nanoTime())); + EventUtils.triggerEvent( + new InvocationStartProcessingEvent("fun3", InvocationType.PRODUCER)); - //sim lease one window time - Thread.sleep(1000); - - RegistryMetric model = dataSource.getRegistryMetric(1000); - - //check InstanceMetric - 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(500, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMax(), - 0); - Assert.assertEquals(100, model.getInstanceMetric().getProducerMetric().getLifeTimeInQueue().getMin(), - 0); - - Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getExecutionTime().getCount()); - Assert.assertEquals(600, model.getInstanceMetric().getProducerMetric().getExecutionTime().getTotal(), - 0); - Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getExecutionTime().getAverage(), - 0); - Assert.assertEquals(400, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMax(), - 0); - Assert.assertEquals(200, model.getInstanceMetric().getProducerMetric().getExecutionTime().getMin(), - 0); - - Assert.assertEquals(2, model.getInstanceMetric().getProducerMetric().getProducerLatency().getCount()); - Assert.assertEquals(1000, model.getInstanceMetric().getProducerMetric().getProducerLatency().getTotal(), - 0); - Assert.assertEquals(500, model.getInstanceMetric().getProducerMetric().getProducerLatency().getAverage(), - 0); - Assert.assertEquals(700, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMax(), - 0); - Assert.assertEquals(300, model.getInstanceMetric().getProducerMetric().getProducerLatency().getMin(), - 0); + //========================================================================== + //fun4 is a PRODUCER call only started and no processing start and finished + EventUtils.triggerEvent(new InvocationStartedEvent("fun4", InvocationType.PRODUCER, System.nanoTime())); - 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(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); + //sim at lease one window time + //increase up to 4 seconds in order to prevent low-probability test failed on ci + Thread.sleep(4000); - Assert.assertEquals(1, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getCount()); - Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getTotal(), - 0); - Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getAverage(), - 0); - Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMax(), - 0); - Assert.assertEquals(300, model.getInstanceMetric().getConsumerMetric().getConsumerLatency().getMin(), - 0); + Map metrics = dataSource.measure(4000, true); - 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); + MetricsLoader loader = new MetricsLoader(metrics); - 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); + MetricNode node = loader + .getMetricTree(MetricsConst.SERVICECOMB_INVOCATION, MetricsConst.TAG_OPERATION, MetricsConst.TAG_ROLE, + MetricsConst.TAG_STAGE); //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(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); + //fun1 + MetricNode node1_queue = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER) + .getChildrenNode(MetricsConst.STAGE_QUEUE); + Assert.assertEquals(0, node1_queue.getMatchStatisticMetricValue("waitInQueue"), 0); + MetricNode node1_queue_status = new MetricNode(node1_queue.getMetrics(), MetricsConst.TAG_STATUS); + Assert.assertEquals(300, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(2, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(400, node1_queue_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0); + Assert.assertEquals(300, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(1, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(300, node1_queue_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0); + + MetricNode node1_exec = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER) + .getChildrenNode(MetricsConst.STAGE_EXECUTION); + MetricNode node1_exec_status = new MetricNode(node1_exec.getMetrics(), MetricsConst.TAG_STATUS); + Assert.assertEquals(400, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(2, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(600, node1_exec_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0); + Assert.assertEquals(400, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(1, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(400, node1_exec_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0); + + MetricNode node1_whole = node.getChildrenNode("fun1").getChildrenNode(MetricsConst.ROLE_PRODUCER) + .getChildrenNode(MetricsConst.STAGE_WHOLE); + MetricNode node1_whole_status = new MetricNode(node1_whole.getMetrics(), MetricsConst.TAG_STATUS); + Assert.assertEquals(700, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(2, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(1000, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0); + Assert.assertEquals(700, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(1, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(700, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("totalTime"), 0); + Assert.assertEquals(0.5, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("tps"), 0); + Assert.assertEquals(2, node1_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalCount"), 0); + Assert.assertEquals(0.25, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("tps"), 0); + Assert.assertEquals(1, node1_whole_status.getChildrenNode("500").getMatchStatisticMetricValue("totalCount"), 0); //check ConsumerMetrics - //no need - 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); + //fun2 + MetricNode node2_whole = node.getChildrenNode("fun2").getChildrenNode(MetricsConst.ROLE_CONSUMER) + .getChildrenNode(MetricsConst.STAGE_WHOLE); + MetricNode node2_whole_status = new MetricNode(node2_whole.getMetrics(), MetricsConst.TAG_STATUS); + Assert.assertEquals(300, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("max"), 0); + Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("count"), 0); + Assert.assertEquals(300, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalTime"), 0); + Assert.assertEquals(0.25, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("tps"), 0); + Assert.assertEquals(1, node2_whole_status.getChildrenNode("200").getMatchStatisticMetricValue("totalCount"), 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(108, metrics.size()); + //fun3 + MetricNode node3_queue = node.getChildrenNode("fun3").getChildrenNode(MetricsConst.ROLE_PRODUCER) + .getChildrenNode(MetricsConst.STAGE_QUEUE); + Assert.assertEquals(0, node3_queue.getMatchStatisticMetricValue("waitInQueue"), 0); + + //fun4 + MetricNode node4_queue = node.getChildrenNode("fun4").getChildrenNode(MetricsConst.ROLE_PRODUCER) + .getChildrenNode(MetricsConst.STAGE_QUEUE); + Assert.assertEquals(1, node4_queue.getMatchStatisticMetricValue("waitInQueue"), 0); + + //System metrics + Assert.assertEquals(1.0, getSystemMetric(loader, "cpuLoad"), 0); + Assert.assertEquals(2, getSystemMetric(loader, "cpuRunningThreads"), 0); + Assert.assertEquals(100, getSystemMetric(loader, "heapCommit"), 0); + Assert.assertEquals(200, getSystemMetric(loader, "heapInit"), 0); + Assert.assertEquals(300, getSystemMetric(loader, "heapMax"), 0); + Assert.assertEquals(400, getSystemMetric(loader, "heapUsed"), 0); + Assert.assertEquals(500, getSystemMetric(loader, "nonHeapCommit"), 0); + Assert.assertEquals(600, getSystemMetric(loader, "nonHeapInit"), 0); + Assert.assertEquals(700, getSystemMetric(loader, "nonHeapMax"), 0); + Assert.assertEquals(800, getSystemMetric(loader, "nonHeapUsed"), 0); + } - 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); + private Double getSystemMetric(MetricsLoader loader, String name) { + return loader.getFirstMatchMetricValue(MetricsConst.JVM, MetricsConst.TAG_NAME, name); } } \ No newline at end of file diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java deleted file mode 100644 index 507ff777408..00000000000 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerManager.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.servicecomb.foundation.common.utils.JsonUtils; -import org.apache.servicecomb.metrics.common.DefaultHealthCheckExtraData; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; -import org.apache.servicecomb.metrics.core.health.DefaultMicroserviceHealthChecker; -import org.apache.servicecomb.metrics.core.publish.DefaultHealthCheckerManager; -import org.apache.servicecomb.metrics.core.publish.HealthCheckerManager; -import org.apache.servicecomb.serviceregistry.RegistryUtils; -import org.apache.servicecomb.serviceregistry.api.registry.Microservice; -import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance; -import org.junit.Assert; -import org.junit.Test; - -import com.google.common.collect.Lists; - -import mockit.Expectations; - -public class TestHealthCheckerManager { - - @Test - public void testRegistry() throws IOException { - - Microservice microservice = new Microservice(); - microservice.setAppId("appId"); - microservice.setServiceName("serviceName"); - microservice.setVersion("0.0.1"); - - MicroserviceInstance microserviceInstance = new MicroserviceInstance(); - microserviceInstance.setEndpoints(Lists.newArrayList("127.0.0.1", "192.168.0.100")); - microserviceInstance.setInstanceId("001"); - microserviceInstance.setHostName("localhost"); - - new Expectations(RegistryUtils.class) { - { - RegistryUtils.getMicroservice(); - result = microservice; - } - }; - - new Expectations(RegistryUtils.class) { - { - RegistryUtils.getMicroserviceInstance(); - result = microserviceInstance; - } - }; - - List checkers = new ArrayList<>(); - checkers.add(new DefaultMicroserviceHealthChecker()); - - HealthCheckerManager manager = new DefaultHealthCheckerManager(checkers); - - manager.register(new HealthChecker() { - @Override - public String getName() { - return "test"; - } - - @Override - public HealthCheckResult check() { - return new HealthCheckResult(false, "bad", "bad"); - } - }); - - Map results = manager.check(); - - Assert.assertEquals(true,results.get("default").isHealthy()); - - DefaultHealthCheckExtraData data = JsonUtils.OBJ_MAPPER - .readValue(results.get("default").getExtraData(), DefaultHealthCheckExtraData.class); - Assert.assertEquals("appId",data.getAppId()); - Assert.assertEquals("serviceName",data.getServiceName()); - Assert.assertEquals("0.0.1",data.getServiceVersion()); - Assert.assertEquals("001",data.getInstanceId()); - Assert.assertEquals("localhost",data.getHostName()); - Assert.assertEquals("127.0.0.1,192.168.0.100",data.getEndpoints()); - - HealthCheckResult result = manager.check("test"); - Assert.assertEquals(false,result.isHealthy()); - } -} diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java index 3fb16e65923..3585193ffc7 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestHealthCheckerPublisher.java @@ -20,37 +20,83 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.servicecomb.foundation.common.utils.JsonUtils; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthCheckerPublisher; -import org.apache.servicecomb.metrics.core.publish.DefaultHealthCheckerPublisher; -import org.apache.servicecomb.metrics.core.publish.HealthCheckerManager; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckResult; +import org.apache.servicecomb.foundation.metrics.health.HealthChecker; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckerManager; +import org.apache.servicecomb.metrics.core.health.DefaultHealthCheckExtraData; +import org.apache.servicecomb.metrics.core.health.DefaultMicroserviceHealthChecker; +import org.apache.servicecomb.metrics.core.publish.HealthCheckerPublisher; +import org.apache.servicecomb.serviceregistry.RegistryUtils; +import org.apache.servicecomb.serviceregistry.api.registry.Microservice; +import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance; import org.junit.Assert; import org.junit.Test; -import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.Lists; + +import mockit.Expectations; public class TestHealthCheckerPublisher { @Test - public void testPublisher() throws JsonProcessingException { + public void testPublisher() throws IOException { + Microservice microservice = new Microservice(); + microservice.setAppId("appId"); + microservice.setServiceName("serviceName"); + microservice.setVersion("0.0.1"); + + MicroserviceInstance microserviceInstance = new MicroserviceInstance(); + microserviceInstance.setEndpoints(Lists.newArrayList("127.0.0.1", "192.168.0.100")); + microserviceInstance.setInstanceId("001"); + microserviceInstance.setHostName("localhost"); + + new Expectations(RegistryUtils.class) { + { + RegistryUtils.getMicroservice(); + result = microservice; + } + }; + + new Expectations(RegistryUtils.class) { + { + RegistryUtils.getMicroserviceInstance(); + result = microserviceInstance; + } + }; + HealthCheckerManager manager = mock(HealthCheckerManager.class); Map results = new HashMap<>(); - HealthCheckResult result = new HealthCheckResult(true, "ok", "extra"); - results.put("default", result); + HealthChecker result = new DefaultMicroserviceHealthChecker(); + results.put("default", result.check()); when(manager.check()).thenReturn(results); - when(manager.check("default")).thenReturn(result); + when(manager.check("default")).thenReturn(result.check()); - HealthCheckerPublisher publisher = new DefaultHealthCheckerPublisher(manager); + HealthCheckerPublisher publisher = new HealthCheckerPublisher(manager); Map content = publisher.health(); - Assert.assertEquals(JsonUtils.writeValueAsString(result),JsonUtils.writeValueAsString(content.get("default"))); - HealthCheckResult checkResult = publisher.healthWithName("default"); - Assert.assertEquals(JsonUtils.writeValueAsString(result),JsonUtils.writeValueAsString(checkResult)); + DefaultHealthCheckExtraData data = JsonUtils.OBJ_MAPPER + .readValue(content.get("default").getExtraData(), DefaultHealthCheckExtraData.class); + Assert.assertEquals("appId", data.getAppId()); + Assert.assertEquals("serviceName", data.getServiceName()); + Assert.assertEquals("0.0.1", data.getServiceVersion()); + Assert.assertEquals("001", data.getInstanceId()); + Assert.assertEquals("localhost", data.getHostName()); + Assert.assertEquals("127.0.0.1,192.168.0.100", data.getEndpoints()); + + data = JsonUtils.OBJ_MAPPER + .readValue(publisher.healthWithName("default").getExtraData(), DefaultHealthCheckExtraData.class); + Assert.assertEquals("appId", data.getAppId()); + Assert.assertEquals("serviceName", data.getServiceName()); + Assert.assertEquals("0.0.1", data.getServiceVersion()); + Assert.assertEquals("001", data.getInstanceId()); + Assert.assertEquals("localhost", data.getHostName()); + Assert.assertEquals("127.0.0.1,192.168.0.100", data.getEndpoints()); } } diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java similarity index 66% rename from metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java rename to metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java index 2f3a48a9afe..48211edc3a3 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/HealthCheckerPublisher.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestMetricsPublisher.java @@ -15,12 +15,20 @@ * limitations under the License. */ -package org.apache.servicecomb.metrics.common; +package org.apache.servicecomb.metrics.core; import java.util.Map; -public interface HealthCheckerPublisher { - Map health(); +import org.apache.servicecomb.metrics.core.publish.MetricsPublisher; +import org.junit.Assert; +import org.junit.Test; - HealthCheckResult healthWithName(String name); +public class TestMetricsPublisher { + @Test + public void test() { + MetricsPublisher publisher = new MetricsPublisher(); + Map metrics = publisher.metrics(); + //10 jvm metrics get + Assert.assertEquals(10, metrics.size()); + } } 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 deleted file mode 100644 index bf380581cc8..00000000000 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 static org.hamcrest.Matchers.containsInAnyOrder; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.apache.servicecomb.metrics.common.RegistryMetric; -import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor; -import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor; -import org.apache.servicecomb.metrics.core.monitor.SystemMonitor; -import org.apache.servicecomb.metrics.core.publish.DefaultDataSource; -import org.apache.servicecomb.metrics.core.publish.DefaultMetricsPublisher; -import org.junit.Assert; -import org.junit.Test; - -public class TestPublisher { - - @Test - public void test() { - SystemMonitor systemMonitor = new DefaultSystemMonitor(); - RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor); - DefaultDataSource dataSource = new DefaultDataSource(registryMonitor, "1000,2000,3000,3000,2000,1000"); - DefaultMetricsPublisher publisher = new DefaultMetricsPublisher(dataSource); - - RegistryMetric registryMetric = publisher.metrics(); - Map metricsMap = registryMetric.toMap(); - Assert.assertEquals(31, metricsMap.size()); - - registryMetric = publisher.metricsWithWindowTime(1000); - metricsMap = registryMetric.toMap(); - Assert.assertEquals(31, metricsMap.size()); - - List appliedWindowTime = publisher.getAppliedWindowTime(); - Assert.assertEquals(3, appliedWindowTime.size()); - Assert.assertThat(appliedWindowTime, containsInAnyOrder(Arrays.asList(1000L, 2000L, 3000L).toArray())); - } -} 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 deleted file mode 100644 index 897648bb7e0..00000000000 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestStatusDimension.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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-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 932863ea152..c3bf27534f4 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,31 +20,16 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Map.Entry; -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; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; +import org.apache.servicecomb.foundation.metrics.MetricsConst; +import org.apache.servicecomb.metrics.core.MetricsDataSource; import io.prometheus.client.Collector; import io.prometheus.client.Collector.MetricFamilySamples.Sample; -@Component public class MetricsCollector extends Collector implements Collector.Describable { - private final DataSource dataSource; - - @Autowired - public MetricsCollector(DataSource dataSource) { - this.dataSource = dataSource; - } - @Override public List collect() { return load(); @@ -56,79 +41,35 @@ public List describe() { } private List load() { - RegistryMetric registryMetric = dataSource.getRegistryMetric(); + Map registryMetric = MetricsDataSource.getInstance() + .measure(MetricsDataSource.getInstance().getAppliedWindowTime().get(0), true); List familySamples = new ArrayList<>(); - 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(new MetricFamilySamples("Consumer Side", Type.UNTYPED, "Consumer Side Metrics", consumerSamples)); - } - - if (registryMetric.getProducerMetrics().size() != 0) { - List producerSamples = new ArrayList<>(); - for (ProducerInvocationMetric metric : registryMetric.getProducerMetrics().values()) { - producerSamples.addAll(convertProducerMetric(metric)); - producerSamples.addAll(convertCallMetric(metric.getProducerCall())); + List samples = new ArrayList<>(); + for (Entry metric : registryMetric.entrySet()) { + List tagNames = new ArrayList<>(); + List tagValues = new ArrayList<>(); + String name = metric.getKey(); + if (metric.getKey().contains("(")) { + String[] nameAndTag = metric.getKey().split("\\("); + name = nameAndTag[0]; + String[] tagAnValues = nameAndTag[1].split("[=,)]"); + for (int i = 0; i < tagAnValues.length; i += 2) { + //we need put operation name in metrics name,not a label + if (MetricsConst.TAG_OPERATION.equals(tagAnValues[i])) { + name = name + "." + tagAnValues[i + 1]; + } else if (!"type".equals(tagAnValues[i])) { + tagNames.add(tagAnValues[i]); + tagValues.add(tagAnValues[i + 1]); + } + } } - familySamples - .add(new MetricFamilySamples("Producer Side", Type.UNTYPED, "Producer Side Metrics", producerSamples)); + samples.add(new Sample(formatMetricName(name), tagNames, tagValues, metric.getValue())); } - + familySamples.add(new MetricFamilySamples("ServiceComb Metrics", Type.UNTYPED, "ServiceComb Metrics", samples)); return familySamples; } - 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/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsPublisher.java b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsHttpPublisher.java similarity index 86% rename from metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsPublisher.java rename to metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsHttpPublisher.java index af99b522d5b..7187467661c 100644 --- a/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsPublisher.java +++ b/metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/MetricsHttpPublisher.java @@ -23,7 +23,6 @@ import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextClosedEvent; @@ -35,21 +34,18 @@ import io.prometheus.client.exporter.HTTPServer; @Component -public class MetricsPublisher implements ApplicationListener { - private static final Logger LOGGER = LoggerFactory.getLogger(MetricsPublisher.class); +public class MetricsHttpPublisher implements ApplicationListener { + private static final Logger LOGGER = LoggerFactory.getLogger(MetricsHttpPublisher.class); private static final String METRICS_PROMETHEUS_PORT = "servicecomb.metrics.prometheus.port"; - private final MetricsCollector metricsCollector; - private HTTPServer httpServer; - @Autowired - public MetricsPublisher(MetricsCollector metricsCollector) { + public MetricsHttpPublisher() { //prometheus default port allocation is here : https://github.com/prometheus/prometheus/wiki/Default-port-allocations int publishPort = DynamicPropertyFactory.getInstance().getIntProperty(METRICS_PROMETHEUS_PORT, 9696).get(); - this.metricsCollector = metricsCollector; - this.metricsCollector.register(); + MetricsCollector metricsCollector = new MetricsCollector(); + metricsCollector.register(); try { this.httpServer = new HTTPServer(new InetSocketAddress(publishPort), CollectorRegistry.defaultRegistry, true); LOGGER.info("Prometheus httpServer listened {}.", publishPort); diff --git a/metrics/pom.xml b/metrics/pom.xml index b0b00e98ddd..990633a4857 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -32,9 +32,9 @@ Java Chassis::Metrics - metrics-common metrics-core metrics-extension metrics-integration + diff --git a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthChecker.java similarity index 76% rename from samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java rename to samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthChecker.java index 9fd3c6c34c1..bd53aa05492 100644 --- a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthCheckerAnnotation.java +++ b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/CustomHealthChecker.java @@ -17,13 +17,11 @@ package org.apache.servicecomb.samples.metrics.extendhealthcheck; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; -import org.springframework.stereotype.Component; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckResult; +import org.apache.servicecomb.foundation.metrics.health.HealthChecker; -//this health check will auto register because spring bean annotation -@Component -public class CustomHealthCheckerAnnotation implements HealthChecker { + +public class CustomHealthChecker implements HealthChecker { @Override public String getName() { return "custom"; diff --git a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java index 66d0852167b..6e11578792f 100644 --- a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java +++ b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/MySqlHealthChecker.java @@ -21,8 +21,9 @@ import java.sql.DriverManager; import java.sql.SQLException; -import org.apache.servicecomb.metrics.common.HealthCheckResult; -import org.apache.servicecomb.metrics.common.HealthChecker; +import org.apache.servicecomb.foundation.metrics.health.HealthCheckResult; +import org.apache.servicecomb.foundation.metrics.health.HealthChecker; + //this is a demo health checker for mysql public class MySqlHealthChecker implements HealthChecker { diff --git a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/SomeServiceWithHealthCheckerManager.java b/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/SomeServiceWithHealthCheckerManager.java deleted file mode 100644 index eee71299fd3..00000000000 --- a/samples/metrics-extend-healthcheck/src/main/java/org/apache/servicecomb/samples/metrics/extendhealthcheck/SomeServiceWithHealthCheckerManager.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.samples.metrics.extendhealthcheck; - -import org.apache.servicecomb.metrics.core.publish.HealthCheckerManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class SomeServiceWithHealthCheckerManager { - - private final HealthCheckerManager manager; - - @Autowired - public SomeServiceWithHealthCheckerManager(HealthCheckerManager manager) { - this.manager = manager; - - this.manager.register(new MySqlHealthChecker()); - } -} diff --git a/samples/metrics-extend-healthcheck/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.health.HealthChecker b/samples/metrics-extend-healthcheck/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.health.HealthChecker new file mode 100644 index 00000000000..f6b0794a409 --- /dev/null +++ b/samples/metrics-extend-healthcheck/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.metrics.health.HealthChecker @@ -0,0 +1,19 @@ +# +# 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. +# + +org.apache.servicecomb.samples.metrics.extendhealthcheck.CustomHealthChecker +org.apache.servicecomb.samples.metrics.extendhealthcheck.MySqlHealthChecker \ No newline at end of file diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java index b835aad6fff..dc13f9a0786 100644 --- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java +++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/FileContentConvertor.java @@ -19,9 +19,7 @@ import java.util.Map; -import org.apache.servicecomb.metrics.common.RegistryMetric; - //convert metrics to output content public interface FileContentConvertor { - Map convert(RegistryMetric registryMetric); + Map convert(Map registryMetric); } diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java index 839fe039725..aa5d909f220 100644 --- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java +++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/SimpleFileContentConvertor.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Map.Entry; -import org.apache.servicecomb.metrics.common.RegistryMetric; +import org.apache.servicecomb.foundation.metrics.MetricsConst; import com.netflix.config.DynamicPropertyFactory; @@ -41,12 +41,11 @@ public SimpleFileContentConvertor() { } @Override - public Map convert(RegistryMetric registryMetric) { + public Map convert(Map registryMetric) { Map pickedMetrics = new HashMap<>(); - for (Entry metric : registryMetric.toMap().entrySet()) { - pickedMetrics.put(metric.getKey(), - String.format(doubleStringFormatter, - round(metric.getValue().doubleValue(), doubleRoundPlaces))); + for (Entry metric : registryMetric.entrySet()) { + pickedMetrics.put(convertMetricKey(metric.getKey()), + String.format(doubleStringFormatter, round(metric.getValue(), doubleRoundPlaces))); } return pickedMetrics; } @@ -58,4 +57,26 @@ private double round(double value, int places) { } return 0; } + + private String convertMetricKey(String key) { + String[] nameAndTag = key.split("\\("); + Map tags = new HashMap<>(); + String[] tagAnValues = nameAndTag[1].split("[=,)]"); + for (int i = 0; i < tagAnValues.length; i += 2) { + tags.put(tagAnValues[i], tagAnValues[i + 1]); + } + if (nameAndTag[0].startsWith(MetricsConst.JVM)) { + return "jvm." + tags.get(MetricsConst.TAG_NAME); + } else { + StringBuilder builder = new StringBuilder(); + builder.append(tags.get(MetricsConst.TAG_OPERATION)); + builder.append("."); + builder.append(tags.get(MetricsConst.TAG_ROLE)); + builder.append("."); + builder.append(tags.get(MetricsConst.TAG_STAGE)); + builder.append("."); + builder.append(tags.get(MetricsConst.TAG_STATISTIC)); + return builder.toString(); + } + } } diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java index a2773289e53..a91ced6a416 100644 --- a/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java +++ b/samples/metrics-write-file-sample/metrics-write-file/src/main/java/org/apache/servicecomb/samples/mwf/WriteFileInitializer.java @@ -24,9 +24,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.foundation.common.net.NetUtils; -import org.apache.servicecomb.metrics.common.RegistryMetric; import org.apache.servicecomb.metrics.core.MetricsConfig; -import org.apache.servicecomb.metrics.core.publish.DataSource; +import org.apache.servicecomb.metrics.core.MetricsDataSource; import org.apache.servicecomb.serviceregistry.RegistryUtils; import org.apache.servicecomb.serviceregistry.api.registry.Microservice; import org.springframework.beans.factory.annotation.Autowired; @@ -42,8 +41,6 @@ public class WriteFileInitializer { private FileContentFormatter formatter; - private final DataSource dataSource; - private final MetricsFileWriter fileWriter; private String filePrefix; @@ -51,17 +48,15 @@ public class WriteFileInitializer { private String hostName; @Autowired - public WriteFileInitializer(MetricsFileWriter fileWriter, DataSource dataSource) { + public WriteFileInitializer(MetricsFileWriter fileWriter) { metricPoll = DynamicPropertyFactory.getInstance().getIntProperty(MetricsConfig.METRICS_POLLING_TIME, 5000).get(); this.fileWriter = fileWriter; - this.dataSource = dataSource; this.convertor = new SimpleFileContentConvertor(); } - public WriteFileInitializer(MetricsFileWriter fileWriter, DataSource dataSource, String hostName, String filePrefix) { + public WriteFileInitializer(MetricsFileWriter fileWriter, String hostName, String filePrefix) { metricPoll = DynamicPropertyFactory.getInstance().getIntProperty(MetricsConfig.METRICS_POLLING_TIME, 5000).get(); this.fileWriter = fileWriter; - this.dataSource = dataSource; this.hostName = hostName; this.filePrefix = filePrefix; this.convertor = new SimpleFileContentConvertor(); @@ -87,8 +82,9 @@ public void startOutput() { .scheduleWithFixedDelay(poller, 0, metricPoll, MILLISECONDS); } - public void run() { - RegistryMetric registryMetric = dataSource.getRegistryMetric(); + private void run() { + Map registryMetric = MetricsDataSource.getInstance() + .measure(MetricsDataSource.getInstance().getAppliedWindowTime().get(0), true); Map convertedMetrics = convertor.convert(registryMetric); Map formattedMetrics = formatter.format(convertedMetrics); 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 deleted file mode 100644 index 67f4b441635..00000000000 --- a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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.samples.mwf; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -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; -import org.apache.servicecomb.metrics.core.publish.DataSource; -import org.apache.servicecomb.serviceregistry.Features; -import org.apache.servicecomb.serviceregistry.RegistryUtils; -import org.apache.servicecomb.serviceregistry.ServiceRegistry; -import org.apache.servicecomb.serviceregistry.api.registry.Microservice; -import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance; -import org.apache.servicecomb.serviceregistry.cache.InstanceCacheManager; -import org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient; -import org.apache.servicecomb.serviceregistry.client.http.MicroserviceInstances; -import org.apache.servicecomb.serviceregistry.consumer.AppManager; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -import mockit.Expectations; - -public class TestWriteFile { - - @Test - public void test() { - - new Expectations(RegistryUtils.class) { - { - RegistryUtils.getServiceRegistry(); - result = new ServiceRegistry() { - @Override - public void init() { - - } - - @Override - public void run() { - - } - - @Override - public void destroy() { - - } - - @Override - public Set getCombinedMicroserviceNames() { - return null; - } - - @Override - public Microservice getMicroservice() { - return null; - } - - @Override - public MicroserviceInstance getMicroserviceInstance() { - return null; - } - - @Override - public ServiceRegistryClient getServiceRegistryClient() { - return null; - } - - @Override - public AppManager getAppManager() { - return null; - } - - @Override - public InstanceCacheManager getInstanceCacheManager() { - return null; - } - - @Override - public List findServiceInstance(String appId, String microserviceName, - String microserviceVersionRule) { - return null; - } - - @Override - public MicroserviceInstances findServiceInstances(String appId, String microserviceName, - String microserviceVersionRule, String revision) { - return null; - } - - @Override - public boolean updateMicroserviceProperties(Map properties) { - return false; - } - - @Override - public boolean updateInstanceProperties(Map instanceProperties) { - return false; - } - - @Override - public Microservice getRemoteMicroservice(String microserviceId) { - return null; - } - - @Override - public Features getFeatures() { - return null; - } - }; - } - }; - - StringBuilder builder = new StringBuilder(); - - 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", 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<>()); - - DataSource dataSource = Mockito.mock(DataSource.class); - Mockito.when(dataSource.getRegistryMetric()).thenReturn(metric); - - WriteFileInitializer writeFileInitializer = new WriteFileInitializer(writer, dataSource, - "localhost", "appId.serviceName"); - - writeFileInitializer.run(); - - String sb = builder.toString(); - - Assert.assertTrue(sb.contains("999.4")); - Assert.assertTrue(sb.contains("888.7")); - } -} 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 843c0fe4542..37bdcfc83f8 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 @@ -129,7 +129,7 @@ private void doRunInExecutor(InvocationStartedEvent startedEvent) throws Excepti invocation.next(response -> { sendResponse(invocation.getContext(), response); - invocation.triggerFinishedEvent(response.getStatusCode(), response.isSuccessed()); + invocation.triggerFinishedEvent(response.getStatusCode()); }); }