use of com.netflix.hystrix.HystrixCommandMetrics in project Hystrix by Netflix.
the class HystrixMetricsStreamHandler method handleHystrixRequest.
private Observable<Void> handleHystrixRequest(final HttpServerResponse<O> response) {
writeHeaders(response);
final Subject<Void, Void> subject = PublishSubject.create();
final MultipleAssignmentSubscription subscription = new MultipleAssignmentSubscription();
Subscription actionSubscription = Observable.interval(interval, TimeUnit.MILLISECONDS).subscribe(new Action1<Long>() {
@Override
public void call(Long tick) {
if (!response.getChannel().isOpen()) {
subscription.unsubscribe();
return;
}
try {
for (HystrixCommandMetrics commandMetrics : HystrixCommandMetrics.getInstances()) {
writeMetric(SerialHystrixDashboardData.toJsonString(commandMetrics), response);
}
for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics.getInstances()) {
writeMetric(SerialHystrixDashboardData.toJsonString(threadPoolMetrics), response);
}
for (HystrixCollapserMetrics collapserMetrics : HystrixCollapserMetrics.getInstances()) {
writeMetric(SerialHystrixDashboardData.toJsonString(collapserMetrics), response);
}
} catch (Exception e) {
subject.onError(e);
}
}
});
subscription.set(actionSubscription);
return subject;
}
use of com.netflix.hystrix.HystrixCommandMetrics in project Hystrix by Netflix.
the class HystrixServoMetricsPublisherCommandTest method testCumulativeCounters.
@Test
public void testCumulativeCounters() throws Exception {
//execute 10 commands/sec (8 SUCCESS, 1 FAILURE, 1 TIMEOUT).
//after 5 seconds, cumulative counters should have observed 50 commands (40 SUCCESS, 5 FAILURE, 5 TIMEOUT)
HystrixCommandKey key = HystrixCommandKey.Factory.asKey("ServoCOMMAND-A");
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
HystrixCommandProperties properties = new HystrixPropertiesCommandDefault(key, propertiesSetter);
HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(key, groupKey, properties);
HystrixServoMetricsPublisherCommand servoPublisher = new HystrixServoMetricsPublisherCommand(key, groupKey, metrics, circuitBreaker, properties);
servoPublisher.initialize();
final int NUM_SECONDS = 5;
for (int i = 0; i < NUM_SECONDS; i++) {
new SuccessCommand(key).execute();
new SuccessCommand(key).execute();
new SuccessCommand(key).execute();
Thread.sleep(10);
new TimeoutCommand(key).execute();
new SuccessCommand(key).execute();
new FailureCommand(key).execute();
new SuccessCommand(key).execute();
new SuccessCommand(key).execute();
new SuccessCommand(key).execute();
Thread.sleep(10);
new SuccessCommand(key).execute();
}
Thread.sleep(500);
assertEquals(40L, servoPublisher.getCumulativeMonitor("success", HystrixEventType.SUCCESS).getValue());
assertEquals(5L, servoPublisher.getCumulativeMonitor("timeout", HystrixEventType.TIMEOUT).getValue());
assertEquals(5L, servoPublisher.getCumulativeMonitor("failure", HystrixEventType.FAILURE).getValue());
assertEquals(10L, servoPublisher.getCumulativeMonitor("fallback_success", HystrixEventType.FALLBACK_SUCCESS).getValue());
}
use of com.netflix.hystrix.HystrixCommandMetrics in project Hystrix by Netflix.
the class HystrixServoMetricsPublisherCommandTest method testRollingLatencies.
@Test
public void testRollingLatencies() throws Exception {
//execute 10 commands, then sleep for 2000ms to let these age out
//execute 10 commands again, these should show up in rolling count
HystrixCommandKey key = HystrixCommandKey.Factory.asKey("ServoCOMMAND-C");
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
HystrixCommandProperties properties = new HystrixPropertiesCommandDefault(key, propertiesSetter);
HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(key, groupKey, properties);
HystrixServoMetricsPublisherCommand servoPublisher = new HystrixServoMetricsPublisherCommand(key, groupKey, metrics, circuitBreaker, properties);
servoPublisher.initialize();
new SuccessCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
new TimeoutCommand(key).execute();
new SuccessCommand(key, 5).execute();
new FailureCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
new SuccessCommand(key, 5).execute();
Thread.sleep(2000);
List<Observable<Integer>> os = new ArrayList<Observable<Integer>>();
TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>();
os.add(new SuccessCommand(key, 10).observe());
os.add(new SuccessCommand(key, 20).observe());
os.add(new SuccessCommand(key, 10).observe());
os.add(new TimeoutCommand(key).observe());
os.add(new SuccessCommand(key, 15).observe());
os.add(new FailureCommand(key, 10).observe());
os.add(new TimeoutCommand(key).observe());
os.add(new TimeoutCommand(key).observe());
os.add(new TimeoutCommand(key).observe());
os.add(new TimeoutCommand(key).observe());
Observable.merge(os).subscribe(testSubscriber);
testSubscriber.awaitTerminalEvent(300, TimeUnit.MILLISECONDS);
testSubscriber.assertCompleted();
testSubscriber.assertNoErrors();
//1 bucket roll
Thread.sleep(100);
int meanExecutionLatency = servoPublisher.getExecutionLatencyMeanMonitor("meanExecutionLatency").getValue().intValue();
int p5ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p5ExecutionLatency", 5).getValue().intValue();
int p25ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p25ExecutionLatency", 25).getValue().intValue();
int p50ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p50ExecutionLatency", 50).getValue().intValue();
int p75ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p75ExecutionLatency", 75).getValue().intValue();
int p90ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p90ExecutionLatency", 90).getValue().intValue();
int p99ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p99ExecutionLatency", 99).getValue().intValue();
int p995ExecutionLatency = servoPublisher.getExecutionLatencyPercentileMonitor("p995ExecutionLatency", 99.5).getValue().intValue();
System.out.println("Execution: Mean : " + meanExecutionLatency + ", p5 : " + p5ExecutionLatency + ", p25 : " + p25ExecutionLatency + ", p50 : " + p50ExecutionLatency + ", p75 : " + p75ExecutionLatency + ", p90 : " + p90ExecutionLatency + ", p99 : " + p99ExecutionLatency + ", p99.5 : " + p995ExecutionLatency);
int meanTotalLatency = servoPublisher.getTotalLatencyMeanMonitor("meanTotalLatency").getValue().intValue();
int p5TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p5TotalLatency", 5).getValue().intValue();
int p25TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p25TotalLatency", 25).getValue().intValue();
int p50TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p50TotalLatency", 50).getValue().intValue();
int p75TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p75TotalLatency", 75).getValue().intValue();
int p90TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p90TotalLatency", 90).getValue().intValue();
int p99TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p99TotalLatency", 99).getValue().intValue();
int p995TotalLatency = servoPublisher.getTotalLatencyPercentileMonitor("p995TotalLatency", 99.5).getValue().intValue();
System.out.println("Total: Mean : " + meanTotalLatency + ", p5 : " + p5TotalLatency + ", p25 : " + p25TotalLatency + ", p50 : " + p50TotalLatency + ", p75 : " + p75TotalLatency + ", p90 : " + p90TotalLatency + ", p99 : " + p99TotalLatency + ", p99.5 : " + p995TotalLatency);
assertTrue(meanExecutionLatency > 10);
assertTrue(p5ExecutionLatency <= p25ExecutionLatency);
assertTrue(p25ExecutionLatency <= p50ExecutionLatency);
assertTrue(p50ExecutionLatency <= p75ExecutionLatency);
assertTrue(p75ExecutionLatency <= p90ExecutionLatency);
assertTrue(p90ExecutionLatency <= p99ExecutionLatency);
assertTrue(p99ExecutionLatency <= p995ExecutionLatency);
assertTrue(meanTotalLatency > 10);
assertTrue(p5TotalLatency <= p25TotalLatency);
assertTrue(p25TotalLatency <= p50TotalLatency);
assertTrue(p50TotalLatency <= p75TotalLatency);
assertTrue(p75TotalLatency <= p90TotalLatency);
assertTrue(p90TotalLatency <= p99TotalLatency);
assertTrue(p99TotalLatency <= p995TotalLatency);
assertTrue(meanExecutionLatency <= meanTotalLatency);
assertTrue(p5ExecutionLatency <= p5TotalLatency);
assertTrue(p25ExecutionLatency <= p25TotalLatency);
assertTrue(p50ExecutionLatency <= p50TotalLatency);
assertTrue(p75ExecutionLatency <= p75TotalLatency);
assertTrue(p90ExecutionLatency <= p90TotalLatency);
assertTrue(p99ExecutionLatency <= p99TotalLatency);
assertTrue(p995ExecutionLatency <= p995TotalLatency);
}
use of com.netflix.hystrix.HystrixCommandMetrics in project Hystrix by Netflix.
the class SerialHystrixDashboardData method writeCommandMetrics.
private static void writeCommandMetrics(final HystrixCommandMetrics commandMetrics, JsonGenerator json) throws IOException {
HystrixCommandKey key = commandMetrics.getCommandKey();
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);
json.writeStartObject();
json.writeStringField("type", "HystrixCommand");
json.writeStringField("name", key.name());
json.writeStringField("group", commandMetrics.getCommandGroup().name());
json.writeNumberField("currentTime", System.currentTimeMillis());
// circuit breaker
if (circuitBreaker == null) {
// circuit breaker is disabled and thus never open
json.writeBooleanField("isCircuitBreakerOpen", false);
} else {
json.writeBooleanField("isCircuitBreakerOpen", circuitBreaker.isOpen());
}
HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics.getHealthCounts();
json.writeNumberField("errorPercentage", healthCounts.getErrorPercentage());
json.writeNumberField("errorCount", healthCounts.getErrorCount());
json.writeNumberField("requestCount", healthCounts.getTotalRequests());
// rolling counters
safelyWriteNumberField(json, "rollingCountBadRequests", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.BAD_REQUEST);
}
});
safelyWriteNumberField(json, "rollingCountCollapsedRequests", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.COLLAPSED);
}
});
safelyWriteNumberField(json, "rollingCountEmit", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.EMIT);
}
});
safelyWriteNumberField(json, "rollingCountExceptionsThrown", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.EXCEPTION_THROWN);
}
});
safelyWriteNumberField(json, "rollingCountFailure", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FAILURE);
}
});
safelyWriteNumberField(json, "rollingCountFallbackEmit", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_EMIT);
}
});
safelyWriteNumberField(json, "rollingCountFallbackFailure", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_FAILURE);
}
});
safelyWriteNumberField(json, "rollingCountFallbackMissing", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_MISSING);
}
});
safelyWriteNumberField(json, "rollingCountFallbackRejection", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_REJECTION);
}
});
safelyWriteNumberField(json, "rollingCountFallbackSuccess", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.FALLBACK_SUCCESS);
}
});
safelyWriteNumberField(json, "rollingCountResponsesFromCache", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.RESPONSE_FROM_CACHE);
}
});
safelyWriteNumberField(json, "rollingCountSemaphoreRejected", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.SEMAPHORE_REJECTED);
}
});
safelyWriteNumberField(json, "rollingCountShortCircuited", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.SHORT_CIRCUITED);
}
});
safelyWriteNumberField(json, "rollingCountSuccess", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.SUCCESS);
}
});
safelyWriteNumberField(json, "rollingCountThreadPoolRejected", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.THREAD_POOL_REJECTED);
}
});
safelyWriteNumberField(json, "rollingCountTimeout", new Func0<Long>() {
@Override
public Long call() {
return commandMetrics.getRollingCount(HystrixEventType.TIMEOUT);
}
});
json.writeNumberField("currentConcurrentExecutionCount", commandMetrics.getCurrentConcurrentExecutionCount());
json.writeNumberField("rollingMaxConcurrentExecutionCount", commandMetrics.getRollingMaxConcurrentExecutions());
// latency percentiles
json.writeNumberField("latencyExecute_mean", commandMetrics.getExecutionTimeMean());
json.writeObjectFieldStart("latencyExecute");
json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0));
json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25));
json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50));
json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75));
json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90));
json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95));
json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99));
json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5));
json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100));
json.writeEndObject();
//
json.writeNumberField("latencyTotal_mean", commandMetrics.getTotalTimeMean());
json.writeObjectFieldStart("latencyTotal");
json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0));
json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25));
json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50));
json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75));
json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90));
json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95));
json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99));
json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5));
json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100));
json.writeEndObject();
// property values for reporting what is actually seen by the command rather than what was set somewhere
HystrixCommandProperties commandProperties = commandMetrics.getProperties();
json.writeNumberField("propertyValue_circuitBreakerRequestVolumeThreshold", commandProperties.circuitBreakerRequestVolumeThreshold().get());
json.writeNumberField("propertyValue_circuitBreakerSleepWindowInMilliseconds", commandProperties.circuitBreakerSleepWindowInMilliseconds().get());
json.writeNumberField("propertyValue_circuitBreakerErrorThresholdPercentage", commandProperties.circuitBreakerErrorThresholdPercentage().get());
json.writeBooleanField("propertyValue_circuitBreakerForceOpen", commandProperties.circuitBreakerForceOpen().get());
json.writeBooleanField("propertyValue_circuitBreakerForceClosed", commandProperties.circuitBreakerForceClosed().get());
json.writeBooleanField("propertyValue_circuitBreakerEnabled", commandProperties.circuitBreakerEnabled().get());
json.writeStringField("propertyValue_executionIsolationStrategy", commandProperties.executionIsolationStrategy().get().name());
json.writeNumberField("propertyValue_executionIsolationThreadTimeoutInMilliseconds", commandProperties.executionTimeoutInMilliseconds().get());
json.writeNumberField("propertyValue_executionTimeoutInMilliseconds", commandProperties.executionTimeoutInMilliseconds().get());
json.writeBooleanField("propertyValue_executionIsolationThreadInterruptOnTimeout", commandProperties.executionIsolationThreadInterruptOnTimeout().get());
json.writeStringField("propertyValue_executionIsolationThreadPoolKeyOverride", commandProperties.executionIsolationThreadPoolKeyOverride().get());
json.writeNumberField("propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get());
json.writeNumberField("propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get());
/*
* The following are commented out as these rarely change and are verbose for streaming for something people don't change.
* We could perhaps allow a property or request argument to include these.
*/
// json.put("propertyValue_metricsRollingPercentileEnabled", commandProperties.metricsRollingPercentileEnabled().get());
// json.put("propertyValue_metricsRollingPercentileBucketSize", commandProperties.metricsRollingPercentileBucketSize().get());
// json.put("propertyValue_metricsRollingPercentileWindow", commandProperties.metricsRollingPercentileWindowInMilliseconds().get());
// json.put("propertyValue_metricsRollingPercentileWindowBuckets", commandProperties.metricsRollingPercentileWindowBuckets().get());
// json.put("propertyValue_metricsRollingStatisticalWindowBuckets", commandProperties.metricsRollingStatisticalWindowBuckets().get());
json.writeNumberField("propertyValue_metricsRollingStatisticalWindowInMilliseconds", commandProperties.metricsRollingStatisticalWindowInMilliseconds().get());
json.writeBooleanField("propertyValue_requestCacheEnabled", commandProperties.requestCacheEnabled().get());
json.writeBooleanField("propertyValue_requestLogEnabled", commandProperties.requestLogEnabled().get());
// this will get summed across all instances in a cluster
json.writeNumberField("reportingHosts", 1);
json.writeStringField("threadPool", commandMetrics.getThreadPoolKey().name());
json.writeEndObject();
}
Aggregations