HomeGuidesChangelog
GuidesGitHubLog In
Guides

Micrometer

Getting started with resilience4j-micrometer

Resilience4j provides a module for Micrometer which supports most popular monitoring systems like InfluxDB or Prometheus.
The module expects that micrometer-core is already provided at runtime. Spring Reactor is not a transitive dependency.

repositories {
    jCenter()
}

dependencies {
  compile "io.github.resilience4j:resilience4j-micrometer:${resilience4jVersion}"
}

CircuitBreaker Metrics

The following code snippet shows how to bind CircuitBreaker metrics to a MeterRegistry. It binds all CircuitBreaker instances at once and registers event consumers to dynamically bind newly created instances.

MeterRegistry meterRegistry = new SimpleMeterRegistry();
CircuitBreakerRegistry circuitBreakerRegistry =
  CircuitBreakerRegistry.ofDefaults();
CircuitBreaker foo = circuitBreakerRegistry
  .circuitBreaker("backendA");
CircuitBreaker boo = circuitBreakerRegistry
  .circuitBreaker("backendB");

TaggedCircuitBreakerMetrics
  .ofCircuitBreakerRegistry(circuitBreakerRegistry)
  .bindTo(meterRegistry)

The following metrics are exported:

Metric nameTypeTagsDescription
resilience4j
.circuitbreaker
.calls
Timername="backendA"Total number of successful and failed calls
resilience4j
.circuitbreaker
.max.buffered.calls
Gaugename="backendA"The maximum number of buffered calls which can be stored in the current ring buffer
resilience4j
.circuitbreaker
.state
Gauge
0 - Not active
1 - Active
One of the following:
state="closed"
state="open"
state="half_open"
state="forced_open"
* state="disabled"

name="backendA"
The states of the circuit breaker
resilience4j
.circuitbreaker
.failure.rate
Gaugename="backendA"The failure rate of the circuit breaker
resilience4j
.circuitbreaker
.buffered.calls
GaugeOne of the following:
kind="failed"
kind="successful"

name="backendA"
The number of buffered successful and failed calls stored in the ring buffer
resilience4
.circuitbreaker
.calls
Counterkind="not_permitted"

name="backendA"
Total number of calls which failed but the exception was ignored
resilience4j
.circuitbreaker
.slow.call.rate
Gaugename="backendA"The slow call of the circuit breaker

Retry Metrics

The following code snippet shows how to bind Retry metrics to a MeterRegistry. It binds all Retry instances at once and registers event consumers to dynamically bind newly created instances

MeterRegistry meterRegistry = new SimpleMeterRegistry();
RetryRegistry retryRegistry = RetryRegistry.ofDefaults();
Retry retry = retryRegistry.retry("backendA");

// Register all retries at once
TaggedRetryMetrics
  .ofRetryRegistry(retryRegistry)
  .bindTo(meterRegistry);

The following metrics are exported:

Metric nameTypeTagsDescription
resilience4j
.retry
.calls
GaugeOne of the following:
kind="successful.without.retry"
kind="successful.with.retry"
kind="failed.with.retry"
kind="failed.without.retry"

name="backendA"
The number of calls by kind

Bulkhead Metrics

The following code snippet shows how to bind Bulkhead metrics to a MeterRegistry. It binds all Bulkhead instances at once and registers event consumers to dynamically bind newly created instances

MeterRegistry meterRegistry = new SimpleMeterRegistry();
BulkheadRegistry bulkheadRegistry = BulkheadRegistry.ofDefaults();
Bulkhead bulkhead = bulkheadRegistry.bulkhead("backendA");

// Register all retries at once
TaggedBulkheadMetrics
  .ofBulkheadRegistry(bulkheadRegistry)
  .bindTo(meterRegistry);

The following metrics are exported:

Metric nameTypeTagsDescription
resilience4j
.bulkhead
.available
.concurrent.calls
Gaugename="backendA"The number of available permissions
resilience4j
.bulkhead
.max.allowed
.concurrent.calls
Gaugename="backendA"The maximum number of available permissions

RateLimiter Metrics

The following code snippet shows how to bind RateLimiter metrics to a MeterRegistry. It binds all RateLimiter instances at once and registers event consumers to dynamically bind newly created instances

MeterRegistry meterRegistry = new SimpleMeterRegistry();
RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.ofDefaults();
RateLimiter rateLimiter = rateLimiterRegistry
  .rateLimiter("backendA");

// Register rate limiters at once
TaggedRateLimiterMetrics
  .ofRateLimiterRegistry(rateLimiterRegistry)
  .bindTo(meterRegistry);

The following metrics are exported:

Metric nameTypeTagsDescription
resilience4j.ratelimiter
.available.permissions
Gaugename="backendA"The number of available permissions
resilience4j.ratelimiter
.waiting.threads
Gaugename="backendA"The number of waiting threads

Prometheus

