use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.
the class CircularEventConsumerTest method shouldBufferErrorEvents.
@Test
public void shouldBufferErrorEvents() {
// Given
// tag::shouldBufferEvents[]
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("testName");
CircularEventConsumer<CircuitBreakerEvent> ringBuffer = new CircularEventConsumer<>(2);
circuitBreaker.getEventPublisher().onEvent(ringBuffer);
// end::shouldBufferEvents[]
assertThat(ringBuffer.getBufferedEvents()).isEmpty();
// When
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
circuitBreaker.onError(0, new RuntimeException("Bla"));
// Then
CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(3);
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(3);
// Should only store 2 events, because capacity is 2
assertThat(ringBuffer.getBufferedEvents()).hasSize(2);
// ringBuffer.getBufferedEvents().forEach(event -> LOG.info(event.toString()));
}
use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.
the class CircuitBreakerExports method collect.
/**
* {@inheritDoc}
*/
@Override
public List<MetricFamilySamples> collect() {
final GaugeMetricFamily states = new GaugeMetricFamily(prefix + "_states", "Circuit Breaker States", asList("name", "state"));
final GaugeMetricFamily calls = new GaugeMetricFamily(prefix + "_calls", "Circuit Breaker Call Stats", asList("name", "call_result"));
for (CircuitBreaker circuitBreaker : circuitBreakersSupplier.get()) {
STATE_NAME_MAP.forEach(e -> {
final CircuitBreaker.State state = e._1;
final String name = e._2;
final double value = state == circuitBreaker.getState() ? 1.0 : 0.0;
states.addMetric(asList(circuitBreaker.getName(), name), value);
});
final CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics();
calls.addMetric(asList(circuitBreaker.getName(), "successful"), metrics.getNumberOfSuccessfulCalls());
calls.addMetric(asList(circuitBreaker.getName(), "failed"), metrics.getNumberOfFailedCalls());
calls.addMetric(asList(circuitBreaker.getName(), "not_permitted"), metrics.getNumberOfNotPermittedCalls());
calls.addMetric(asList(circuitBreaker.getName(), "buffered"), metrics.getNumberOfBufferedCalls());
calls.addMetric(asList(circuitBreaker.getName(), "buffered_max"), metrics.getMaxNumberOfBufferedCalls());
}
return asList(calls, states);
}
use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.
the class CircuitBreakerExportsTest method testExportsCircuitBreakerMetrics.
@Test
public void testExportsCircuitBreakerMetrics() {
// Given
final CollectorRegistry registry = new CollectorRegistry();
final CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("foo");
CircuitBreakerExports.ofIterable("boo_circuit_breaker", singletonList(circuitBreaker)).register(registry);
final Supplier<Map<String, Double>> values = () -> HashSet.of("successful", "failed", "not_permitted", "buffered", "buffered_max").map(callType -> Tuple.of(callType, registry.getSampleValue("boo_circuit_breaker_calls", new String[] { "name", "call_result" }, new String[] { "foo", callType }))).toMap(t -> t);
// When
final Map<String, Double> initialValues = values.get();
circuitBreaker.executeRunnable(() -> {
});
final Map<String, Double> afterSuccessValues = values.get();
try {
circuitBreaker.executeRunnable(() -> {
throw new SomeAppException("Some exception");
});
} catch (RuntimeException e) {
// expected
}
final Map<String, Double> afterFailureValues = values.get();
circuitBreaker.transitionToOpenState();
try {
circuitBreaker.executeRunnable(() -> {
});
} catch (CircuitBreakerOpenException e) {
// expected
}
final Map<String, Double> afterDeclinedValues = values.get();
// Then
assertThat(initialValues).isEqualTo(HashMap.of("successful", 0.0, "failed", 0.0, "not_permitted", 0.0, "buffered", 0.0, "buffered_max", 100.0));
assertThat(afterSuccessValues).isEqualTo(HashMap.of("successful", 1.0, "failed", 0.0, "not_permitted", 0.0, "buffered", 1.0, "buffered_max", 100.0));
assertThat(afterFailureValues).isEqualTo(HashMap.of("successful", 1.0, "failed", 1.0, "not_permitted", 0.0, "buffered", 2.0, "buffered_max", 100.0));
assertThat(afterDeclinedValues).isEqualTo(HashMap.of("successful", 1.0, "failed", 1.0, "not_permitted", 1.0, "buffered", 2.0, "buffered_max", 100.0));
}
use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.
the class CircuitBreakerMetrics method bindTo.
@Override
public void bindTo(MeterRegistry registry) {
for (CircuitBreaker circuitBreaker : circuitBreakers) {
final String name = circuitBreaker.getName();
Gauge.builder(getName(prefix, name, STATE), circuitBreaker, (cb) -> cb.getState().getOrder()).register(registry);
Gauge.builder(getName(prefix, name, BUFFERED_MAX), circuitBreaker, (cb) -> cb.getMetrics().getMaxNumberOfBufferedCalls()).register(registry);
Gauge.builder(getName(prefix, name, BUFFERED), circuitBreaker, (cb) -> cb.getMetrics().getNumberOfBufferedCalls()).register(registry);
Gauge.builder(getName(prefix, name, FAILED), circuitBreaker, (cb) -> cb.getMetrics().getNumberOfFailedCalls()).register(registry);
Gauge.builder(getName(prefix, name, NOT_PERMITTED), circuitBreaker, (cb) -> cb.getMetrics().getNumberOfNotPermittedCalls()).register(registry);
Gauge.builder(getName(prefix, name, SUCCESSFUL), circuitBreaker, (cb) -> cb.getMetrics().getNumberOfSuccessfulCalls()).register(registry);
}
}
use of io.github.resilience4j.circuitbreaker.CircuitBreaker in project resilience4j by resilience4j.
the class CircuitBreakerChain method execute.
@Override
public void execute(Chain chain) throws Exception {
String prefix = chain.getRegistry().get(Resilience4jConfig.class).getEndpoints().getCircuitBreakers().getPath();
chain.prefix(prefix, chain1 -> {
chain1.get("events", ctx -> Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getAllEventConsumer().flatMap(CircularEventConsumer::getBufferedEvents).sorted(Comparator.comparing(CircuitBreakerEvent::getCreationTime)).map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r))));
chain1.get("stream/events", ctx -> {
Seq<Flowable<CircuitBreakerEvent>> eventStreams = circuitBreakerRegistry.getAllCircuitBreakers().map(circuitBreaker -> RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(Flowable.merge(eventStreams), e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(circuitBreakerName).getBufferedEvents().map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
CircuitBreaker circuitBreaker = circuitBreakerRegistry.getAllCircuitBreakers().find(cb -> cb.getName().equals(circuitBreakerName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("circuit breaker with name %s not found", circuitBreakerName)));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()), e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
chain1.get("events/:name/:type", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
Promise.<CircuitBreakerEventsEndpointResponse>async(d -> {
CircuitBreakerEventsEndpointResponse response = new CircuitBreakerEventsEndpointResponse(eventConsumerRegistry.getEventConsumer(circuitBreakerName).getBufferedEvents().filter(event -> event.getEventType() == CircuitBreakerEvent.Type.valueOf(eventType.toUpperCase())).map(CircuitBreakerEventDTOFactory::createCircuitBreakerEventDTO).toJavaList());
d.success(response);
}).then(r -> ctx.render(Jackson.json(r)));
});
chain1.get("stream/events/:name/:type", ctx -> {
String circuitBreakerName = ctx.getPathTokens().get("name");
String eventType = ctx.getPathTokens().get("type");
CircuitBreaker circuitBreaker = circuitBreakerRegistry.getAllCircuitBreakers().find(cb -> cb.getName().equals(circuitBreakerName)).getOrElseThrow(() -> new IllegalArgumentException(String.format("circuit breaker with name %s not found", circuitBreakerName)));
Flowable<CircuitBreakerEvent> eventStream = RxJava2Adapter.toFlowable(circuitBreaker.getEventPublisher()).filter(event -> event.getEventType() == CircuitBreakerEvent.Type.valueOf(eventType.toUpperCase()));
Function<CircuitBreakerEvent, String> data = c -> Jackson.getObjectWriter(chain1.getRegistry()).writeValueAsString(CircuitBreakerEventDTOFactory.createCircuitBreakerEventDTO(c));
ServerSentEvents events = ServerSentEvents.serverSentEvents(eventStream, e -> e.id(CircuitBreakerEvent::getCircuitBreakerName).event(c -> c.getEventType().name()).data(data));
ctx.render(events);
});
});
}
Aggregations