use of io.helidon.faulttolerance.Timeout in project helidon by oracle.
the class MethodInvoker method updateMetricsAfter.
/**
* Update metrics after method is called and depending on outcome.
*
* @param cause Mapped cause or {@code null} if successful.
*/
private void updateMetricsAfter(Throwable cause) {
if (!isFaultToleranceMetricsEnabled()) {
return;
}
methodState.lock.lock();
try {
// Calculate execution time
long executionTime = System.nanoTime() - handlerStartNanos;
// Retries
if (introspector.hasRetry()) {
long retryCounter = methodState.retry.retryCounter();
boolean wasRetried = retryCounter > 0;
Counter retryRetriesTotal = RetryRetriesTotal.get(introspector.getMethodNameTag());
// Update retry counter
if (wasRetried) {
retryRetriesTotal.inc(retryCounter);
}
// Update retry metrics based on outcome
if (cause == null) {
RetryCallsTotal.get(introspector.getMethodNameTag(), wasRetried ? RetryRetried.TRUE.get() : RetryRetried.FALSE.get(), RetryResult.VALUE_RETURNED.get()).inc();
} else if (cause instanceof RetryTimeoutException) {
RetryCallsTotal.get(introspector.getMethodNameTag(), wasRetried ? RetryRetried.TRUE.get() : RetryRetried.FALSE.get(), RetryResult.MAX_DURATION_REACHED.get()).inc();
} else {
// Exception thrown but not RetryTimeoutException
int maxRetries = introspector.getRetry().maxRetries();
if (maxRetries == -1) {
maxRetries = Integer.MAX_VALUE;
}
if (retryCounter == maxRetries) {
RetryCallsTotal.get(introspector.getMethodNameTag(), wasRetried ? RetryRetried.TRUE.get() : RetryRetried.FALSE.get(), RetryResult.MAX_RETRIES_REACHED.get()).inc();
} else if (retryCounter < maxRetries) {
RetryCallsTotal.get(introspector.getMethodNameTag(), wasRetried ? RetryRetried.TRUE.get() : RetryRetried.FALSE.get(), RetryResult.EXCEPTION_NOT_RETRYABLE.get()).inc();
}
}
}
// Timeout
if (introspector.hasTimeout()) {
if (cause instanceof org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException) {
TimeoutCallsTotal.get(introspector.getMethodNameTag(), TimeoutTimedOut.TRUE.get()).inc();
} else {
TimeoutCallsTotal.get(introspector.getMethodNameTag(), TimeoutTimedOut.FALSE.get()).inc();
}
TimeoutExecutionDuration.get(introspector.getMethodNameTag()).update(executionTime);
}
// CircuitBreaker
if (introspector.hasCircuitBreaker()) {
Objects.requireNonNull(methodState.breaker);
if (methodState.lastBreakerState == State.OPEN) {
CircuitBreakerCallsTotal.get(introspector.getMethodNameTag(), CircuitBreakerResult.CIRCUIT_BREAKER_OPEN.get()).inc();
} else if (methodState.breaker.state() == State.OPEN) {
// closed -> open
CircuitBreakerOpenedTotal.get(introspector.getMethodNameTag()).inc();
}
if (cause == null) {
CircuitBreakerCallsTotal.get(introspector.getMethodNameTag(), CircuitBreakerResult.SUCCESS.get()).inc();
} else if (!(cause instanceof CircuitBreakerOpenException)) {
boolean skipOnThrowable = Arrays.stream(introspector.getCircuitBreaker().skipOn()).anyMatch(c -> c.isAssignableFrom(cause.getClass()));
boolean failOnThrowable = Arrays.stream(introspector.getCircuitBreaker().failOn()).anyMatch(c -> c.isAssignableFrom(cause.getClass()));
if (skipOnThrowable || !failOnThrowable) {
CircuitBreakerCallsTotal.get(introspector.getMethodNameTag(), CircuitBreakerResult.SUCCESS.get()).inc();
} else {
CircuitBreakerCallsTotal.get(introspector.getMethodNameTag(), CircuitBreakerResult.FAILURE.get()).inc();
}
}
// Update times for gauges
switch(methodState.lastBreakerState) {
case OPEN:
methodState.breakerTimerOpen += System.nanoTime() - methodState.startNanos;
break;
case CLOSED:
methodState.breakerTimerClosed += System.nanoTime() - methodState.startNanos;
break;
case HALF_OPEN:
methodState.breakerTimerHalfOpen += System.nanoTime() - methodState.startNanos;
break;
default:
throw new IllegalStateException("Unknown breaker state " + methodState.lastBreakerState);
}
// Update internal state
methodState.lastBreakerState = methodState.breaker.state();
methodState.startNanos = System.nanoTime();
}
// Bulkhead
if (introspector.hasBulkhead()) {
Objects.requireNonNull(methodState.bulkhead);
Bulkhead.Stats stats = methodState.bulkhead.stats();
Counter bulkheadAccepted = BulkheadCallsTotal.get(introspector.getMethodNameTag(), BulkheadResult.ACCEPTED.get());
if (stats.callsAccepted() > bulkheadAccepted.getCount()) {
bulkheadAccepted.inc(stats.callsAccepted() - bulkheadAccepted.getCount());
}
Counter bulkheadRejected = BulkheadCallsTotal.get(introspector.getMethodNameTag(), BulkheadResult.REJECTED.get());
if (stats.callsRejected() > bulkheadRejected.getCount()) {
bulkheadRejected.inc(stats.callsRejected() - bulkheadRejected.getCount());
}
// Update histograms if task accepted
if (!(cause instanceof BulkheadException)) {
long waitingTime = invocationStartNanos - handlerStartNanos;
BulkheadRunningDuration.get(introspector.getMethodNameTag()).update(executionTime - waitingTime);
if (introspector.isAsynchronous()) {
BulkheadWaitingDuration.get(introspector.getMethodNameTag()).update(waitingTime);
}
}
}
// Global method counters
if (cause == null) {
InvocationsTotal.get(introspector.getMethodNameTag(), VALUE_RETURNED.get(), introspector.getFallbackTag(fallbackCalled.get())).inc();
} else {
InvocationsTotal.get(introspector.getMethodNameTag(), EXCEPTION_THROWN.get(), introspector.getFallbackTag(fallbackCalled.get())).inc();
}
} finally {
methodState.lock.unlock();
}
}
Aggregations