When you want to publish to Prometheus, you have to add the following dependency:

dependencies {
  compile "io.micrometer:micrometer-registry-prometheus"
}

The following metrics are exported per CircuitBreaker:

# HELP resilience4j_circuitbreaker_buffered_calls The number of buffered failed calls stored in the ring buffer
# TYPE resilience4j_circuitbreaker_buffered_calls gauge
resilience4j_circuitbreaker_buffered_calls{kind="failed",name="backendA",} 0.0
resilience4j_circuitbreaker_buffered_calls{kind="successful",name="backendA",} 0.0

# HELP resilience4j_circuitbreaker_calls_total Total number of not permitted calls
# TYPE resilience4j_circuitbreaker_calls_total counter
resilience4j_circuitbreaker_calls_total{kind="not_permitted",name="backendA",} 0.0

# HELP resilience4j_circuitbreaker_state The states of the circuit breaker
# TYPE resilience4j_circuitbreaker_state gauge
resilience4j_circuitbreaker_state{name="backendA",state="half_open",} 0.0
resilience4j_circuitbreaker_state{name="backendA",state="forced_open",} 0.0
resilience4j_circuitbreaker_state{name="backendA",state="disabled",} 0.0
resilience4j_circuitbreaker_state{name="backendA",state="closed",} 1.0
resilience4j_circuitbreaker_state{name="backendA",state="open",} 0.0
resilience4j_circuitbreaker_state{name="backendA",} 0.0

# HELP resilience4j_circuitbreaker_failure_rate The failure rate of the circuit breaker
# TYPE resilience4j_circuitbreaker_failure_rate gauge
resilience4j_circuitbreaker_failure_rate{name="backendA",} 20.0

# HELP resilience4j_circuitbreaker_max_buffered_calls The maximum number of buffered calls which can be stored in the ring buffer
# TYPE resilience4j_circuitbreaker_max_buffered_calls gauge
resilience4j_circuitbreaker_max_buffered_calls{name="backendA",} 5.0

# HELP resilience4j_circuitbreaker_calls_seconds_max Total duration of calls
# TYPE resilience4j_circuitbreaker_calls_seconds_max gauge
resilience4j_circuitbreaker_calls_seconds_max{kind="successful",name="backendA",} 0.0
resilience4j_circuitbreaker_calls_seconds_max{kind="failed",name="backendA",} 0.0
resilience4j_circuitbreaker_calls_seconds_max{kind="ignored",name="backendA",} 0.0

resilience4j_circuitbreaker_calls_seconds_sum{kind="ignored",name="backendA",} 0.0

# HELP resilience4j_circuitbreaker_calls_seconds Total number of successful calls
# TYPE resilience4j_circuitbreaker_calls_seconds histogram
resilience4j_circuitbreaker_calls_seconds_count{kind="successful",name="backendA",} 0.0
resilience4j_circuitbreaker_calls_seconds_sum{kind="successful",name="backendA",} 0.0

# HELP resilience4j_circuitbreaker_calls_seconds Total number of failed calls
# TYPE resilience4j_circuitbreaker_calls_seconds histogram
resilience4j_circuitbreaker_calls_seconds_count{kind="failed",name="backendA",} 0.0
resilience4j_circuitbreaker_calls_seconds_sum{kind="failed",name="backendA",} 0.0

The following metrics are exported per Bulkhead:

# HELP resilience4j_bulkhead_available_concurrent_calls The number of available permissions
# TYPE resilience4j_bulkhead_available_concurrent_calls gauge
resilience4j_bulkhead_available_concurrent_calls{name="backendA",} 10.0

# HELP resilience4j_bulkhead_max_allowed_concurrent_calls The maximum number available permissions
# TYPE resilience4j_bulkhead_max_allowed_concurrent_calls gauge
resilience4j_bulkhead_max_allowed_concurrent_calls{name="backendA",} 10.0

The following metrics are exported per Retry:

# HELP resilience4j_retry_calls The number of successful calls without a retry attempt
# TYPE resilience4j_retry_calls gauge
resilience4j_retry_calls{kind="failed_with_retry",name="backendA",} 0.0
resilience4j_retry_calls{kind="failed_without_retry",name="backendA",} 0.0
resilience4j_retry_calls{kind="successful_without_retry",name="backendA",} 0.0
resilience4j_retry_calls{kind="successful_with_retry",name="backendA",} 0.0

The following metrics are exported per RateLimiter:

# HELP resilience4j_ratelimiter_waiting_threads The number of waiting threads
# TYPE resilience4j_ratelimiter_waiting_threads gauge
resilience4j_ratelimiter_waiting_threads{name="backendA",} 0.0

# HELP resilience4j_ratelimiter_available_permissions The number of available permissions
# TYPE resilience4j_ratelimiter_available_permissions gauge
resilience4j_ratelimiter_available_permissions{name="backendA",} 50.0