From d3ae672f4946a8406af82f60611e6089a293c71a Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:02:26 -0700 Subject: [PATCH 1/9] Revert "Add minimal concrete implementations of abstract metrics" This reverts commit 35798bf7396c755e087d77bd8f37d638bcaacf2c. --- .../noop/HystrixCollapserMetricsNoOp.java | 91 -------------- .../noop/HystrixCommandMetricsCountsOnly.java | 112 ------------------ .../noop/HystrixMetricsCollectionMinimal.java | 49 -------- .../noop/HystrixThreadPoolMetricsNoOp.java | 63 ---------- 4 files changed, 315 deletions(-) delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCollapserMetricsNoOp.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCommandMetricsCountsOnly.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixMetricsCollectionMinimal.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixThreadPoolMetricsNoOp.java diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCollapserMetricsNoOp.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCollapserMetricsNoOp.java deleted file mode 100644 index 187159081..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCollapserMetricsNoOp.java +++ /dev/null @@ -1,91 +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.strategy.metrics.noop; - -import com.netflix.hystrix.HystrixCollapserKey; -import com.netflix.hystrix.HystrixCollapserMetrics; -import com.netflix.hystrix.HystrixCollapserProperties; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; - -/** - * Not needed for health check - so it's fine to just drop all collapser metrics on the floor if you're not interested in them - */ -public class HystrixCollapserMetricsNoOp extends HystrixCollapserMetrics { - - HystrixCollapserMetricsNoOp(HystrixCollapserKey key, HystrixCollapserProperties properties) { - super(key, properties); - } - - @Override - public int getBatchSizePercentile(double percentile) { - return 0; - } - - @Override - public int getBatchSizeMean() { - return 0; - } - - @Override - protected void addBatchSize(int batchSize) { - - } - - @Override - public int getShardSizePercentile(double percentile) { - return 0; - } - - @Override - public int getShardSizeMean() { - return 0; - } - - @Override - protected void addShardSize(int shardSize) { - - } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - - } -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCommandMetricsCountsOnly.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCommandMetricsCountsOnly.java deleted file mode 100644 index 4021ecedc..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixCommandMetricsCountsOnly.java +++ /dev/null @@ -1,112 +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.strategy.metrics.noop; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.util.HystrixRollingNumber; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; - -/** - * We need to track counts accurately to properly calculate circuit health. We can ignore latency, though - */ -public class HystrixCommandMetricsCountsOnly extends HystrixCommandMetrics { - - private final HystrixRollingNumber counter; - - public HystrixCommandMetricsCountsOnly(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { - super(key, commandGroup, threadPoolKey, properties, eventNotifier); - this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); - } - - /** - * COUNT measurements that must be implemented - */ - - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } - - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - counter.increment(event); - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - counter.add(event, value); - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - counter.updateRollingMax(event, value); - } - - @Override - protected void clear() { - counter.reset(); - } - - /** - * LATENCY measurements that may be ignored - */ - - @Override - public int getExecutionTimePercentile(double percentile) { - return 0; - } - - @Override - public int getExecutionTimeMean() { - return 0; - } - - @Override - public int getTotalTimePercentile(double percentile) { - return 0; - } - - @Override - public int getTotalTimeMean() { - return 0; - } - - @Override - protected void addCommandExecutionTime(long duration) { - - } - - @Override - protected void addUserThreadExecutionTime(long duration) { - - } -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixMetricsCollectionMinimal.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixMetricsCollectionMinimal.java deleted file mode 100644 index 5239b3cf2..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixMetricsCollectionMinimal.java +++ /dev/null @@ -1,49 +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.strategy.metrics.noop; - -import com.netflix.hystrix.HystrixCollapserKey; -import com.netflix.hystrix.HystrixCollapserMetrics; -import com.netflix.hystrix.HystrixCollapserProperties; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; - -import java.util.concurrent.ThreadPoolExecutor; - -public class HystrixMetricsCollectionMinimal extends HystrixMetricsCollection { - - @Override - public HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { - return new HystrixCommandMetricsCountsOnly(key, commandGroup, threadPoolKey, properties, eventNotifier); - } - - @Override - public HystrixThreadPoolMetrics getThreadPoolMetricsInstance(HystrixThreadPoolKey key, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { - return new HystrixThreadPoolMetricsNoOp(key, threadPool, properties); - } - - @Override - public HystrixCollapserMetrics getCollapserMetricsInstance(HystrixCollapserKey key, HystrixCollapserProperties properties) { - return new HystrixCollapserMetricsNoOp(key, properties); - } -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixThreadPoolMetricsNoOp.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixThreadPoolMetricsNoOp.java deleted file mode 100644 index d6b5b2bb0..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/noop/HystrixThreadPoolMetricsNoOp.java +++ /dev/null @@ -1,63 +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.strategy.metrics.noop; - -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; - -import java.util.concurrent.ThreadPoolExecutor; - -/** - * Thread pool metrics not used in health checks, so these may be dropped on the floor if you're not interested in them - */ -public class HystrixThreadPoolMetricsNoOp extends HystrixThreadPoolMetrics { - - public HystrixThreadPoolMetricsNoOp(HystrixThreadPoolKey key, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { - super(key, threadPool, properties); - } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - - } -} From afdf297de7b4f4cd7f7a73435bea7c108a9628f4 Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:02:39 -0700 Subject: [PATCH 2/9] Revert "Cleanup Javadoc for HystrixCommandMetrics" This reverts commit dfb2be675375a2a93a1d1d55272ef34b78b28b43. --- .../main/java/com/netflix/hystrix/HystrixCommandMetrics.java | 3 --- .../strategy/metrics/HystrixCommandMetricsSummary.java | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java index 5a9559bd3..5e80d0552 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -414,9 +414,6 @@ public long getRollingMaxConcurrentExecutions() { /** * Retrieve a snapshot of total requests, error count and error percentage. - * - * Marked final so that concrete implementation may vary how to implement {@link #getRollingCount(HystrixRollingNumberEvent)} - * and the health check (used for opening a {@link HystrixCircuitBreaker} is constant * * @return {@link HealthCounts} */ diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java index e616cc768..1d9cc4e8b 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java @@ -79,6 +79,10 @@ protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { counter.updateRollingMax(event, value); } + public long getRollingMaxConcurrentExecutions() { + return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); + } + /** * Execution time of {@link HystrixCommand#run()}. */ From 93c80e811d25f1bb7a77cb758c1bfa1103dcca4a Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:02:51 -0700 Subject: [PATCH 3/9] Revert "Cleanup Javadoc for HystrixThreadPoolMetrics" This reverts commit 17d37e6695809e23dd47f6610905d5a8caffac53. --- .../hystrix/HystrixThreadPoolMetrics.java | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java index e9a376c80..cb3d6df5e 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java @@ -23,20 +23,14 @@ import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.netflix.hystrix.util.HystrixRollingNumber; import com.netflix.hystrix.util.HystrixRollingNumberEvent; /** - * Metrics class to track usage of {@link HystrixThreadPool}s. - * - * This is an abstract class that provides a home for statics that manage caching of HystrixThreadPoolMetrics instances. - * It also provides a limited surface-area for concrete subclasses to implement. This allows different data structures - * to be used in the actual storage of metrics. - * - * For instance, you may drop all metrics. You may also keep references to all threadpool events that pass through - * the JVM. The default is to take a middle ground and summarize threadpool metrics into counts of events and - * percentiles of batch/shard size. - * - * As in {@link HystrixMetrics}, all read methods are public and write methods are package-private or protected. + * Used by {@link HystrixThreadPool} to record metrics. */ public abstract class HystrixThreadPoolMetrics extends HystrixMetrics { @@ -216,7 +210,7 @@ public Number getCurrentQueueSize() { /** * Invoked each time a thread is executed. */ - protected void markThreadExecution() { + public void markThreadExecution() { // increment the count addEvent(HystrixRollingNumberEvent.THREAD_EXECUTION); setMaxActiveThreads(); @@ -245,7 +239,7 @@ public long getCumulativeCountThreadsExecuted() { /** * Invoked each time a thread completes. */ - protected void markThreadCompletion() { + public void markThreadCompletion() { setMaxActiveThreads(); } @@ -260,10 +254,6 @@ public long getRollingMaxActiveThreads() { return getRollingMax(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE); } - /** - * Update the rolling max counter of active threads - * - */ private void setMaxActiveThreads() { updateRollingMax(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE, threadPool.getActiveCount()); } @@ -271,7 +261,7 @@ private void setMaxActiveThreads() { /** * Invoked each time a command is rejected from the thread-pool */ - protected void markThreadRejection() { + public void markThreadRejection() { addEvent(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); } } \ No newline at end of file From ca50ab062d2c6255e1a254568a1c98921632a2ba Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:03:00 -0700 Subject: [PATCH 4/9] Revert "Add/Fix Javadoc for HystrixCollapserMetrics." This reverts commit 9a8ab7cd22acb218bbc8f6e3a3ea2542c2a9f0a9. --- .../hystrix/HystrixCollapserMetrics.java | 64 ++----------------- .../HystrixCollapserMetricsSummary.java | 44 ++++++++----- .../metrics/HystrixCommandMetricsSummary.java | 10 +-- .../HystrixThreadPoolMetricsSummary.java | 10 +-- 4 files changed, 45 insertions(+), 83 deletions(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java index ede8d91fc..ea8116eb1 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java @@ -27,17 +27,7 @@ /** * Used by {@link HystrixCollapser} to record metrics. - * This is an abstract class that provides a home for statics that manage caching of HystrixCollapserMetrics instances. - * It also provides a limited surface-area for concrete subclasses to implement. This allows different data structures - * to be used in the actual storage of metrics. - * - * For instance, you may drop all metrics. You may also keep references to all collapser events that pass through - * the JVM. The default is to take a middle ground and summarize collapser metrics into counts of events and - * percentiles of batch/shard size. - * - * Note that {@link com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier} is not hooked up yet. It may be in the future. - * - * As in {@link HystrixMetrics}, all read methods are public and write methods are package-private or protected. + * {@link com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier} not hooked up yet. It may be in the future. */ public abstract class HystrixCollapserMetrics extends HystrixMetrics { @@ -114,7 +104,7 @@ public HystrixCollapserProperties getProperties() { } /** - * Retrieve the batch size for the {@link HystrixCollapser} being invoked at a given percentile over a rolling window. + * Retrieve the batch size for the {@link HystrixCollapser} being invoked at a given percentile. *

* Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. * @@ -124,22 +114,12 @@ public HystrixCollapserProperties getProperties() { */ public abstract int getBatchSizePercentile(double percentile); - /** - * Mean of batch size over rolling window. - * - * @return batch size mean - */ public abstract int getBatchSizeMean(); - /** - * Add a batch size to the batch size metrics data structure - * - * @param batchSize batch size to add - */ protected abstract void addBatchSize(int batchSize); /** - * Retrieve the shard size for the {@link HystrixCollapser} being invoked at a given percentile for a rolling window. + * Retrieve the shard size for the {@link HystrixCollapser} being invoked at a given percentile. *

* Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. * @@ -149,54 +129,24 @@ public HystrixCollapserProperties getProperties() { */ public abstract int getShardSizePercentile(double percentile); - /** - * Mean of shard size over rolling window. - * - * @return shard size mean - */ public abstract int getShardSizeMean(); - /** - * Add a shard size to the shard size metrics data structure. - * - * @param shardSize shard size to add - */ protected abstract void addShardSize(int shardSize); - /** - * Called when a {@link HystrixCollapser} has been invoked. This does not directly execute work, just places the - * args in a queue to be batched at a later point. Keeping track of this value will allow us to determine - * the effectiveness of batching over executing each command individually. - */ - /* package */ void markRequestBatched() { + public void markRequestBatched() { addEvent(HystrixRollingNumberEvent.COLLAPSER_REQUEST_BATCHED); } - /** - * Called when a {@link HystrixCollapser} has been invoked and the response is returned directly from the - * {@link HystrixRequestCache}. - */ - /* package */ void markResponseFromCache() { + public void markResponseFromCache() { addEvent(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE); } - /** - * Called when a batch {@link HystrixCommand} has been executed. Tracking this event allows us to determine the - * effectiveness of collapsing by getting the distribution of batch sizes. - * - * @param batchSize number of request arguments in the batch - */ - /* package */ void markBatch(int batchSize) { + public void markBatch(int batchSize) { addBatchSize(batchSize); addEvent(HystrixRollingNumberEvent.COLLAPSER_BATCH); } - /** - * Called when a batch of request arguments has been divided into shards for separate execution. - * - * @param numShards number of shards in the batch - */ - /* package */ void markShards(int numShards) { + public void markShards(int numShards) { addShardSize(numShards); } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java index 7e1f0f4a9..30c48e3cb 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix.strategy.metrics; +import com.netflix.hystrix.HystrixCollapser; import com.netflix.hystrix.HystrixCollapserKey; import com.netflix.hystrix.HystrixCollapserMetrics; import com.netflix.hystrix.HystrixCollapserProperties; @@ -23,13 +24,8 @@ import com.netflix.hystrix.util.HystrixRollingPercentile; /** - * Concrete implementation of {@link HystrixCollapserMetrics}. - * - * It uses a {@link HystrixRollingNumber} to track the counts - * of events (request batched, batch sent, cache hit). It uses a {@link HystrixRollingPercentile} to track batch size - * and shard size. - * - * These are accurate, but only allow for queries of properties of the distribution/counts. + * Used by {@link HystrixCollapser} to record metrics. + * {@link com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier} not hooked up yet. It may be in the future. */ public class HystrixCollapserMetricsSummary extends HystrixCollapserMetrics { @@ -44,6 +40,15 @@ public class HystrixCollapserMetricsSummary extends HystrixCollapserMetrics { this.percentileShardSize = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); } + /** + * Retrieve the batch size for the {@link HystrixCollapser} being invoked at a given percentile. + *

+ * Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. + * + * @param percentile + * Percentile such as 50, 99, or 99.5. + * @return batch size + */ @Override public int getBatchSizePercentile(double percentile) { return percentileBatchSize.getPercentile(percentile); @@ -59,6 +64,15 @@ protected void addBatchSize(int batchSize) { percentileBatchSize.addValue(batchSize); } + /** + * Retrieve the shard size for the {@link HystrixCollapser} being invoked at a given percentile. + *

+ * Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. + * + * @param percentile + * Percentile such as 50, 99, or 99.5. + * @return batch size + */ @Override public int getShardSizePercentile(double percentile) { return percentileShardSize.getPercentile(percentile); @@ -70,12 +84,12 @@ public int getShardSizeMean() { } @Override - protected void addShardSize(int numShards) { - percentileShardSize.addValue(numShards); + protected void addShardSize(int shardSize) { + percentileShardSize.addValue(shardSize); } public void markShards(int numShards) { - addShardSize(numShards); + percentileShardSize.addValue(numShards); } @Override @@ -88,11 +102,6 @@ public long getRollingCount(HystrixRollingNumberEvent event) { return counter.getRollingSum(event); } - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } - @Override protected void addEvent(HystrixRollingNumberEvent event) { counter.increment(event); @@ -108,5 +117,8 @@ protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { counter.updateRollingMax(event, value); } - + @Override + protected long getRollingMax(HystrixRollingNumberEvent event) { + return counter.getRollingMaxValue(event); + } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java index 1d9cc4e8b..8fea6bced 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java @@ -59,11 +59,6 @@ public long getRollingCount(HystrixRollingNumberEvent event) { return counter.getRollingSum(event); } - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } - @Override protected void addEvent(HystrixRollingNumberEvent event) { counter.increment(event); @@ -79,6 +74,11 @@ protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { counter.updateRollingMax(event, value); } + @Override + protected long getRollingMax(HystrixRollingNumberEvent event) { + return counter.getRollingMaxValue(event); + } + public long getRollingMaxConcurrentExecutions() { return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java index f6c2cfbcb..1408ad944 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java @@ -47,11 +47,6 @@ public long getRollingCount(HystrixRollingNumberEvent event) { return counter.getRollingSum(event); } - @Override - public long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } - @Override protected void addEvent(HystrixRollingNumberEvent event) { counter.increment(event); @@ -66,4 +61,9 @@ protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { counter.updateRollingMax(event, value); } + + @Override + protected long getRollingMax(HystrixRollingNumberEvent event) { + return counter.getRollingMaxValue(event); + } } From 5270f4b5ccc1a5ae5ee400df8d2fdd04526a3ea0 Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:03:11 -0700 Subject: [PATCH 5/9] Revert "Add Javadoc for HystrixMetrics" This reverts commit f13314a34436374ac80b92c0ae56641da4a20dd0. --- .../com/netflix/hystrix/HystrixMetrics.java | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java index 2b410cf00..50a1a497d 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java @@ -19,16 +19,14 @@ /** * Abstract base class for Hystrix metrics - * - * Read methods are public, as they may get called by arbitrary metrics consumers in other projects - * Write methods are protected, so that only internals may trigger them. */ public abstract class HystrixMetrics { /** * Get the cumulative count since the start of the application for the given {@link HystrixRollingNumberEvent}. * - * @param event {@link HystrixRollingNumberEvent} of the event to retrieve a sum for + * @param event + * {@link HystrixRollingNumberEvent} of the event to retrieve a sum for * @return long cumulative count */ public abstract long getCumulativeCount(HystrixRollingNumberEvent event); @@ -38,42 +36,17 @@ public abstract class HystrixMetrics { *

* The rolling window is defined by {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()}. * - * @param event {@link HystrixRollingNumberEvent} of the event to retrieve a sum for + * @param event + * {@link HystrixRollingNumberEvent} of the event to retrieve a sum for * @return long rolling count */ public abstract long getRollingCount(HystrixRollingNumberEvent event); - /** - * Get the rolling max for the given {@link HystrixRollingNumberEvent}. This number is the high-water mark - * that the metric has observed in the rolling window. - *

- * The rolling window is defined by {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()}. - * - * @param event {@link HystrixRollingNumberEvent} of the event to retrieve a rolling max for - * @return long rolling max - */ - public abstract long getRollingMax(HystrixRollingNumberEvent event); - - /** - * Increment the count of an {@link HystrixRollingNumberEvent}. - * - * @param event event type to increment - */ protected abstract void addEvent(HystrixRollingNumberEvent event); - /** - * Add a count of {@link HystrixRollingNumberEvent}s - * - * @param event event type to add to - * @param value count to add - */ protected abstract void addEventWithValue(HystrixRollingNumberEvent event, long value); - /** - * Set the observed value of a {@link HystrixRollingNumberEvent} into a counter that keeps track of maximum values - * - * @param event event type to observe count of - * @param value count observed - */ protected abstract void updateRollingMax(HystrixRollingNumberEvent event, long value); + + protected abstract long getRollingMax(HystrixRollingNumberEvent event); } From fd71da55eb4a5e6b6404850d49fbe527d035f59f Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:03:23 -0700 Subject: [PATCH 6/9] Revert "Make thread-pool and collapser metrics also able to be varied by plugin" This reverts commit a46b6e95f3c0882630553382e3b7bb932b1a8b10. --- .../hystrix/HystrixCollapserMetrics.java | 63 ++++--- .../hystrix/HystrixCommandMetrics.java | 77 ++++---- .../HystrixCommandMetricsSummary.java | 170 ++++++++++-------- .../com/netflix/hystrix/HystrixMetrics.java | 8 - .../hystrix/HystrixThreadPoolMetrics.java | 33 ++-- .../HystrixCollapserMetricsSummary.java | 124 ------------- .../metrics/HystrixMetricsCollection.java | 13 +- .../HystrixMetricsCollectionDefault.java | 22 +-- .../HystrixThreadPoolMetricsSummary.java | 69 ------- .../hystrix/HystrixCircuitBreakerTest.java | 1 - .../hystrix/HystrixCommandMetricsTest.java | 1 - 11 files changed, 206 insertions(+), 375 deletions(-) rename hystrix-core/src/main/java/com/netflix/hystrix/{strategy/metrics => }/HystrixCommandMetricsSummary.java (76%) delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java index ea8116eb1..369bb654e 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java @@ -19,17 +19,20 @@ import java.util.Collections; import java.util.concurrent.ConcurrentHashMap; -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; +import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; +import com.netflix.hystrix.util.HystrixRollingNumber; import com.netflix.hystrix.util.HystrixRollingNumberEvent; +import com.netflix.hystrix.util.HystrixRollingPercentile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Used by {@link HystrixCollapser} to record metrics. - * {@link com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier} not hooked up yet. It may be in the future. + * {@link HystrixEventNotifier} not hooked up yet. It may be in the future. */ -public abstract class HystrixCollapserMetrics extends HystrixMetrics { +public class HystrixCollapserMetrics extends HystrixMetrics { + + private final HystrixRollingNumber counter; @SuppressWarnings("unused") private static final Logger logger = LoggerFactory.getLogger(HystrixCollapserMetrics.class); @@ -53,8 +56,7 @@ public static HystrixCollapserMetrics getInstance(HystrixCollapserKey key, Hystr return collapserMetrics; } // it doesn't exist so we need to create it - HystrixMetricsCollection metricsCollectionStrategy = HystrixPlugins.getInstance().getMetricsCollection(); - collapserMetrics = metricsCollectionStrategy.getCollapserMetricsInstance(key, properties); + collapserMetrics = new HystrixCollapserMetrics(key, properties); // attempt to store it (race other threads) HystrixCollapserMetrics existing = metrics.putIfAbsent(key.name(), collapserMetrics); if (existing == null) { @@ -84,10 +86,16 @@ public static Collection getInstances() { private final HystrixCollapserKey key; private final HystrixCollapserProperties properties; + private final HystrixRollingPercentile percentileBatchSize; + private final HystrixRollingPercentile percentileShardSize; - protected HystrixCollapserMetrics(HystrixCollapserKey key, HystrixCollapserProperties properties) { + /* package */HystrixCollapserMetrics(HystrixCollapserKey key, HystrixCollapserProperties properties) { + counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); this.key = key; this.properties = properties; + + this.percentileBatchSize = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); + this.percentileShardSize = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); } /** @@ -112,11 +120,13 @@ public HystrixCollapserProperties getProperties() { * Percentile such as 50, 99, or 99.5. * @return batch size */ - public abstract int getBatchSizePercentile(double percentile); - - public abstract int getBatchSizeMean(); + public int getBatchSizePercentile(double percentile) { + return percentileBatchSize.getPercentile(percentile); + } - protected abstract void addBatchSize(int batchSize); + public int getBatchSizeMean() { + return percentileBatchSize.getMean(); + } /** * Retrieve the shard size for the {@link HystrixCollapser} being invoked at a given percentile. @@ -127,26 +137,39 @@ public HystrixCollapserProperties getProperties() { * Percentile such as 50, 99, or 99.5. * @return batch size */ - public abstract int getShardSizePercentile(double percentile); - - public abstract int getShardSizeMean(); + public int getShardSizePercentile(double percentile) { + return percentileShardSize.getPercentile(percentile); + } - protected abstract void addShardSize(int shardSize); + public int getShardSizeMean() { + return percentileShardSize.getMean(); + } public void markRequestBatched() { - addEvent(HystrixRollingNumberEvent.COLLAPSER_REQUEST_BATCHED); + counter.increment(HystrixRollingNumberEvent.COLLAPSER_REQUEST_BATCHED); } public void markResponseFromCache() { - addEvent(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE); + counter.increment(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE); } public void markBatch(int batchSize) { - addBatchSize(batchSize); - addEvent(HystrixRollingNumberEvent.COLLAPSER_BATCH); + percentileBatchSize.addValue(batchSize); + counter.increment(HystrixRollingNumberEvent.COLLAPSER_BATCH); } public void markShards(int numShards) { - addShardSize(numShards); + percentileShardSize.addValue(numShards); + } + + + @Override + public long getCumulativeCount(HystrixRollingNumberEvent event) { + return counter.getCumulativeSum(event); + } + + @Override + public long getRollingCount(HystrixRollingNumberEvent event) { + return counter.getRollingSum(event); } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java index 5e80d0552..62b85bfa0 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; @@ -34,7 +33,8 @@ */ public abstract class HystrixCommandMetrics extends HystrixMetrics { - private final AtomicInteger concurrentExecutionCount = new AtomicInteger(); + /* strategy: HystrixMetricsCollection */ + protected HystrixMetricsCollection metricsCollection; // String is HystrixCommandKey.name() (we can't use HystrixCommandKey directly as we can't guarantee it implements hashcode/equals correctly) private static final ConcurrentHashMap metrics = new ConcurrentHashMap(); @@ -131,7 +131,7 @@ public static Collection getInstances() { private final HystrixThreadPoolKey threadPoolKey; private final HystrixEventNotifier eventNotifier; - protected HystrixCommandMetrics(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { + /* package */HystrixCommandMetrics(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { this.key = key; this.group = commandGroup; this.threadPoolKey = threadPoolKey; @@ -230,31 +230,16 @@ public HystrixCommandProperties getProperties() { /** * Current number of concurrent executions of {@link HystrixCommand#run()}; - * + * * @return int */ - public int getCurrentConcurrentExecutionCount() { - return concurrentExecutionCount.get(); - } + public abstract int getCurrentConcurrentExecutionCount(); - /** - * Increment concurrent requests counter. - */ - /* package */ void incrementConcurrentExecutionCount() { - int numConcurrent = concurrentExecutionCount.incrementAndGet(); - updateRollingMax(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE, (long) numConcurrent); - } + protected abstract void addEvent(HystrixRollingNumberEvent event); - /** - * Decrement concurrent requests counter. - */ - /* package */ void decrementConcurrentExecutionCount() { - concurrentExecutionCount.decrementAndGet(); - } + protected abstract void addEventWithValue(HystrixRollingNumberEvent event, int count); - public long getRollingMaxConcurrentExecutions() { - return getRollingMax(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); - } + protected abstract long getRollingSum(HystrixRollingNumberEvent event); /** * When a {@link HystrixCommand} successfully completes it will call this method to report its success along with how long the execution took. @@ -388,10 +373,24 @@ public long getRollingMaxConcurrentExecutions() { addEvent(HystrixRollingNumberEvent.FALLBACK_EMIT); } + + /** + * Increment concurrent requests counter. + */ + /* package */ abstract void incrementConcurrentExecutionCount(); + + /** + * Decrement concurrent requests counter. + */ + /* package */ abstract void decrementConcurrentExecutionCount(); + + public abstract long getRollingMaxConcurrentExecutions(); + + /** * Execution time of {@link HystrixCommand#run()}. */ - protected abstract void addCommandExecutionTime(long duration); + /* package */abstract void addCommandExecutionTime(long duration); /** * Complete execution time of {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} (queue is considered complete once the work is finished and {@link Future#get} is capable of @@ -399,15 +398,7 @@ public long getRollingMaxConcurrentExecutions() { *

* This differs from {@link #addCommandExecutionTime} in that this covers all of the threading and scheduling overhead, not just the execution of the {@link HystrixCommand#run()} method. */ - protected abstract void addUserThreadExecutionTime(long duration); - - protected abstract void clear(); - - /* package */ void resetCounter() { - clear(); - lastHealthCountsSnapshot.set(System.currentTimeMillis()); - healthCountsSnapshot = new HealthCounts(0, 0, 0); - } + /* package */abstract void addUserThreadExecutionTime(long duration); private volatile HealthCounts healthCountsSnapshot = new HealthCounts(0, 0, 0); private volatile AtomicLong lastHealthCountsSnapshot = new AtomicLong(System.currentTimeMillis()); @@ -426,12 +417,12 @@ public final HealthCounts getHealthCounts() { if (lastHealthCountsSnapshot.compareAndSet(lastTime, currentTime)) { // our thread won setting the snapshot time so we will proceed with generating a new snapshot // losing threads will continue using the old snapshot - long success = getRollingCount(HystrixRollingNumberEvent.SUCCESS); - long failure = getRollingCount(HystrixRollingNumberEvent.FAILURE); // fallbacks occur on this - long timeout = getRollingCount(HystrixRollingNumberEvent.TIMEOUT); // fallbacks occur on this - long threadPoolRejected = getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); // fallbacks occur on this - long semaphoreRejected = getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); // fallbacks occur on this - long shortCircuited = getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED); // fallbacks occur on this + long success = getRollingSum(HystrixRollingNumberEvent.SUCCESS); + long failure = getRollingSum(HystrixRollingNumberEvent.FAILURE); // fallbacks occur on this + long timeout = getRollingSum(HystrixRollingNumberEvent.TIMEOUT); // fallbacks occur on this + long threadPoolRejected = getRollingSum(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); // fallbacks occur on this + long semaphoreRejected = getRollingSum(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); // fallbacks occur on this + long shortCircuited = getRollingSum(HystrixRollingNumberEvent.SHORT_CIRCUITED); // fallbacks occur on this long totalCount = failure + success + timeout + threadPoolRejected + shortCircuited + semaphoreRejected; long errorCount = failure + timeout + threadPoolRejected + shortCircuited + semaphoreRejected; int errorPercentage = 0; @@ -446,6 +437,14 @@ public final HealthCounts getHealthCounts() { return healthCountsSnapshot; } + /* package */ abstract void clear(); + + /* package */ void resetCounter() { + clear(); + lastHealthCountsSnapshot.set(System.currentTimeMillis()); + healthCountsSnapshot = new HealthCounts(0, 0, 0); + } + /** * Number of requests during rolling window. * Number that failed (failure + success + timeout + threadPoolRejected + shortCircuited + semaphoreRejected). diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java similarity index 76% rename from hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java rename to hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java index 8fea6bced..ef4f12d84 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCommandMetricsSummary.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java @@ -13,27 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.netflix.hystrix.strategy.metrics; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; +package com.netflix.hystrix; + +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.netflix.hystrix.exception.HystrixBadRequestException; +import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; import com.netflix.hystrix.util.HystrixRollingNumber; import com.netflix.hystrix.util.HystrixRollingNumberEvent; import com.netflix.hystrix.util.HystrixRollingPercentile; /** - * Used by {@link HystrixCommand} to record metrics into {@link HystrixRollingNumber} and {@link HystrixRollingPercentile} summary data structures. + * Used by {@link HystrixCommand} to record metrics. */ public class HystrixCommandMetricsSummary extends HystrixCommandMetrics { private final HystrixRollingNumber counter; private final HystrixRollingPercentile percentileExecution; private final HystrixRollingPercentile percentileTotal; + private final AtomicInteger concurrentExecutionCount = new AtomicInteger(); public HystrixCommandMetricsSummary(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { super(key, commandGroup, threadPoolKey, properties, eventNotifier); @@ -42,70 +49,11 @@ public HystrixCommandMetricsSummary(HystrixCommandKey key, HystrixCommandGroupKe this.percentileTotal = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); } - - @Override - protected void clear() { - // TODO can we do without this somehow? - counter.reset(); - } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - counter.increment(event); - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - counter.add(event, value); - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - counter.updateRollingMax(event, value); - } - - @Override - protected long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } - - public long getRollingMaxConcurrentExecutions() { - return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); - } - - /** - * Execution time of {@link HystrixCommand#run()}. - */ - @Override - protected void addCommandExecutionTime(long duration) { - percentileExecution.addValue((int) duration); - } - - /** - * Complete HystrixCommand execution (either via completion of Hystrix work / timeout / failure / fail-fast - *

- * This differs from {@link #addCommandExecutionTime} in that this covers all of the threading and scheduling overhead, not just the execution of the {@link HystrixCommand#run()} method. - */ - @Override - protected void addUserThreadExecutionTime(long duration) { - percentileTotal.addValue((int) duration); - } - /** * Retrieve the execution time (in milliseconds) for the {@link HystrixCommand#run()} method being invoked at a given percentile. *

* Percentile capture and calculation is configured via {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * + * * @param percentile * Percentile such as 50, 99, or 99.5. * @return int time in milliseconds @@ -118,7 +66,7 @@ public int getExecutionTimePercentile(double percentile) { * The mean (average) execution time (in milliseconds) for the {@link HystrixCommand#run()}. *

* This uses the same backing data as {@link #getExecutionTimePercentile}; - * + * * @return int time in milliseconds */ public int getExecutionTimeMean() { @@ -141,7 +89,7 @@ public int getExecutionTimeMean() { * the overhead of queuing, executing and waiting for a thread to invoke {@link HystrixCommand#run()} . *

* Percentile capture and calculation is configured via {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * + * * @param percentile * Percentile such as 50, 99, or 99.5. * @return int time in milliseconds @@ -154,10 +102,88 @@ public int getTotalTimePercentile(double percentile) { * The mean (average) execution time (in milliseconds) for {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()}. *

* This uses the same backing data as {@link #getTotalTimePercentile}; - * + * * @return int time in milliseconds */ public int getTotalTimeMean() { return percentileTotal.getMean(); } + + @Override + /* package */void clear() { + // TODO can we do without this somehow? + counter.reset(); + } + + /** + * Current number of concurrent executions of {@link HystrixCommand#run()}; + * + * @return int + */ + public int getCurrentConcurrentExecutionCount() { + return concurrentExecutionCount.get(); + } + + @Override + protected void addEvent(HystrixRollingNumberEvent event) { + counter.increment(event); + } + + @Override + protected void addEventWithValue(HystrixRollingNumberEvent event, int count) { + counter.add(event, count); + } + + @Override + protected long getRollingSum(HystrixRollingNumberEvent event) { + return counter.getRollingSum(event); + } + + /** + * Increment concurrent requests counter. + */ + /* package */void incrementConcurrentExecutionCount() { + int numConcurrent = concurrentExecutionCount.incrementAndGet(); + counter.updateRollingMax(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE, (long) numConcurrent); + } + + /** + * Decrement concurrent requests counter. + */ + /* package */void decrementConcurrentExecutionCount() { + concurrentExecutionCount.decrementAndGet(); + } + + public long getRollingMaxConcurrentExecutions() { + return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); + } + + /** + * Execution time of {@link HystrixCommand#run()}. + */ + @Override + /* package */void addCommandExecutionTime(long duration) { + percentileExecution.addValue((int) duration); + } + + /** + * Complete execution time of {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} (queue is considered complete once the work is finished and {@link Future#get} is capable of + * retrieving the value. + *

+ * This differs from {@link #addCommandExecutionTime} in that this covers all of the threading and scheduling overhead, not just the execution of the {@link HystrixCommand#run()} method. + */ + @Override + /* package */void addUserThreadExecutionTime(long duration) { + percentileTotal.addValue((int) duration); + } + + @Override + public long getCumulativeCount(HystrixRollingNumberEvent event) { + return counter.getCumulativeSum(event); + } + + @Override + public long getRollingCount(HystrixRollingNumberEvent event) { + return counter.getCumulativeSum(event); + } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java index 50a1a497d..79db3bbe9 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java @@ -41,12 +41,4 @@ public abstract class HystrixMetrics { * @return long rolling count */ public abstract long getRollingCount(HystrixRollingNumberEvent event); - - protected abstract void addEvent(HystrixRollingNumberEvent event); - - protected abstract void addEventWithValue(HystrixRollingNumberEvent event, long value); - - protected abstract void updateRollingMax(HystrixRollingNumberEvent event, long value); - - protected abstract long getRollingMax(HystrixRollingNumberEvent event); } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java index cb3d6df5e..56a6bb9fc 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java @@ -21,8 +21,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadPoolExecutor; -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +30,12 @@ /** * Used by {@link HystrixThreadPool} to record metrics. */ -public abstract class HystrixThreadPoolMetrics extends HystrixMetrics { +public class HystrixThreadPoolMetrics extends HystrixMetrics { + + private final HystrixRollingNumber counter; + + @SuppressWarnings("unused") + private static final Logger logger = LoggerFactory.getLogger(HystrixThreadPoolMetrics.class); // String is HystrixThreadPoolKey.name() (we can't use HystrixThreadPoolKey directly as we can't guarantee it implements hashcode/equals correctly) private static final ConcurrentHashMap metrics = new ConcurrentHashMap(); @@ -57,8 +60,7 @@ public static HystrixThreadPoolMetrics getInstance(HystrixThreadPoolKey key, Thr return threadPoolMetrics; } // it doesn't exist so we need to create it - HystrixMetricsCollection metricsCollectionStrategy = HystrixPlugins.getInstance().getMetricsCollection(); - threadPoolMetrics = metricsCollectionStrategy.getThreadPoolMetricsInstance(key, threadPool, properties); + threadPoolMetrics = new HystrixThreadPoolMetrics(key, threadPool, properties); // attempt to store it (race other threads) HystrixThreadPoolMetrics existing = metrics.putIfAbsent(key.name(), threadPoolMetrics); if (existing == null) { @@ -102,7 +104,8 @@ public static Collection getInstances() { private final ThreadPoolExecutor threadPool; private final HystrixThreadPoolProperties properties; - protected HystrixThreadPoolMetrics(HystrixThreadPoolKey threadPoolKey, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { + private HystrixThreadPoolMetrics(HystrixThreadPoolKey threadPoolKey, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { + this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); this.threadPoolKey = threadPoolKey; this.threadPool = threadPool; this.properties = properties; @@ -212,7 +215,7 @@ public Number getCurrentQueueSize() { */ public void markThreadExecution() { // increment the count - addEvent(HystrixRollingNumberEvent.THREAD_EXECUTION); + counter.increment(HystrixRollingNumberEvent.THREAD_EXECUTION); setMaxActiveThreads(); } @@ -251,17 +254,27 @@ public void markThreadCompletion() { * @return rolling max active threads */ public long getRollingMaxActiveThreads() { - return getRollingMax(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE); + return counter.getRollingMaxValue(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE); } private void setMaxActiveThreads() { - updateRollingMax(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE, threadPool.getActiveCount()); + counter.updateRollingMax(HystrixRollingNumberEvent.THREAD_MAX_ACTIVE, threadPool.getActiveCount()); } /** * Invoked each time a command is rejected from the thread-pool */ public void markThreadRejection() { - addEvent(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); + counter.increment(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); + } + + @Override + public long getCumulativeCount(HystrixRollingNumberEvent event) { + return 0; + } + + @Override + public long getRollingCount(HystrixRollingNumberEvent event) { + return 0; } } \ No newline at end of file diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.java deleted file mode 100644 index 30c48e3cb..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixCollapserMetricsSummary.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.strategy.metrics; - -import com.netflix.hystrix.HystrixCollapser; -import com.netflix.hystrix.HystrixCollapserKey; -import com.netflix.hystrix.HystrixCollapserMetrics; -import com.netflix.hystrix.HystrixCollapserProperties; -import com.netflix.hystrix.util.HystrixRollingNumber; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import com.netflix.hystrix.util.HystrixRollingPercentile; - -/** - * Used by {@link HystrixCollapser} to record metrics. - * {@link com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier} not hooked up yet. It may be in the future. - */ -public class HystrixCollapserMetricsSummary extends HystrixCollapserMetrics { - - private final HystrixRollingNumber counter; - private final HystrixRollingPercentile percentileBatchSize; - private final HystrixRollingPercentile percentileShardSize; - - /* package */HystrixCollapserMetricsSummary(HystrixCollapserKey key, HystrixCollapserProperties properties) { - super(key, properties); - this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); - this.percentileBatchSize = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); - this.percentileShardSize = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); - } - - /** - * Retrieve the batch size for the {@link HystrixCollapser} being invoked at a given percentile. - *

- * Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * - * @param percentile - * Percentile such as 50, 99, or 99.5. - * @return batch size - */ - @Override - public int getBatchSizePercentile(double percentile) { - return percentileBatchSize.getPercentile(percentile); - } - - @Override - public int getBatchSizeMean() { - return percentileBatchSize.getMean(); - } - - @Override - protected void addBatchSize(int batchSize) { - percentileBatchSize.addValue(batchSize); - } - - /** - * Retrieve the shard size for the {@link HystrixCollapser} being invoked at a given percentile. - *

- * Percentile capture and calculation is configured via {@link HystrixCollapserProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * - * @param percentile - * Percentile such as 50, 99, or 99.5. - * @return batch size - */ - @Override - public int getShardSizePercentile(double percentile) { - return percentileShardSize.getPercentile(percentile); - } - - @Override - public int getShardSizeMean() { - return percentileShardSize.getMean(); - } - - @Override - protected void addShardSize(int shardSize) { - percentileShardSize.addValue(shardSize); - } - - public void markShards(int numShards) { - percentileShardSize.addValue(numShards); - } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - counter.increment(event); - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - counter.add(event, value); - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - counter.updateRollingMax(event, value); - } - - @Override - protected long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java index dd61ef912..7d4bdacd3 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java @@ -15,28 +15,17 @@ */ package com.netflix.hystrix.strategy.metrics; -import com.netflix.hystrix.HystrixCollapserKey; -import com.netflix.hystrix.HystrixCollapserMetrics; -import com.netflix.hystrix.HystrixCollapserProperties; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandMetrics; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import java.util.concurrent.ThreadPoolExecutor; - public abstract class HystrixMetricsCollection { /** * Generate an instance of {@link HystrixCommandMetrics} */ - public abstract HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier); - - public abstract HystrixThreadPoolMetrics getThreadPoolMetricsInstance(HystrixThreadPoolKey key, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties); - - public abstract HystrixCollapserMetrics getCollapserMetricsInstance(HystrixCollapserKey key, HystrixCollapserProperties properties); + public abstract HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey nonNullThreadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier); } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java index 52ca29bd8..86aca7f73 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java @@ -15,20 +15,14 @@ */ package com.netflix.hystrix.strategy.metrics; -import com.netflix.hystrix.HystrixCollapserKey; -import com.netflix.hystrix.HystrixCollapserMetrics; -import com.netflix.hystrix.HystrixCollapserProperties; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandMetrics; +import com.netflix.hystrix.HystrixCommandMetricsSummary; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import java.util.concurrent.ThreadPoolExecutor; - /** * Default implementation of {@link HystrixMetricsCollection}. *

@@ -48,17 +42,7 @@ private HystrixMetricsCollectionDefault() { } @Override - public HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { - return new HystrixCommandMetricsSummary(key, commandGroup, threadPoolKey, properties, eventNotifier); - } - - @Override - public HystrixThreadPoolMetrics getThreadPoolMetricsInstance(HystrixThreadPoolKey key, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { - return new HystrixThreadPoolMetricsSummary(key, threadPool, properties); - } - - @Override - public HystrixCollapserMetrics getCollapserMetricsInstance(HystrixCollapserKey key, HystrixCollapserProperties properties) { - return new HystrixCollapserMetricsSummary(key, properties); + public HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey nonNullThreadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { + return new HystrixCommandMetricsSummary(key, commandGroup, nonNullThreadPoolKey, properties, eventNotifier); } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java deleted file mode 100644 index 1408ad944..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixThreadPoolMetricsSummary.java +++ /dev/null @@ -1,69 +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.strategy.metrics; - -import java.util.concurrent.ThreadPoolExecutor; - -import com.netflix.hystrix.HystrixThreadPool; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.util.HystrixRollingNumber; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; - -/** - * Used by {@link HystrixThreadPool} to record metrics. - */ -public class HystrixThreadPoolMetricsSummary extends HystrixThreadPoolMetrics { - - private final HystrixRollingNumber counter; - - /* package */HystrixThreadPoolMetricsSummary(HystrixThreadPoolKey threadPoolKey, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { - super(threadPoolKey, threadPool, properties); - this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); - } - - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - counter.increment(event); - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, long value) { - counter.add(event, value); - } - - @Override - protected void updateRollingMax(HystrixRollingNumberEvent event, long value) { - counter.updateRollingMax(event, value); - } - - @Override - protected long getRollingMax(HystrixRollingNumberEvent event) { - return counter.getRollingMaxValue(event); - } -} diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java index 00874c034..61b83296b 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java @@ -21,7 +21,6 @@ import java.util.Random; -import com.netflix.hystrix.strategy.metrics.HystrixCommandMetricsSummary; import org.junit.Ignore; import org.junit.Test; diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java index c3c3a9926..4d8ea71bc 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import com.netflix.hystrix.strategy.metrics.HystrixCommandMetricsSummary; import org.junit.Test; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifierDefault; From 754bd602cf8aab8ac38fb085d17b2ec21dbe915d Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:03:37 -0700 Subject: [PATCH 7/9] Revert "Made HystrixCommandMetrics.getHealthCounts() final" This reverts commit 795e937d8be8e449f28d04b74c21370b0f5dd3f5. --- .../main/java/com/netflix/hystrix/HystrixCommandMetrics.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java index 62b85bfa0..dd8507b69 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -408,7 +408,8 @@ public HystrixCommandProperties getProperties() { * * @return {@link HealthCounts} */ - public final HealthCounts getHealthCounts() { + //TODO Should this be final? + public HealthCounts getHealthCounts() { // we put an interval between snapshots so high-volume commands don't // spend too much unnecessary time calculating metrics in very small time periods long lastTime = lastHealthCountsSnapshot.get(); From 520e941aef9974fa141b35b412639ccdf2f5a936 Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Wed, 14 Oct 2015 14:03:47 -0700 Subject: [PATCH 8/9] Revert "Added HystrixMetricsCollection plugin that allows for varying implementation of HystrixCommandMetrics" This reverts commit e1b0db0dc6609c1cdd64b1a8f85b2772d9ba24e1. --- .../hystrix/HystrixCommandMetricsSamples.java | 6 +- .../com/netflix/hystrix/AbstractCommand.java | 1 + .../hystrix/HystrixCollapserMetrics.java | 13 +- .../hystrix/HystrixCommandMetrics.java | 154 +++++++------- .../hystrix/HystrixCommandMetricsSummary.java | 189 ------------------ .../com/netflix/hystrix/HystrixMetrics.java | 15 +- .../hystrix/HystrixThreadPoolMetrics.java | 14 +- .../hystrix/strategy/HystrixPlugins.java | 42 ---- .../metrics/HystrixMetricsCollection.java | 31 --- .../HystrixMetricsCollectionDefault.java | 48 ----- .../hystrix/HystrixCircuitBreakerTest.java | 2 +- .../hystrix/HystrixCommandMetricsTest.java | 2 +- .../hystrix/HystrixThreadPoolMetricsTest.java | 15 ++ 13 files changed, 124 insertions(+), 408 deletions(-) delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java delete mode 100644 hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java diff --git a/hystrix-contrib/hystrix-rx-netty-metrics-stream/src/test/java/com/netflix/hystrix/HystrixCommandMetricsSamples.java b/hystrix-contrib/hystrix-rx-netty-metrics-stream/src/test/java/com/netflix/hystrix/HystrixCommandMetricsSamples.java index 02f8a787a..0c0e6215f 100644 --- a/hystrix-contrib/hystrix-rx-netty-metrics-stream/src/test/java/com/netflix/hystrix/HystrixCommandMetricsSamples.java +++ b/hystrix-contrib/hystrix-rx-netty-metrics-stream/src/test/java/com/netflix/hystrix/HystrixCommandMetricsSamples.java @@ -15,6 +15,8 @@ */ package com.netflix.hystrix; +import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifierDefault; + /** * Not very elegant, but there is no other way to create this data directly for testing * purposes, as {@link com.netflix.hystrix.HystrixCommandMetrics} has no public constructors, @@ -55,7 +57,7 @@ protected MyHystrixCommandProperties(HystrixCommandKey key) { static { HystrixCommandKey key = new MyHystrixCommandKey(); - SAMPLE_1 = HystrixCommandMetrics.getInstance(key, new MyHystrixCommandGroupKey(), new MyHystrixThreadPoolKey(), - new MyHystrixCommandProperties(key)); + SAMPLE_1 = new HystrixCommandMetrics(key, new MyHystrixCommandGroupKey(), new MyHystrixThreadPoolKey(), + new MyHystrixCommandProperties(key), HystrixEventNotifierDefault.getInstance()); } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java index ff39f6f48..873173d4b 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/AbstractCommand.java @@ -16,6 +16,7 @@ package com.netflix.hystrix; import java.lang.ref.Reference; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java index 369bb654e..54e04f7a2 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCollapserMetrics.java @@ -32,8 +32,6 @@ */ public class HystrixCollapserMetrics extends HystrixMetrics { - private final HystrixRollingNumber counter; - @SuppressWarnings("unused") private static final Logger logger = LoggerFactory.getLogger(HystrixCollapserMetrics.class); @@ -90,7 +88,7 @@ public static Collection getInstances() { private final HystrixRollingPercentile percentileShardSize; /* package */HystrixCollapserMetrics(HystrixCollapserKey key, HystrixCollapserProperties properties) { - counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); + super(new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get())); this.key = key; this.properties = properties; @@ -163,13 +161,4 @@ public void markShards(int numShards) { } - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java index dd8507b69..99152e196 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetrics.java @@ -19,22 +19,26 @@ import java.util.Collections; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.netflix.hystrix.exception.HystrixBadRequestException; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; +import com.netflix.hystrix.util.HystrixRollingNumber; import com.netflix.hystrix.util.HystrixRollingNumberEvent; +import com.netflix.hystrix.util.HystrixRollingPercentile; /** * Used by {@link HystrixCommand} to record metrics. */ -public abstract class HystrixCommandMetrics extends HystrixMetrics { +public class HystrixCommandMetrics extends HystrixMetrics { - /* strategy: HystrixMetricsCollection */ - protected HystrixMetricsCollection metricsCollection; + @SuppressWarnings("unused") + private static final Logger logger = LoggerFactory.getLogger(HystrixCommandMetrics.class); // String is HystrixCommandKey.name() (we can't use HystrixCommandKey directly as we can't guarantee it implements hashcode/equals correctly) private static final ConcurrentHashMap metrics = new ConcurrentHashMap(); @@ -76,6 +80,7 @@ public static HystrixCommandMetrics getInstance(HystrixCommandKey key, HystrixCo return commandMetrics; } // it doesn't exist so we need to create it + //now check to see if we need to create a synthetic threadPoolKey HystrixThreadPoolKey nonNullThreadPoolKey; if (threadPoolKey == null) { @@ -83,10 +88,7 @@ public static HystrixCommandMetrics getInstance(HystrixCommandKey key, HystrixCo } else { nonNullThreadPoolKey = threadPoolKey; } - HystrixMetricsCollection metricsCollectionStrategy = HystrixPlugins.getInstance().getMetricsCollection(); - HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); - commandMetrics = metricsCollectionStrategy.getCommandMetricsInstance(key, commandGroup, nonNullThreadPoolKey, properties, eventNotifier); - + commandMetrics = new HystrixCommandMetrics(key, commandGroup, nonNullThreadPoolKey, properties, HystrixPlugins.getInstance().getEventNotifier()); // attempt to store it (race other threads) HystrixCommandMetrics existing = metrics.putIfAbsent(key.name(), commandMetrics); if (existing == null) { @@ -126,16 +128,22 @@ public static Collection getInstances() { } private final HystrixCommandProperties properties; + private final HystrixRollingPercentile percentileExecution; + private final HystrixRollingPercentile percentileTotal; private final HystrixCommandKey key; private final HystrixCommandGroupKey group; private final HystrixThreadPoolKey threadPoolKey; + private final AtomicInteger concurrentExecutionCount = new AtomicInteger(); private final HystrixEventNotifier eventNotifier; /* package */HystrixCommandMetrics(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { + super(new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get())); this.key = key; this.group = commandGroup; this.threadPoolKey = threadPoolKey; this.properties = properties; + this.percentileExecution = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); + this.percentileTotal = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); this.eventNotifier = eventNotifier; } @@ -185,7 +193,9 @@ public HystrixCommandProperties getProperties() { * Percentile such as 50, 99, or 99.5. * @return int time in milliseconds */ - public abstract int getExecutionTimePercentile(double percentile); + public int getExecutionTimePercentile(double percentile) { + return percentileExecution.getPercentile(percentile); + } /** * The mean (average) execution time (in milliseconds) for the {@link HystrixCommand#run()}. @@ -194,7 +204,9 @@ public HystrixCommandProperties getProperties() { * * @return int time in milliseconds */ - public abstract int getExecutionTimeMean(); + public int getExecutionTimeMean() { + return percentileExecution.getMean(); + } /** * Retrieve the total end-to-end execution time (in milliseconds) for {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} at a given percentile. @@ -217,29 +229,36 @@ public HystrixCommandProperties getProperties() { * Percentile such as 50, 99, or 99.5. * @return int time in milliseconds */ - public abstract int getTotalTimePercentile(double percentile); + public int getTotalTimePercentile(double percentile) { + return percentileTotal.getPercentile(percentile); + } /** - * The mean (average) execution time (in milliseconds) for command execution. + * The mean (average) execution time (in milliseconds) for {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()}. *

* This uses the same backing data as {@link #getTotalTimePercentile}; * * @return int time in milliseconds */ - public abstract int getTotalTimeMean(); + public int getTotalTimeMean() { + return percentileTotal.getMean(); + } + + /* package */void resetCounter() { + // TODO can we do without this somehow? + counter.reset(); + lastHealthCountsSnapshot.set(System.currentTimeMillis()); + healthCountsSnapshot = new HealthCounts(0, 0, 0); + } /** * Current number of concurrent executions of {@link HystrixCommand#run()}; * * @return int */ - public abstract int getCurrentConcurrentExecutionCount(); - - protected abstract void addEvent(HystrixRollingNumberEvent event); - - protected abstract void addEventWithValue(HystrixRollingNumberEvent event, int count); - - protected abstract long getRollingSum(HystrixRollingNumberEvent event); + public int getCurrentConcurrentExecutionCount() { + return concurrentExecutionCount.get(); + } /** * When a {@link HystrixCommand} successfully completes it will call this method to report its success along with how long the execution took. @@ -248,7 +267,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markSuccess(long duration) { eventNotifier.markEvent(HystrixEventType.SUCCESS, key); - addEvent(HystrixRollingNumberEvent.SUCCESS); + counter.increment(HystrixRollingNumberEvent.SUCCESS); } /** @@ -258,7 +277,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markFailure(long duration) { eventNotifier.markEvent(HystrixEventType.FAILURE, key); - addEvent(HystrixRollingNumberEvent.FAILURE); + counter.increment(HystrixRollingNumberEvent.FAILURE); } /** @@ -269,7 +288,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markTimeout(long duration) { eventNotifier.markEvent(HystrixEventType.TIMEOUT, key); - addEvent(HystrixRollingNumberEvent.TIMEOUT); + counter.increment(HystrixRollingNumberEvent.TIMEOUT); } /** @@ -277,7 +296,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markShortCircuited() { eventNotifier.markEvent(HystrixEventType.SHORT_CIRCUITED, key); - addEvent(HystrixRollingNumberEvent.SHORT_CIRCUITED); + counter.increment(HystrixRollingNumberEvent.SHORT_CIRCUITED); } /** @@ -285,7 +304,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markThreadPoolRejection() { eventNotifier.markEvent(HystrixEventType.THREAD_POOL_REJECTED, key); - addEvent(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); + counter.increment(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); } /** @@ -293,7 +312,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markSemaphoreRejection() { eventNotifier.markEvent(HystrixEventType.SEMAPHORE_REJECTED, key); - addEvent(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); + counter.increment(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); } /** @@ -301,7 +320,26 @@ public HystrixCommandProperties getProperties() { */ /* package */void markBadRequest(long duration) { eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, key); - addEvent(HystrixRollingNumberEvent.BAD_REQUEST); + counter.increment(HystrixRollingNumberEvent.BAD_REQUEST); + } + + /** + * Increment concurrent requests counter. + */ + /* package */void incrementConcurrentExecutionCount() { + int numConcurrent = concurrentExecutionCount.incrementAndGet(); + counter.updateRollingMax(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE, (long) numConcurrent); + } + + /** + * Decrement concurrent requests counter. + */ + /* package */void decrementConcurrentExecutionCount() { + concurrentExecutionCount.decrementAndGet(); + } + + public long getRollingMaxConcurrentExecutions() { + return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); } /** @@ -309,7 +347,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markFallbackSuccess() { eventNotifier.markEvent(HystrixEventType.FALLBACK_SUCCESS, key); - addEvent(HystrixRollingNumberEvent.FALLBACK_SUCCESS); + counter.increment(HystrixRollingNumberEvent.FALLBACK_SUCCESS); } /** @@ -317,7 +355,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markFallbackFailure() { eventNotifier.markEvent(HystrixEventType.FALLBACK_FAILURE, key); - addEvent(HystrixRollingNumberEvent.FALLBACK_FAILURE); + counter.increment(HystrixRollingNumberEvent.FALLBACK_FAILURE); } /** @@ -325,7 +363,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markFallbackRejection() { eventNotifier.markEvent(HystrixEventType.FALLBACK_REJECTION, key); - addEvent(HystrixRollingNumberEvent.FALLBACK_REJECTION); + counter.increment(HystrixRollingNumberEvent.FALLBACK_REJECTION); } /** @@ -334,17 +372,17 @@ public HystrixCommandProperties getProperties() { */ /* package */void markExceptionThrown() { eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, key); - addEvent(HystrixRollingNumberEvent.EXCEPTION_THROWN); + counter.increment(HystrixRollingNumberEvent.EXCEPTION_THROWN); } /** * When a command is fronted by an {@link HystrixCollapser} then this marks how many requests are collapsed into the single command execution. - * + * * @param numRequestsCollapsedToBatch number of requests which got batched */ /* package */void markCollapsed(int numRequestsCollapsedToBatch) { eventNotifier.markEvent(HystrixEventType.COLLAPSED, key); - addEventWithValue(HystrixRollingNumberEvent.COLLAPSED, numRequestsCollapsedToBatch); + counter.add(HystrixRollingNumberEvent.COLLAPSED, numRequestsCollapsedToBatch); } /** @@ -354,7 +392,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markResponseFromCache() { eventNotifier.markEvent(HystrixEventType.RESPONSE_FROM_CACHE, key); - addEvent(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE); + counter.increment(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE); } /** @@ -362,7 +400,7 @@ public HystrixCommandProperties getProperties() { */ /* package */void markEmit() { eventNotifier.markEvent(HystrixEventType.EMIT, getCommandKey()); - addEvent(HystrixRollingNumberEvent.EMIT); + counter.increment(HystrixRollingNumberEvent.EMIT); } /** @@ -370,27 +408,15 @@ public HystrixCommandProperties getProperties() { */ /* package */void markFallbackEmit() { eventNotifier.markEvent(HystrixEventType.FALLBACK_EMIT, getCommandKey()); - addEvent(HystrixRollingNumberEvent.FALLBACK_EMIT); + counter.increment(HystrixRollingNumberEvent.FALLBACK_EMIT); } - - /** - * Increment concurrent requests counter. - */ - /* package */ abstract void incrementConcurrentExecutionCount(); - - /** - * Decrement concurrent requests counter. - */ - /* package */ abstract void decrementConcurrentExecutionCount(); - - public abstract long getRollingMaxConcurrentExecutions(); - - /** * Execution time of {@link HystrixCommand#run()}. */ - /* package */abstract void addCommandExecutionTime(long duration); + /* package */void addCommandExecutionTime(long duration) { + percentileExecution.addValue((int) duration); + } /** * Complete execution time of {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} (queue is considered complete once the work is finished and {@link Future#get} is capable of @@ -398,7 +424,9 @@ public HystrixCommandProperties getProperties() { *

* This differs from {@link #addCommandExecutionTime} in that this covers all of the threading and scheduling overhead, not just the execution of the {@link HystrixCommand#run()} method. */ - /* package */abstract void addUserThreadExecutionTime(long duration); + /* package */void addUserThreadExecutionTime(long duration) { + percentileTotal.addValue((int) duration); + } private volatile HealthCounts healthCountsSnapshot = new HealthCounts(0, 0, 0); private volatile AtomicLong lastHealthCountsSnapshot = new AtomicLong(System.currentTimeMillis()); @@ -408,7 +436,6 @@ public HystrixCommandProperties getProperties() { * * @return {@link HealthCounts} */ - //TODO Should this be final? public HealthCounts getHealthCounts() { // we put an interval between snapshots so high-volume commands don't // spend too much unnecessary time calculating metrics in very small time periods @@ -418,12 +445,12 @@ public HealthCounts getHealthCounts() { if (lastHealthCountsSnapshot.compareAndSet(lastTime, currentTime)) { // our thread won setting the snapshot time so we will proceed with generating a new snapshot // losing threads will continue using the old snapshot - long success = getRollingSum(HystrixRollingNumberEvent.SUCCESS); - long failure = getRollingSum(HystrixRollingNumberEvent.FAILURE); // fallbacks occur on this - long timeout = getRollingSum(HystrixRollingNumberEvent.TIMEOUT); // fallbacks occur on this - long threadPoolRejected = getRollingSum(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); // fallbacks occur on this - long semaphoreRejected = getRollingSum(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); // fallbacks occur on this - long shortCircuited = getRollingSum(HystrixRollingNumberEvent.SHORT_CIRCUITED); // fallbacks occur on this + long success = counter.getRollingSum(HystrixRollingNumberEvent.SUCCESS); + long failure = counter.getRollingSum(HystrixRollingNumberEvent.FAILURE); // fallbacks occur on this + long timeout = counter.getRollingSum(HystrixRollingNumberEvent.TIMEOUT); // fallbacks occur on this + long threadPoolRejected = counter.getRollingSum(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); // fallbacks occur on this + long semaphoreRejected = counter.getRollingSum(HystrixRollingNumberEvent.SEMAPHORE_REJECTED); // fallbacks occur on this + long shortCircuited = counter.getRollingSum(HystrixRollingNumberEvent.SHORT_CIRCUITED); // fallbacks occur on this long totalCount = failure + success + timeout + threadPoolRejected + shortCircuited + semaphoreRejected; long errorCount = failure + timeout + threadPoolRejected + shortCircuited + semaphoreRejected; int errorPercentage = 0; @@ -438,14 +465,6 @@ public HealthCounts getHealthCounts() { return healthCountsSnapshot; } - /* package */ abstract void clear(); - - /* package */ void resetCounter() { - clear(); - lastHealthCountsSnapshot.set(System.currentTimeMillis()); - healthCountsSnapshot = new HealthCounts(0, 0, 0); - } - /** * Number of requests during rolling window. * Number that failed (failure + success + timeout + threadPoolRejected + shortCircuited + semaphoreRejected). @@ -474,4 +493,5 @@ public int getErrorPercentage() { return errorPercentage; } } + } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java deleted file mode 100644 index ef4f12d84..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandMetricsSummary.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright 2012 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; - -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.hystrix.exception.HystrixBadRequestException; -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.util.HystrixRollingNumber; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import com.netflix.hystrix.util.HystrixRollingPercentile; - -/** - * Used by {@link HystrixCommand} to record metrics. - */ -public class HystrixCommandMetricsSummary extends HystrixCommandMetrics { - - private final HystrixRollingNumber counter; - private final HystrixRollingPercentile percentileExecution; - private final HystrixRollingPercentile percentileTotal; - private final AtomicInteger concurrentExecutionCount = new AtomicInteger(); - - public HystrixCommandMetricsSummary(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey threadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { - super(key, commandGroup, threadPoolKey, properties, eventNotifier); - this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); - this.percentileExecution = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); - this.percentileTotal = new HystrixRollingPercentile(properties.metricsRollingPercentileWindowInMilliseconds().get(), properties.metricsRollingPercentileWindowBuckets().get(), properties.metricsRollingPercentileBucketSize().get(), properties.metricsRollingPercentileEnabled()); - } - - /** - * Retrieve the execution time (in milliseconds) for the {@link HystrixCommand#run()} method being invoked at a given percentile. - *

- * Percentile capture and calculation is configured via {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * - * @param percentile - * Percentile such as 50, 99, or 99.5. - * @return int time in milliseconds - */ - public int getExecutionTimePercentile(double percentile) { - return percentileExecution.getPercentile(percentile); - } - - /** - * The mean (average) execution time (in milliseconds) for the {@link HystrixCommand#run()}. - *

- * This uses the same backing data as {@link #getExecutionTimePercentile}; - * - * @return int time in milliseconds - */ - public int getExecutionTimeMean() { - return percentileExecution.getMean(); - } - - /** - * Retrieve the total end-to-end execution time (in milliseconds) for {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} at a given percentile. - *

- * When execution is successful this would include time from {@link #getExecutionTimePercentile} but when execution - * is being rejected, short-circuited, or timed-out then the time will differ. - *

- * This time can be lower than {@link #getExecutionTimePercentile} when a timeout occurs and the backing - * thread that calls {@link HystrixCommand#run()} is still running. - *

- * When rejections or short-circuits occur then {@link HystrixCommand#run()} will not be executed and thus - * not contribute time to {@link #getExecutionTimePercentile} but time will still show up in this metric for the end-to-end time. - *

- * This metric gives visibility into the total cost of {@link HystrixCommand} execution including - * the overhead of queuing, executing and waiting for a thread to invoke {@link HystrixCommand#run()} . - *

- * Percentile capture and calculation is configured via {@link HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()} and other related properties. - * - * @param percentile - * Percentile such as 50, 99, or 99.5. - * @return int time in milliseconds - */ - public int getTotalTimePercentile(double percentile) { - return percentileTotal.getPercentile(percentile); - } - - /** - * The mean (average) execution time (in milliseconds) for {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()}. - *

- * This uses the same backing data as {@link #getTotalTimePercentile}; - * - * @return int time in milliseconds - */ - public int getTotalTimeMean() { - return percentileTotal.getMean(); - } - - @Override - /* package */void clear() { - // TODO can we do without this somehow? - counter.reset(); - } - - /** - * Current number of concurrent executions of {@link HystrixCommand#run()}; - * - * @return int - */ - public int getCurrentConcurrentExecutionCount() { - return concurrentExecutionCount.get(); - } - - @Override - protected void addEvent(HystrixRollingNumberEvent event) { - counter.increment(event); - } - - @Override - protected void addEventWithValue(HystrixRollingNumberEvent event, int count) { - counter.add(event, count); - } - - @Override - protected long getRollingSum(HystrixRollingNumberEvent event) { - return counter.getRollingSum(event); - } - - /** - * Increment concurrent requests counter. - */ - /* package */void incrementConcurrentExecutionCount() { - int numConcurrent = concurrentExecutionCount.incrementAndGet(); - counter.updateRollingMax(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE, (long) numConcurrent); - } - - /** - * Decrement concurrent requests counter. - */ - /* package */void decrementConcurrentExecutionCount() { - concurrentExecutionCount.decrementAndGet(); - } - - public long getRollingMaxConcurrentExecutions() { - return counter.getRollingMaxValue(HystrixRollingNumberEvent.COMMAND_MAX_ACTIVE); - } - - /** - * Execution time of {@link HystrixCommand#run()}. - */ - @Override - /* package */void addCommandExecutionTime(long duration) { - percentileExecution.addValue((int) duration); - } - - /** - * Complete execution time of {@link HystrixCommand#execute()} or {@link HystrixCommand#queue()} (queue is considered complete once the work is finished and {@link Future#get} is capable of - * retrieving the value. - *

- * This differs from {@link #addCommandExecutionTime} in that this covers all of the threading and scheduling overhead, not just the execution of the {@link HystrixCommand#run()} method. - */ - @Override - /* package */void addUserThreadExecutionTime(long duration) { - percentileTotal.addValue((int) duration); - } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return counter.getCumulativeSum(event); - } -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java index 79db3bbe9..5850168d3 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixMetrics.java @@ -15,6 +15,7 @@ */ package com.netflix.hystrix; +import com.netflix.hystrix.util.HystrixRollingNumber; import com.netflix.hystrix.util.HystrixRollingNumberEvent; /** @@ -22,6 +23,11 @@ */ public abstract class HystrixMetrics { + protected final HystrixRollingNumber counter; + + protected HystrixMetrics(HystrixRollingNumber counter) { + this.counter = counter; + } /** * Get the cumulative count since the start of the application for the given {@link HystrixRollingNumberEvent}. * @@ -29,7 +35,9 @@ public abstract class HystrixMetrics { * {@link HystrixRollingNumberEvent} of the event to retrieve a sum for * @return long cumulative count */ - public abstract long getCumulativeCount(HystrixRollingNumberEvent event); + public long getCumulativeCount(HystrixRollingNumberEvent event) { + return counter.getCumulativeSum(event); + } /** * Get the rolling count for the given {@link HystrixRollingNumberEvent}. @@ -40,5 +48,8 @@ public abstract class HystrixMetrics { * {@link HystrixRollingNumberEvent} of the event to retrieve a sum for * @return long rolling count */ - public abstract long getRollingCount(HystrixRollingNumberEvent event); + public long getRollingCount(HystrixRollingNumberEvent event) { + return counter.getRollingSum(event); + } + } diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java index 56a6bb9fc..8bfeb1ef7 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolMetrics.java @@ -32,8 +32,6 @@ */ public class HystrixThreadPoolMetrics extends HystrixMetrics { - private final HystrixRollingNumber counter; - @SuppressWarnings("unused") private static final Logger logger = LoggerFactory.getLogger(HystrixThreadPoolMetrics.class); @@ -105,7 +103,7 @@ public static Collection getInstances() { private final HystrixThreadPoolProperties properties; private HystrixThreadPoolMetrics(HystrixThreadPoolKey threadPoolKey, ThreadPoolExecutor threadPool, HystrixThreadPoolProperties properties) { - this.counter = new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get()); + super(new HystrixRollingNumber(properties.metricsRollingStatisticalWindowInMilliseconds().get(), properties.metricsRollingStatisticalWindowBuckets().get())); this.threadPoolKey = threadPoolKey; this.threadPool = threadPool; this.properties = properties; @@ -267,14 +265,4 @@ private void setMaxActiveThreads() { public void markThreadRejection() { counter.increment(HystrixRollingNumberEvent.THREAD_POOL_REJECTED); } - - @Override - public long getCumulativeCount(HystrixRollingNumberEvent event) { - return 0; - } - - @Override - public long getRollingCount(HystrixRollingNumberEvent event) { - return 0; - } } \ No newline at end of file diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java index da7558f8d..cf3edce8f 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java @@ -26,8 +26,6 @@ import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifierDefault; import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHookDefault; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollection; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsCollectionDefault; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherDefault; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherFactory; @@ -50,7 +48,6 @@ public class HystrixPlugins { /* package */ final AtomicReference notifier = new AtomicReference(); /* package */ final AtomicReference concurrencyStrategy = new AtomicReference(); /* package */ final AtomicReference metricsPublisher = new AtomicReference(); - /* package */ final AtomicReference metricsCollection = new AtomicReference(); /* package */ final AtomicReference propertiesFactory = new AtomicReference(); /* package */ final AtomicReference commandExecutionHook = new AtomicReference(); @@ -74,7 +71,6 @@ public static void reset() { getInstance().notifier.set(null); getInstance().concurrencyStrategy.set(null); getInstance().metricsPublisher.set(null); - getInstance().metricsCollection.set(null); getInstance().propertiesFactory.set(null); getInstance().commandExecutionHook.set(null); HystrixMetricsPublisherFactory.reset(); @@ -194,44 +190,6 @@ public void registerMetricsPublisher(HystrixMetricsPublisher impl) { } } - /** - * Retrieve instance of {@link HystrixMetricsCollection} to use based on order of precedence as defined in {@link HystrixPlugins} class header. - *

- * Override default by using {@link #registerMetricsCollection(HystrixMetricsCollection)} or setting property (via Archaius): - * hystrix.plugin.HystrixMetricsCollectionStrategy.implementation with the full classname to load. - * - * @return {@link HystrixMetricsCollection} implementation to use - */ - public HystrixMetricsCollection getMetricsCollection() { - if (metricsCollection.get() == null) { - // check for an implementation from Archaius first - Object impl = getPluginImplementationViaArchaius(HystrixMetricsCollection.class); - if (impl == null) { - // nothing set via Archaius so initialize with default - metricsCollection.compareAndSet(null, HystrixMetricsCollectionDefault.getInstance()); - // we don't return from here but call get() again in case of thread-race so the winner will always get returned - } else { - // we received an implementation from Archaius so use it - metricsCollection.compareAndSet(null, (HystrixMetricsCollection) impl); - } - } - return metricsCollection.get(); - } - - /** - * Register a {@link HystrixMetricsCollection} implementation as a global override of any injected or default implementations. - * - * @param impl - * {@link HystrixMetricsCollection} implementation - * @throws IllegalStateException - * if called more than once or after the default was initialized (if usage occurs before trying to register) - */ - public void registerMetricsCollection(HystrixMetricsCollection impl) { - if (!metricsCollection.compareAndSet(null, impl)) { - throw new IllegalStateException("Another HystrixMetricsCollectionStrategy was already registered."); - } - } - /** * Retrieve instance of {@link HystrixPropertiesStrategy} to use based on order of precedence as defined in {@link HystrixPlugins} class header. *

diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java deleted file mode 100644 index 7d4bdacd3..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollection.java +++ /dev/null @@ -1,31 +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.strategy.metrics; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; - -public abstract class HystrixMetricsCollection { - - /** - * Generate an instance of {@link HystrixCommandMetrics} - */ - public abstract HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey nonNullThreadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier); -} diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java b/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java deleted file mode 100644 index 86aca7f73..000000000 --- a/hystrix-core/src/main/java/com/netflix/hystrix/strategy/metrics/HystrixMetricsCollectionDefault.java +++ /dev/null @@ -1,48 +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.strategy.metrics; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandMetricsSummary; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; - -/** - * Default implementation of {@link HystrixMetricsCollection}. - *

- * See Wiki docs about plugins for more information. - * - * @ExcludeFromJavadoc - */ -public class HystrixMetricsCollectionDefault extends HystrixMetricsCollection { - - private static HystrixMetricsCollectionDefault INSTANCE = new HystrixMetricsCollectionDefault(); - - public static HystrixMetricsCollection getInstance() { - return INSTANCE; - } - - private HystrixMetricsCollectionDefault() { - } - - @Override - public HystrixCommandMetrics getCommandMetricsInstance(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixThreadPoolKey nonNullThreadPoolKey, HystrixCommandProperties properties, HystrixEventNotifier eventNotifier) { - return new HystrixCommandMetricsSummary(key, commandGroup, nonNullThreadPoolKey, properties, eventNotifier); - } -} diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java index 61b83296b..7e073f9fb 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java @@ -494,7 +494,7 @@ public void testLowVolumeDoesNotTripCircuit() { * Utility method for creating {@link HystrixCommandMetrics} for unit tests. */ private static HystrixCommandMetrics getMetrics(HystrixCommandProperties.Setter properties) { - return new HystrixCommandMetricsSummary(CommandKeyForUnitTest.KEY_ONE, CommandOwnerForUnitTest.OWNER_ONE, ThreadPoolKeyForUnitTest.THREAD_POOL_ONE, HystrixCommandPropertiesTest.asMock(properties), HystrixEventNotifierDefault.getInstance()); + return new HystrixCommandMetrics(CommandKeyForUnitTest.KEY_ONE, CommandOwnerForUnitTest.OWNER_ONE, ThreadPoolKeyForUnitTest.THREAD_POOL_ONE, HystrixCommandPropertiesTest.asMock(properties), HystrixEventNotifierDefault.getInstance()); } /** diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java index 4d8ea71bc..93d279b6b 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCommandMetricsTest.java @@ -129,7 +129,7 @@ protected Boolean getFallback() { * Utility method for creating {@link HystrixCommandMetrics} for unit tests. */ private static HystrixCommandMetrics getMetrics(HystrixCommandProperties.Setter properties) { - return new HystrixCommandMetricsSummary(InspectableBuilder.CommandKeyForUnitTest.KEY_ONE, InspectableBuilder.CommandGroupForUnitTest.OWNER_ONE, InspectableBuilder.ThreadPoolKeyForUnitTest.THREAD_POOL_ONE, HystrixCommandPropertiesTest.asMock(properties), HystrixEventNotifierDefault.getInstance()); + return new HystrixCommandMetrics(InspectableBuilder.CommandKeyForUnitTest.KEY_ONE, InspectableBuilder.CommandGroupForUnitTest.OWNER_ONE, InspectableBuilder.ThreadPoolKeyForUnitTest.THREAD_POOL_ONE, HystrixCommandPropertiesTest.asMock(properties), HystrixEventNotifierDefault.getInstance()); } } diff --git a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixThreadPoolMetricsTest.java b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixThreadPoolMetricsTest.java index 1ddd06c6b..79414158a 100644 --- a/hystrix-core/src/test/java/com/netflix/hystrix/HystrixThreadPoolMetricsTest.java +++ b/hystrix-core/src/test/java/com/netflix/hystrix/HystrixThreadPoolMetricsTest.java @@ -22,6 +22,21 @@ import static org.junit.Assert.assertEquals; +/** + * Copyright 2013 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. + */ public class HystrixThreadPoolMetricsTest { @Before From 93ac53543f6c272342d6e02d3134671c7f92f95f Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Sun, 27 Sep 2015 00:47:51 -0700 Subject: [PATCH 9/9] Better implementation that allows overriding classes of HystrixServoMetricsPublisherCommand to be less-aware of implementation details --- .../HystrixServoMetricsPublisherCommand.java | 151 +++++++++++++----- ...xServoMetricsPublisherCommandAbstract.java | 124 -------------- 2 files changed, 114 insertions(+), 161 deletions(-) delete mode 100644 hystrix-contrib/hystrix-servo-metrics-publisher/src/main/java/com/netflix/hystrix/contrib/servopublisher/HystrixServoMetricsPublisherCommandAbstract.java 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(); - } - }; - } -}