This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit b44106b876225f8650d167f85bb52908cbb81835 Author: zhengyangyong <[email protected]> AuthorDate: Tue Jan 16 16:35:02 2018 +0800 SCB-12 Support Custom Metrics implement Signed-off-by: zhengyangyong <[email protected]> --- .../servicecomb/metrics/common/RegistryMetric.java | 23 ++++-- .../metrics/core/custom/CounterService.java | 28 ++++++++ .../metrics/core/custom/DefaultCounterService.java | 71 +++++++++++++++++++ .../metrics/core/custom/DefaultGaugeService.java | 43 ++++++++++++ .../core/custom/DefaultWindowCounterService.java | 49 +++++++++++++ .../metrics/core/custom/GaugeService.java | 22 ++++++ .../metrics/core/custom/WindowCounter.java | 82 ++++++++++++++++++++++ .../metrics/core/custom/WindowCounterService.java | 22 ++++++ .../metrics/core/monitor/RegistryMonitor.java | 24 ++++++- .../metrics/core/TestCustomMetrics.java | 79 +++++++++++++++++++++ .../metrics/core/TestEventAndRunner.java | 6 +- .../metrics/core/TestHealthCheckerManager.java | 16 +++++ .../servicecomb/metrics/core/TestPublisher.java | 6 +- .../metrics/prometheus/MetricsCollector.java | 5 ++ samples/custom-business-metrics/pom.xml | 56 +++++++++++++++ .../metrics/custom/CustomMetricsApplication.java | 30 ++++++++ .../samples/metrics/custom/ShopDemoService.java | 70 ++++++++++++++++++ .../servicecomb/samples/mwf/TestWriteFile.java | 3 +- samples/pom.xml | 1 + 19 files changed, 624 insertions(+), 12 deletions(-) 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 index a2ac66e..d838628 100644 --- 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 @@ -23,11 +23,13 @@ import java.util.Map; import com.fasterxml.jackson.annotation.JsonProperty; public class RegistryMetric { - private InstanceMetric instanceMetric; + private final InstanceMetric instanceMetric; - private Map<String, ConsumerInvocationMetric> consumerMetrics; + private final Map<String, ConsumerInvocationMetric> consumerMetrics; - private Map<String, ProducerInvocationMetric> producerMetrics; + private final Map<String, ProducerInvocationMetric> producerMetrics; + + private final Map<String, Number> customMetrics; public InstanceMetric getInstanceMetric() { return instanceMetric; @@ -41,19 +43,27 @@ public class RegistryMetric { return producerMetrics; } + public Map<String, Number> getCustomMetrics() { + return customMetrics; + } + public RegistryMetric(@JsonProperty("instanceMetric") InstanceMetric instanceMetric, @JsonProperty("consumerMetrics") Map<String, ConsumerInvocationMetric> consumerMetrics, - @JsonProperty("producerMetrics") Map<String, ProducerInvocationMetric> producerMetrics) { + @JsonProperty("producerMetrics") Map<String, ProducerInvocationMetric> producerMetrics, + @JsonProperty("customMetrics") Map<String, Number> customMetrics) { this.consumerMetrics = consumerMetrics; this.producerMetrics = producerMetrics; this.instanceMetric = instanceMetric; + this.customMetrics = customMetrics; } public RegistryMetric(SystemMetric systemMetric, Map<String, ConsumerInvocationMetric> consumerMetrics, - Map<String, ProducerInvocationMetric> producerMetrics) { + Map<String, ProducerInvocationMetric> producerMetrics, + Map<String, Number> customMetrics) { this.consumerMetrics = consumerMetrics; this.producerMetrics = producerMetrics; + this.customMetrics = customMetrics; ConsumerInvocationMetric instanceConsumerInvocationMetric = new ConsumerInvocationMetric("instance", MetricsConst.INSTANCE_CONSUMER_PREFIX, @@ -79,8 +89,7 @@ public class RegistryMetric { } public Map<String, Number> toMap() { - Map<String, Number> metrics = new HashMap<>(); - metrics.putAll(instanceMetric.toMap()); + Map<String, Number> metrics = new HashMap<>(instanceMetric.toMap()); for (ConsumerInvocationMetric metric : consumerMetrics.values()) { metrics.putAll(metric.toMap()); } diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/CounterService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/CounterService.java new file mode 100644 index 0000000..2dc8aa1 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/CounterService.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.metrics.core.custom; + +public interface CounterService { + void increment(String name); + + void increment(String name, long value); + + void decrement(String name); + + void reset(String name); +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultCounterService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultCounterService.java new file mode 100644 index 0000000..f9b9210 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultCounterService.java @@ -0,0 +1,71 @@ +/* + * 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.custom; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.springframework.stereotype.Component; + +import com.netflix.servo.monitor.BasicCounter; +import com.netflix.servo.monitor.MonitorConfig; + +@Component +public class DefaultCounterService implements CounterService { + + private final Map<String, BasicCounter> counters; + + public DefaultCounterService() { + this.counters = new ConcurrentHashMapEx<>(); + } + + @Override + public void increment(String name) { + getCounter(name).increment(); + } + + @Override + public void increment(String name, long value) { + getCounter(name).increment(value); + } + + @Override + public void decrement(String name) { + getCounter(name).increment(-1); + } + + @Override + public void reset(String name) { + counters.remove(name); + this.increment(name, 0); + } + + private BasicCounter getCounter(String name) { + return counters.computeIfAbsent(name, n -> new BasicCounter(MonitorConfig.builder(n).build())); + } + + public Map<String, Number> toMetrics() { + Map<String, Number> metrics = new HashMap<>(); + for (Entry<String, BasicCounter> counter : counters.entrySet()) { + metrics.put(counter.getKey(), counter.getValue().getValue()); + } + return metrics; + } +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultGaugeService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultGaugeService.java new file mode 100644 index 0000000..edb9aff --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultGaugeService.java @@ -0,0 +1,43 @@ +/* + * 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.custom; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.springframework.stereotype.Component; + +@Component +public class DefaultGaugeService implements GaugeService { + + private final Map<String, Number> gauges; + + public DefaultGaugeService() { + this.gauges = new ConcurrentHashMapEx<>(); + } + + @Override + public void update(String name, Number value) { + this.gauges.put(name, value); + } + + public Map<String, Number> toMetrics() { + return new HashMap<>(gauges); + } +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultWindowCounterService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultWindowCounterService.java new file mode 100644 index 0000000..227fd85 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/DefaultWindowCounterService.java @@ -0,0 +1,49 @@ +/* + * 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.custom; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.springframework.stereotype.Component; + +@Component +public class DefaultWindowCounterService implements WindowCounterService { + + private final Map<String, WindowCounter> counters; + + public DefaultWindowCounterService() { + this.counters = new ConcurrentHashMapEx<>(); + } + + @Override + public void record(String name, long value) { + WindowCounter counter = counters.computeIfAbsent(name, WindowCounter::new); + counter.update(value); + } + + public Map<String, Number> toMetrics(int windowTimeIndex) { + Map<String, Number> metrics = new HashMap<>(); + for (Entry<String, WindowCounter> counter : counters.entrySet()) { + metrics.putAll(counter.getValue().toMetric(windowTimeIndex)); + } + return metrics; + } +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/GaugeService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/GaugeService.java new file mode 100644 index 0000000..0b7c526 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/GaugeService.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.metrics.core.custom; + +public interface GaugeService { + void update(String name, Number value); +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounter.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounter.java new file mode 100644 index 0000000..7c7bd2b --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounter.java @@ -0,0 +1,82 @@ +/* + * 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.custom; + +import java.util.HashMap; +import java.util.Map; + +import com.netflix.servo.monitor.MaxGauge; +import com.netflix.servo.monitor.MinGauge; +import com.netflix.servo.monitor.MonitorConfig; +import com.netflix.servo.monitor.StepCounter; + +public class WindowCounter { + private final String name; + + private final StepCounter total; + + private final StepCounter count; + + private final MinGauge min; + + private final MaxGauge max; + + public WindowCounter(String name) { + this.name = name; + total = new StepCounter(MonitorConfig.builder(name).build()); + count = new StepCounter(MonitorConfig.builder(name).build()); + min = new MinGauge(MonitorConfig.builder(name).build()); + max = new MaxGauge(MonitorConfig.builder(name).build()); + } + + public void update(long value) { + if (value > 0) { + total.increment(value); + count.increment(); + max.update(value); + min.update(value); + } + } + + public Map<String, Number> toMetric(int windowTimeIndex) { + Map<String, Number> metrics = new HashMap<>(); + metrics.put(name + ".total", this.adjustValue(total.getCount(windowTimeIndex))); + metrics.put(name + ".count", this.adjustValue(count.getCount(windowTimeIndex))); + metrics.put(name + ".max", this.adjustValue(max.getValue(windowTimeIndex))); + metrics.put(name + ".min", this.adjustValue(min.getValue(windowTimeIndex))); + double value = count.getCount(windowTimeIndex) == 0 ? 0 : + (double) this.total.getCount(windowTimeIndex) / (double) this.count.getCount(windowTimeIndex); + metrics.put(name + ".average", value); + metrics.put(name + ".tps", this.adjustValue(total.getValue(windowTimeIndex).doubleValue())); + return metrics; + } + + //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 + private long adjustValue(long value) { + return 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 + private double adjustValue(double value) { + return value < 0 ? 0 : value; + } +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounterService.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounterService.java new file mode 100644 index 0000000..4a15947 --- /dev/null +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/custom/WindowCounterService.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.metrics.core.custom; + +public interface WindowCounterService { + void record(String name, long value); +} 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 7a105de..7cdb1db 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 @@ -24,6 +24,9 @@ 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.apache.servicecomb.metrics.core.custom.DefaultCounterService; +import org.apache.servicecomb.metrics.core.custom.DefaultGaugeService; +import org.apache.servicecomb.metrics.core.custom.DefaultWindowCounterService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -36,9 +39,20 @@ public class RegistryMonitor { private final Map<String, ProducerInvocationMonitor> producerInvocationMonitors; + private final DefaultCounterService counterService; + + private final DefaultGaugeService gaugeService; + + private final DefaultWindowCounterService windowCounterService; + @Autowired - public RegistryMonitor(SystemMonitor systemMonitor) { + public RegistryMonitor(SystemMonitor systemMonitor, + DefaultCounterService counterService, DefaultGaugeService gaugeService, + DefaultWindowCounterService windowCounterService) { this.systemMonitor = systemMonitor; + this.counterService = counterService; + this.gaugeService = gaugeService; + this.windowCounterService = windowCounterService; this.consumerInvocationMonitors = new ConcurrentHashMapEx<>(); this.producerInvocationMonitors = new ConcurrentHashMapEx<>(); } @@ -60,6 +74,12 @@ public class RegistryMonitor { for (ProducerInvocationMonitor monitor : this.producerInvocationMonitors.values()) { producerInvocationMetrics.put(monitor.getOperationName(), monitor.toMetric(windowTimeIndex)); } - return new RegistryMetric(systemMonitor.toMetric(), consumerInvocationMetrics, producerInvocationMetrics); + + Map<String, Number> customMetrics = new HashMap<>(counterService.toMetrics()); + customMetrics.putAll(gaugeService.toMetrics()); + customMetrics.putAll(windowCounterService.toMetrics(windowTimeIndex)); + + return new RegistryMetric(systemMonitor.toMetric(), consumerInvocationMetrics, producerInvocationMetrics, + customMetrics); } } diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestCustomMetrics.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestCustomMetrics.java new file mode 100644 index 0000000..c9ccc23 --- /dev/null +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestCustomMetrics.java @@ -0,0 +1,79 @@ +/* + * 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 org.apache.servicecomb.metrics.common.RegistryMetric; +import org.apache.servicecomb.metrics.core.custom.DefaultCounterService; +import org.apache.servicecomb.metrics.core.custom.DefaultGaugeService; +import org.apache.servicecomb.metrics.core.custom.DefaultWindowCounterService; +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.junit.Assert; +import org.junit.Test; + +public class TestCustomMetrics { + + @Test + public void testCustom() throws InterruptedException { + SystemMonitor systemMonitor = new DefaultSystemMonitor(); + DefaultCounterService counterService = new DefaultCounterService(); + DefaultGaugeService gaugeService = new DefaultGaugeService(); + DefaultWindowCounterService windowCounterService = new DefaultWindowCounterService(); + + RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor, counterService, gaugeService, + windowCounterService); + DefaultDataSource dataSource = new DefaultDataSource(registryMonitor, "1000,2000,3000,3000,2000,1000"); + + counterService.increment("C1"); + counterService.increment("C1"); + counterService.decrement("C1"); + + counterService.increment("C2", 99); + counterService.reset("C2"); + + counterService.increment("C3", 20); + + gaugeService.update("G1", 100); + gaugeService.update("G1", 200); + gaugeService.update("G2", 150); + + windowCounterService.record("W1", 1); + windowCounterService.record("W1", 2); + windowCounterService.record("W1", 3); + + //sim lease one window time + Thread.sleep(1000); + + RegistryMetric metric = dataSource.getRegistryMetric(1000); + + Assert.assertEquals(1, metric.getCustomMetrics().get("C1").intValue()); + Assert.assertEquals(0, metric.getCustomMetrics().get("C2").intValue()); + Assert.assertEquals(20, metric.getCustomMetrics().get("C3").intValue()); + Assert.assertEquals(200, metric.getCustomMetrics().get("G1").intValue()); + Assert.assertEquals(150, metric.getCustomMetrics().get("G2").intValue()); + + Assert.assertEquals(6, metric.getCustomMetrics().get("W1.total").doubleValue(), 0); + Assert.assertEquals(3, metric.getCustomMetrics().get("W1.count").doubleValue(), 0); + Assert.assertEquals(6, metric.getCustomMetrics().get("W1.tps").doubleValue(), 0); + Assert.assertEquals(2, metric.getCustomMetrics().get("W1.average").doubleValue(), 0); + Assert.assertEquals(1, metric.getCustomMetrics().get("W1.min").doubleValue(), 0); + Assert.assertEquals(3, metric.getCustomMetrics().get("W1.max").doubleValue(), 0); + } +} 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 85cf463..db400d1 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 @@ -35,6 +35,9 @@ 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.custom.DefaultCounterService; +import org.apache.servicecomb.metrics.core.custom.DefaultGaugeService; +import org.apache.servicecomb.metrics.core.custom.DefaultWindowCounterService; 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; @@ -68,7 +71,8 @@ public class TestEventAndRunner { when(nonHeap.getUsed()).thenReturn(800L); DefaultSystemMonitor systemMonitor = new DefaultSystemMonitor(systemMXBean, threadMXBean, memoryMXBean); - RegistryMonitor monitor = new RegistryMonitor(systemMonitor); + RegistryMonitor monitor = new RegistryMonitor(systemMonitor, new DefaultCounterService(), new DefaultGaugeService(), + new DefaultWindowCounterService()); DefaultDataSource dataSource = new DefaultDataSource(monitor, "1000,2000,3000"); List<Long> intervals = dataSource.getAppliedWindowTime(); 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 index f98ee52..1d25569 100644 --- 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 @@ -72,6 +72,19 @@ public class TestHealthCheckerManager { 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<String, HealthCheckResult> results = manager.check(); Assert.assertTrue(results.get("default").isHealthy()); @@ -84,5 +97,8 @@ public class TestHealthCheckerManager { Assert.assertTrue(data.getInstanceId().equals("001")); Assert.assertTrue(data.getHostName().equals("localhost")); Assert.assertTrue(data.getEndpoints().equals("127.0.0.1,192.168.0.100")); + + HealthCheckResult result = manager.check("test"); + Assert.assertTrue(!result.isHealthy()); } } diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java index 55bd705..1586b46 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestPublisher.java @@ -24,6 +24,9 @@ import java.util.List; import java.util.Map; import org.apache.servicecomb.metrics.common.RegistryMetric; +import org.apache.servicecomb.metrics.core.custom.DefaultCounterService; +import org.apache.servicecomb.metrics.core.custom.DefaultGaugeService; +import org.apache.servicecomb.metrics.core.custom.DefaultWindowCounterService; import org.apache.servicecomb.metrics.core.monitor.DefaultSystemMonitor; import org.apache.servicecomb.metrics.core.monitor.RegistryMonitor; import org.apache.servicecomb.metrics.core.monitor.SystemMonitor; @@ -37,7 +40,8 @@ public class TestPublisher { @Test public void test() { SystemMonitor systemMonitor = new DefaultSystemMonitor(); - RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor); + RegistryMonitor registryMonitor = new RegistryMonitor(systemMonitor, new DefaultCounterService(), + new DefaultGaugeService(), new DefaultWindowCounterService()); DefaultDataSource dataSource = new DefaultDataSource(registryMonitor, "1000,2000,3000,3000,2000,1000"); DefaultMetricsPublisher publisher = new DefaultMetricsPublisher(dataSource); 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 932863e..0b576fb 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 @@ -78,6 +78,11 @@ public class MetricsCollector extends Collector implements Collector.Describable .add(new MetricFamilySamples("Consumer Side", Type.UNTYPED, "Consumer Side Metrics", consumerSamples)); } + if (registryMetric.getCustomMetrics().size() != 0) { + familySamples.add(getFamilySamples("User Custom", registryMetric.getCustomMetrics())); + } + + if (registryMetric.getProducerMetrics().size() != 0) { List<Sample> producerSamples = new ArrayList<>(); for (ProducerInvocationMetric metric : registryMetric.getProducerMetrics().values()) { diff --git a/samples/custom-business-metrics/pom.xml b/samples/custom-business-metrics/pom.xml new file mode 100644 index 0000000..90b60da --- /dev/null +++ b/samples/custom-business-metrics/pom.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>samples</artifactId> + <groupId>org.apache.servicecomb.samples</groupId> + <version>0.6.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>custom-business-metrics</artifactId> + <name>Java Chassis::Samples::Custom Business Metrics</name> + + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.servicecomb</groupId> + <artifactId>spring-boot-starter-provider</artifactId> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-validator</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.servicecomb</groupId> + <artifactId>metrics-core</artifactId> + </dependency> + </dependencies> + + +</project> \ No newline at end of file diff --git a/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/CustomMetricsApplication.java b/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/CustomMetricsApplication.java new file mode 100644 index 0000000..3826c99 --- /dev/null +++ b/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/CustomMetricsApplication.java @@ -0,0 +1,30 @@ +/* + * 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.custom; + +import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableServiceComb +public class CustomMetricsApplication { + public static void main(String[] args) { + SpringApplication.run(CustomMetricsApplication.class, args); + } +} diff --git a/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/ShopDemoService.java b/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/ShopDemoService.java new file mode 100644 index 0000000..f9f9986 --- /dev/null +++ b/samples/custom-business-metrics/src/main/java/org/apache/servicecomb/samples/metrics/custom/ShopDemoService.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples.metrics.custom; + +import org.apache.servicecomb.metrics.core.custom.CounterService; +import org.apache.servicecomb.metrics.core.custom.GaugeService; +import org.apache.servicecomb.metrics.core.custom.WindowCounterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ShopDemoService { + + private final CounterService counterService; + + private final GaugeService gaugeService; + + private final WindowCounterService windowCounterService; + + //autowire metrics service + @Autowired + public ShopDemoService(CounterService counterService, GaugeService gaugeService, + WindowCounterService windowCounterService) { + this.counterService = counterService; + this.gaugeService = gaugeService; + this.windowCounterService = windowCounterService; + } + + public void login(String name, String password) { + counterService.increment("Active User"); + } + + public void logout(String session) { + counterService.decrement("Active User"); + } + + public void order(String orderInfo) throws InterruptedException { + long start = System.currentTimeMillis(); + //sim do order process + Thread.sleep(100); + + //sim record order process time + windowCounterService.record("Order Latency", System.currentTimeMillis() - start); + + windowCounterService.record("Order Count", 1); + //only support long + windowCounterService.record("Order Amount", 66); + } + + public void discount(double value) { + //make a discount to Levis Jeans + + gaugeService.update("Levis Jeans", value); + } +} diff --git a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java b/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java index d550f77..63a46d2 100644 --- a/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java +++ b/samples/metrics-write-file-sample/metrics-write-file/src/test/java/org/apache/servicecomb/samples/mwf/TestWriteFile.java @@ -155,7 +155,8 @@ public class TestWriteFile { 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<>()); + RegistryMetric metric = new RegistryMetric(systemMetric, consumerInvocationMetricMap, new HashMap<>(), + new HashMap<>()); DataSource dataSource = Mockito.mock(DataSource.class); Mockito.when(dataSource.getRegistryMetric()).thenReturn(metric); diff --git a/samples/pom.xml b/samples/pom.xml index 0590c43..2c60a7c 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -37,6 +37,7 @@ <module>metrics-write-file-sample</module> <module>metrics-extend-healthcheck</module> <module>config-apollo-sample</module> + <module>custom-business-metrics</module> </modules> <dependencyManagement> -- To stop receiving notification emails like this one, please contact [email protected].
