diff --git a/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommand.java b/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommand.java index 3ae3fe758..eee704bf7 100644 --- a/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommand.java +++ b/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommand.java @@ -25,6 +25,7 @@ import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixEventType; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherCommand; +import com.netflix.hystrix.util.HystrixRollingNumberEvent; import com.netflix.servo.DefaultMonitorRegistry; import com.netflix.servo.annotations.DataSourceLevel; import com.netflix.servo.monitor.BasicCompositeMonitor; @@ -35,8 +36,12 @@ /** * Concrete Implementation of {@link HystrixMetricsPublisherCommand} using Servo (https://github.com/Netflix/servo) + * + * This class should encapsulate all logic around how to pull metrics. This will allow any other custom Servo publisher + * to extend. Then, if that class wishes to override {@link #initialize()}, that concrete implementation can choose + * by picking the set of semantic metrics and names, rather than providing an implementation of how. */ -public class HystrixServoMetricsPublisherCommand extends HystrixServoMetricsPublisherCommandAbstract implements HystrixMetricsPublisherCommand { +public class HystrixServoMetricsPublisherCommand extends HystrixServoMetricsPublisherAbstract implements HystrixMetricsPublisherCommand { private final HystrixCommandKey key; private final HystrixCommandGroupKey commandGroupKey; @@ -112,50 +117,127 @@ protected Tag getServoInstanceTag() { return servoInstanceTag; } - @Override - protected long getCumulativeCount(HystrixEventType event) { - return metrics.getCumulativeCount(getRollingNumberTypeFromEventType(event)); - } - - @Override - protected long getRollingCount(HystrixEventType event) { - return metrics.getRollingCount(getRollingNumberTypeFromEventType(event)); - } - - @Override - protected int getExecutionLatencyMean() { - return metrics.getExecutionTimeMean(); - } - - @Override - protected int getExecutionLatencyPercentile(double percentile) { - return metrics.getExecutionTimePercentile(percentile); - } - - @Override - protected int getTotalLatencyMean() { - return metrics.getTotalTimeMean(); - } - - @Override - protected int getTotalLatencyPercentile(double percentile) { - return metrics.getTotalTimePercentile(percentile); + protected final HystrixRollingNumberEvent getRollingNumberTypeFromEventType(HystrixEventType event) { + switch (event) { + case BAD_REQUEST: return HystrixRollingNumberEvent.BAD_REQUEST; + case COLLAPSED: return HystrixRollingNumberEvent.COLLAPSED; + case EMIT: return HystrixRollingNumberEvent.EMIT; + case EXCEPTION_THROWN: return HystrixRollingNumberEvent.EXCEPTION_THROWN; + case FAILURE: return HystrixRollingNumberEvent.FAILURE; + case FALLBACK_EMIT: return HystrixRollingNumberEvent.FALLBACK_EMIT; + case FALLBACK_FAILURE: return HystrixRollingNumberEvent.FALLBACK_FAILURE; + case FALLBACK_REJECTION: return HystrixRollingNumberEvent.FALLBACK_REJECTION; + case FALLBACK_SUCCESS: return HystrixRollingNumberEvent.FALLBACK_SUCCESS; + case RESPONSE_FROM_CACHE: return HystrixRollingNumberEvent.RESPONSE_FROM_CACHE; + case SEMAPHORE_REJECTED: return HystrixRollingNumberEvent.SEMAPHORE_REJECTED; + case SHORT_CIRCUITED: return HystrixRollingNumberEvent.SHORT_CIRCUITED; + case SUCCESS: return HystrixRollingNumberEvent.SUCCESS; + case THREAD_POOL_REJECTED: return HystrixRollingNumberEvent.THREAD_POOL_REJECTED; + case TIMEOUT: return HystrixRollingNumberEvent.TIMEOUT; + default: throw new RuntimeException("Unknown HystrixEventType : " + event); + } } - private final Func0 currentConcurrentExecutionCountThunk = new Func0() { + protected final Func0 currentConcurrentExecutionCountThunk = new Func0() { @Override public Integer call() { return metrics.getCurrentConcurrentExecutionCount(); } }; - private final Func0 errorPercentageThunk = new Func0() { + protected final Func0 rollingMaxConcurrentExecutionCountThunk = new Func0() { + @Override + public Long call() { + return metrics.getRollingMaxConcurrentExecutions(); + } + }; + + protected final Func0 errorPercentageThunk = new Func0() { @Override public Integer call() { return metrics.getHealthCounts().getErrorPercentage(); } }; + protected final Func0 currentTimeThunk = new Func0() { + @Override + public Number call() { + return System.currentTimeMillis(); + } + }; + + protected Monitor getCumulativeMonitor(final String name, final HystrixEventType event) { + return new CounterMetric(MonitorConfig.builder(name).withTag(getServoTypeTag()).withTag(getServoInstanceTag()).build()) { + @Override + public Long getValue() { + return metrics.getCumulativeCount(getRollingNumberTypeFromEventType(event)); + } + }; + } + + protected Monitor getRollingMonitor(final String name, final HystrixEventType event) { + return new CounterMetric(MonitorConfig.builder(name).withTag(getServoTypeTag()).withTag(getServoInstanceTag()).build()) { + @Override + public Long getValue() { + return metrics.getRollingCount(getRollingNumberTypeFromEventType(event)); + } + }; + } + + protected Monitor getExecutionLatencyMeanMonitor(final String name) { + return new GaugeMetric(MonitorConfig.builder(name).build()) { + @Override + public Number getValue() { + return metrics.getExecutionTimeMean(); + } + }; + } + + protected Monitor getExecutionLatencyPercentileMonitor(final String name, final double percentile) { + return new GaugeMetric(MonitorConfig.builder(name).build()) { + @Override + public Number getValue() { + return metrics.getExecutionTimePercentile(percentile); + } + }; + } + + protected Monitor getTotalLatencyMeanMonitor(final String name) { + return new GaugeMetric(MonitorConfig.builder(name).build()) { + @Override + public Number getValue() { + return metrics.getTotalTimeMean(); + } + }; + } + + protected Monitor getTotalLatencyPercentileMonitor(final String name, final double percentile) { + return new GaugeMetric(MonitorConfig.builder(name).build()) { + @Override + public Number getValue() { + return metrics.getTotalTimePercentile(percentile); + } + }; + } + + protected Monitor getCurrentValueMonitor(final String name, final Func0 metricToEvaluate) { + return new GaugeMetric(MonitorConfig.builder(name).build()) { + @Override + public Number getValue() { + return metricToEvaluate.call(); + } + }; + } + + protected Monitor getCurrentValueMonitor(final String name, final Func0 metricToEvaluate, final Tag tag) { + return new GaugeMetric(MonitorConfig.builder(name).withTag(tag).build()) { + @Override + public Number getValue() { + return metricToEvaluate.call(); + } + }; + } + /** * Servo will flatten metric names as: getServoTypeTag()_getServoInstanceTag()_monitorName */ @@ -171,12 +253,7 @@ public Boolean getValue() { }); // allow Servo and monitor to know exactly at what point in time these stats are for so they can be plotted accurately - monitors.add(new GaugeMetric(MonitorConfig.builder("currentTime").withTag(DataSourceLevel.DEBUG).build()) { - @Override - public Number getValue() { - return System.currentTimeMillis(); - } - }); + monitors.add(getCurrentValueMonitor("currentTime", currentTimeThunk, DataSourceLevel.DEBUG)); // cumulative counts monitors.add(getCumulativeMonitor("countBadRequests", HystrixEventType.BAD_REQUEST)); diff --git a/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommandAbstract.java b/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommandAbstract.java deleted file mode 100644 index d9c01e987..000000000 --- a/hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommandAbstract.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright 2015 Netflix, Inc. - * - * Licensed 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 com.netflix.hystrix.contrib.servopublisher; - -import com.netflix.hystrix.HystrixEventType; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import com.netflix.servo.monitor.Monitor; -import com.netflix.servo.monitor.MonitorConfig; -import rx.functions.Func0; - -/** - * Servo publisher for HystrixCommand metrics. It makes no assumptions on how metrics are gathered. - */ -/* package */abstract class HystrixServoMetricsPublisherCommandAbstract extends HystrixServoMetricsPublisherAbstract { - - protected abstract long getCumulativeCount(HystrixEventType event); - - protected abstract long getRollingCount(HystrixEventType event); - - protected abstract int getExecutionLatencyMean(); - - protected abstract int getExecutionLatencyPercentile(double percentile); - - protected abstract int getTotalLatencyMean(); - - protected abstract int getTotalLatencyPercentile(double percentile); - - protected final HystrixRollingNumberEvent getRollingNumberTypeFromEventType(HystrixEventType event) { - switch (event) { - case BAD_REQUEST: return HystrixRollingNumberEvent.BAD_REQUEST; - case COLLAPSED: return HystrixRollingNumberEvent.COLLAPSED; - case EMIT: return HystrixRollingNumberEvent.EMIT; - case EXCEPTION_THROWN: return HystrixRollingNumberEvent.EXCEPTION_THROWN; - case FAILURE: return HystrixRollingNumberEvent.FAILURE; - case FALLBACK_EMIT: return HystrixRollingNumberEvent.FALLBACK_EMIT; - case FALLBACK_FAILURE: return HystrixRollingNumberEvent.FALLBACK_FAILURE; - case FALLBACK_REJECTION: return HystrixRollingNumberEvent.FALLBACK_REJECTION; - case FALLBACK_SUCCESS: return HystrixRollingNumberEvent.FALLBACK_SUCCESS; - case RESPONSE_FROM_CACHE: return HystrixRollingNumberEvent.RESPONSE_FROM_CACHE; - case SEMAPHORE_REJECTED: return HystrixRollingNumberEvent.SEMAPHORE_REJECTED; - case SHORT_CIRCUITED: return HystrixRollingNumberEvent.SHORT_CIRCUITED; - case SUCCESS: return HystrixRollingNumberEvent.SUCCESS; - case THREAD_POOL_REJECTED: return HystrixRollingNumberEvent.THREAD_POOL_REJECTED; - case TIMEOUT: return HystrixRollingNumberEvent.TIMEOUT; - default: throw new RuntimeException("Unknown HystrixEventType : " + event); - } - } - - protected Monitor getCumulativeMonitor(final String name, final HystrixEventType event) { - return new CounterMetric(MonitorConfig.builder(name).withTag(getServoTypeTag()).withTag(getServoInstanceTag()).build()) { - @Override - public Long getValue() { - return getCumulativeCount(event); - } - }; - } - - protected Monitor getRollingMonitor(final String name, final HystrixEventType event) { - return new CounterMetric(MonitorConfig.builder(name).withTag(getServoTypeTag()).withTag(getServoInstanceTag()).build()) { - @Override - public Long getValue() { - return getRollingCount(event); - } - }; - } - - protected Monitor getExecutionLatencyMeanMonitor(final String name) { - return new GaugeMetric(MonitorConfig.builder(name).build()) { - @Override - public Number getValue() { - return getExecutionLatencyMean(); - } - }; - } - - protected Monitor getExecutionLatencyPercentileMonitor(final String name, final double percentile) { - return new GaugeMetric(MonitorConfig.builder(name).build()) { - @Override - public Number getValue() { - return getExecutionLatencyPercentile(percentile); - } - }; - } - - protected Monitor getTotalLatencyMeanMonitor(final String name) { - return new GaugeMetric(MonitorConfig.builder(name).build()) { - @Override - public Number getValue() { - return getTotalLatencyMean(); - } - }; - } - - protected Monitor getTotalLatencyPercentileMonitor(final String name, final double percentile) { - return new GaugeMetric(MonitorConfig.builder(name).build()) { - @Override - public Number getValue() { - return getTotalLatencyPercentile(percentile); - } - }; - } - - protected Monitor getCurrentValueMonitor(final String name, final Func0 metricToEvaluate) { - return new GaugeMetric(MonitorConfig.builder(name).build()) { - @Override - public Number getValue() { - return metricToEvaluate.call(); - } - }; - } -}