Close

Spring Cloud - Circuit Breaker Hystrix Event Listener

[Last Updated: Aug 11, 2020]

We can receive Hystrix Circuit Breaker events by extending HystrixEventNotifier.

Two methods can be overridden from HystrixEventNotifier

public void markEvent(HystrixEventType eventType, HystrixCommandKey key)

Called for every event fired.


public void markCommandExecution(HystrixCommandKey key,
                         HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy,
                         int duration,
                         java.util.List<HystrixEventType> eventsDuringExecution)

Called after a command is executed using thread isolation. Will not get called if a command is rejected, short-circuited etc.


HystrixEventType enum

package com.netflix.hystrix;
 ......
HystrixEventType {
    EMIT(false),
    SUCCESS(true),
    FAILURE(false),
    TIMEOUT(false),
    BAD_REQUEST(true),
    SHORT_CIRCUITED(false),
    THREAD_POOL_REJECTED(false),
    SEMAPHORE_REJECTED(false),
    FALLBACK_EMIT(false),
    FALLBACK_SUCCESS(true),
    FALLBACK_FAILURE(true),
    FALLBACK_REJECTION(true),
    FALLBACK_MISSING(true),
    EXCEPTION_THROWN(false),
    RESPONSE_FROM_CACHE(true),
    CANCELLED(true),
    COLLAPSED(false),
    COMMAND_MAX_ACTIVE(false);
  ....
 private HystrixEventType(boolean isTerminal){
  .....
 }
 ....
}

Examples

Extending HystrixEventNotifier

package com.logicbig.example;

import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixEventType;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;

public class MyHystrixNotifier extends HystrixEventNotifier {
  @Override
  public void markEvent(HystrixEventType eventType, HystrixCommandKey commandKey){
      System.out.printf("-->Event, type=%s, Key=%s%n", eventType, commandKey);
  }
}

Circuit Breaker Method

@Service
public class MyService {
  @HystrixCommand(fallbackMethod = "defaultDoSomething")
  public void doSomething(int input) {
      System.out.println("output: " + 10 / input);
  }

  public void defaultDoSomething(int input, Throwable throwable) {
      System.out.printf("Default, input=%s, exception=%s%n", input, throwable);
  }
}
package com.logicbig.example;

import com.netflix.hystrix.strategy.HystrixPlugins;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
@EnableCircuitBreaker
public class CircuitBreakerMain {
  public static void main(String[] args) {
      HystrixPlugins.getInstance().registerEventNotifier(new MyHystrixNotifier());
      ConfigurableApplicationContext ctx = SpringApplication.run(CircuitBreakerMain.class, args);
      MyService myService = ctx.getBean(MyService.class);
      System.out.println("-- calling doSomething(2) --");
      myService.doSomething(2);
      System.out.println("-- calling doSomething(0) --");
      myService.doSomething(0);
      System.out.println("-- calling doSomething(5) --");
      myService.doSomething(5);
  }
}
-- calling doSomething(2) --
output: 5
-->Event, type=SUCCESS, Key=doSomething
-- calling doSomething(0) --
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-- calling doSomething(5) --
output: 2
-->Event, type=SUCCESS, Key=doSomething

Tripping the Circuit

package com.logicbig.example;

import com.netflix.hystrix.strategy.HystrixPlugins;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
@EnableCircuitBreaker
public class CircuitBreakerMain2 {
  public static void main(String[] args) throws InterruptedException {
      HystrixPlugins.getInstance().registerEventNotifier(new MyHystrixNotifier());
      ConfigurableApplicationContext ctx = SpringApplication.run(CircuitBreakerMain2.class, args);
      MyService myService = ctx.getBean(MyService.class);

      System.out.println("-- calling doSomething() 40 times --");
      int n = 40;
      for (int i = 0; i < n; i++) {
          myService.doSomething(i < (n * 0.6) ? 0 : 2);
          TimeUnit.MILLISECONDS.sleep(100);
      }
      TimeUnit.SECONDS.sleep(6);

      System.out.println("-- final call --");
      myService.doSomething(2);
  }
}
-- calling doSomething() 40 times --
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=FAILURE, Key=doSomething
Default, input=0, exception=java.lang.ArithmeticException: / by zero
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=0, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-->Event, type=SHORT_CIRCUITED, Key=doSomething
Default, input=2, exception=java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN
-->Event, type=FALLBACK_SUCCESS, Key=doSomething
-- final call --
output: 5
-->Event, type=SUCCESS, Key=doSomething

Example Project

Dependencies and Technologies Used:

  • Spring Boot 2.1.6.RELEASE
    Corresponding Spring Version 5.1.8.RELEASE
  • Spring Cloud Greenwich.SR2
  • spring-boot-starter : Core starter, including auto-configuration support, logging and YAML.
  • spring-cloud-starter-netflix-hystrix 2.1.2.RELEASE: Spring Cloud Starter Netflix Hystrix.
  • JDK 1.8
  • Maven 3.5.4

Implementing Hystrix Event Notifier Select All Download
  • circuit-breaker-hystrix-event-listener
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • MyHystrixNotifier.java

    See Also