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. Micrometer 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
TimerOne of the following:

kind="failed"
kind="successful"
* kind="ignored"

name="backendA"
Total number of successful, failed or ignored 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
.not.permitted.calls
Counterkind="not_permitted"

name="backendA"
Total number of calls which have not been permitted.
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 bulkheads 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

ThreadPoolBulkhead Metrics

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

MeterRegistry meterRegistry = new SimpleMeterRegistry();
ThreadPoolBulkheadRegistry threadPoolBulkheadRegistry = ThreadPoolBulkheadRegistry();
ThreadPoolBulkhead threadPoolBulkhead = threadPoolBulkheadRegistry.bulkhead("backendA");

// Register all bulkheads at once
TaggedThreadPoolBulkheadMetrics
  .ofThreadPoolBulkheadRegistry(threadPoolBulkheadRegistry)
  .bindTo(meterRegistry);

The following metrics are exported:

Metric NameTypeTagsDescription
resilience4j
.bulkhead
.queue
.depth
Gaugename="backendA"The queue depth. The number of tasks waiting to be executed
resilience4j
.bulkhead
.queue
.capacity
Gaugename="backendA"The queue capacity. The maximum number of tasks which are allowed to be queued before tasks are rejected.
resilience4j
.bulkhead
.thread
.pool
.size
Gaugename="backendA"The current size of the thread pool.
resilience4j
.bulkhead
.core
.thread
.pool
.size
Gaugename="backendA"The core thread pool size. The smallest size the pool is allowed to be.
resilience4j
.bulkhead
.max
.thread
.pool
.size
Gaugename="backendA"The maximum thread pool size.

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

TimeLimiter

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

MeterRegistry meterRegistry = new SimpleMeterRegistry();
TimeLimiterRegistry timeLimiterRegistry = TimeLimiterRegistry.ofDefaults();
TimeLimiter timeLimiter = timeLimiterRegistry
  .timeLimiter("backendA");

// Register time limiters at once
TaggedTimeLimiterMetrics
  .ofTimeLimiterRegistry(timeLimiterRegistry)
  .bindTo(meterRegistry);

The following metrics are exported:

Metric nameTypeTagsDescription
resilience4j.timelimiter.callsCountername="backendA"
kind="successful"
Total number of calls which were successful
resilience4j.timelimiter.callsCountername="backendA"
kind="failed"
Total number of calls which failed
resilience4j.timelimiter.callsCountername="backendA"
kind="timeout"
Total number of calls where a timeout occured

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 ThreadPoolBulkhead:

# HELP resilience4j_bulkhead_queue_depth The number of tasks in the queue
# TYPE resilience4j_bulkhead_queue_depth gauge
resilience4j_bulkhead_queue_depth{name="backendA",} 10.0

# HELP resilience4j_bulkhead_queue_capacity The maximum allowed size of the queue
# TYPE resilience4j_bulkhead_queue_capacity gauge
resilience4j_bulkhead_queue_capacity{name="backendA",} 50.0

# HELP resilience4j_bulkhead_thread_pool_size The current size of the thread pool
# TYPE resilience4j_bulkhead_thread_pool_size gauge
resilience4j_bulkhead_thread_pool_size{name="backendA",} 10.0

# HELP resilience4j_bulkhead_core_thread_pool_size The minimum size of the thread pool
# TYPE resilience4j_bulkhead_core_thread_pool_size gauge
resilience4j_bulkhead_core_thread_pool_size{name="backendA",} 5.0

# HELP resilience4j_bulkhead_max_thread_pool_size The maximum allowed size of the thread pool
# TYPE resilience4j_bulkhead_max_thread_pool_size gauge
resilience4j_bulkhead_max_thread_pool_size{name="backendA",} 20.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