PatPanda
PatPanda

Reputation: 5010

Resilience4j - Log circuit breaker state change

Question regarding Resilience4J, and how to log a circuit breaker state change please.

Currently, Resilience4j is working great. Having the ability to invoke a fallback when downstream systems are down, giving them time to breath, etc...

Unfortunately, I am facing an issue with my Spring Webflux 2.4.4+ app with

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-reactor</artifactId>
</dependency>
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

Suppose our circuit breaker exists closed mode at the time T, due to the downstream system being unavailable for instance.

On subsequent calls, since the circuit is opened, goes into a fallback, and I have a log when the fallback method is being invoked.

Hence, I only know at T+1 when the circuit breaker has been opened. But not the exact moment the circuit breaker changed state.

I was wondering, how to log the event of the circuit breaker changing the state, at the moment it really changes state at info level, please?

Upvotes: 1

Views: 10946

Answers (3)

andro83
andro83

Reputation: 4163

I found it more convenient to add listener for CircuitBreaker events in configuration so I wouldn't need to add binding to each listener. This also reacts on dynamically added circuit breaker events.

@Bean
    public RegistryEventConsumer<CircuitBreaker> myCircuitBreakerRegistryEventConsumer() {
        return new RegistryEventConsumer<>() {
            @Override
            public void onEntryAddedEvent(EntryAddedEvent<CircuitBreaker> entryAddedEvent) {
                entryAddedEvent.getAddedEntry().getEventPublisher().onStateTransition(event -> log.info(event.toString()));
            }

            @Override
            public void onEntryRemovedEvent(EntryRemovedEvent<CircuitBreaker> entryRemoveEvent) {
            }

            @Override
            public void onEntryReplacedEvent(EntryReplacedEvent<CircuitBreaker> entryReplacedEvent) {
            }
        };
    }

Upvotes: 1

Nikolas
Nikolas

Reputation: 44368

You can consume the emitted events. This can be found in the CircuitBreaker module documentation, section Consume emitted CircuitBreakerEvents.

A CircuitBreakerEvent can be a state transition, a circuit breaker reset, a successful call, a recorded error or an ignored error. All events contains additional information like event creation time and processing duration of the call. If you want to consume events, you have to register an event consumer.

You are interested in the onStateTransition method (a full list of event consumers is here):

circuitBreaker.getEventPublisher()
              .onStateTransition(e -> logger.info(e));

Feel free to log the whole event directly as it properly overrides the toString method and a sample log record looks like this:

2021-06-01T01:23:45.678901+00:00: CircuitBreaker 'myService' changed state from CLOSED to OPEN

Upvotes: 2

athom
athom

Reputation: 1598

You can use the following to log the transition

circuitBreaker.getEventPublisher().onEvent(event -> {
   LOG.info("State change {}", event);
});

Upvotes: 3

Related Questions