Skip to content

Commit a6da58b

Browse files
leonard84RobWin
authored andcommitted
Issue ReactiveX#354: Use tags instead of gauge values to indicate circuit breaker state (ReactiveX#416)
1 parent 16ba681 commit a6da58b

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

resilience4j-micrometer/src/main/java/io/github/resilience4j/micrometer/CircuitBreakerMetrics.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,15 @@ public static CircuitBreakerMetrics ofIterable(String prefix, Iterable<CircuitBr
8080

8181
@Override
8282
public void bindTo(MeterRegistry registry) {
83+
final CircuitBreaker.State[] states = CircuitBreaker.State.values();
8384
for (CircuitBreaker circuitBreaker : circuitBreakers) {
8485
final String name = circuitBreaker.getName();
85-
Gauge.builder(getName(prefix, name, STATE), circuitBreaker, (cb) -> cb.getState().getOrder())
86-
.register(registry);
86+
for (CircuitBreaker.State state : states) {
87+
Gauge.builder(getName(prefix, name, STATE), circuitBreaker, (cb) -> cb.getState() == state ? 1 : 0)
88+
.tag("state", state.name().toLowerCase())
89+
.register(registry);
90+
}
91+
8792
Gauge.builder(getName(prefix, name, BUFFERED_MAX), circuitBreaker, (cb) -> cb.getMetrics().getMaxNumberOfBufferedCalls())
8893
.register(registry);
8994
Gauge.builder(getName(prefix, name, BUFFERED), circuitBreaker, (cb) -> cb.getMetrics().getNumberOfBufferedCalls())

resilience4j-prometheus/src/main/java/io/github/resilience4j/prometheus/collectors/CircuitBreakerMetricsCollector.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ private CircuitBreakerMetricsCollector(MetricNames names, Supplier<? extends Ite
9191
public List<MetricFamilySamples> collect() {
9292
GaugeMetricFamily stateFamily = new GaugeMetricFamily(
9393
names.getStateMetricName(),
94-
"The state of the circuit breaker: 0 - CLOSED, 1 - OPEN, 2 - HALF_OPEN",
95-
LabelNames.NAME
94+
"The state of the circuit breaker:",
95+
LabelNames.NAME_AND_STATE
9696
);
9797
GaugeMetricFamily callsFamily = new GaugeMetricFamily(
9898
names.getCallsMetricName(),
@@ -109,17 +109,22 @@ public List<MetricFamilySamples> collect() {
109109
"The maximum number of buffered calls",
110110
LabelNames.NAME
111111
);
112-
113-
GaugeMetricFamily failureRateFamily = new GaugeMetricFamily(
112+
113+
GaugeMetricFamily failureRateFamily = new GaugeMetricFamily(
114114
names.getFailureRateMetricName(),
115115
"The failure rate",
116116
LabelNames.NAME
117117
);
118118

119+
final CircuitBreaker.State[] states = CircuitBreaker.State.values();
120+
119121
for (CircuitBreaker circuitBreaker : supplier.get()) {
120122
List<String> nameLabel = singletonList(circuitBreaker.getName());
121123

122-
stateFamily.addMetric(nameLabel, circuitBreaker.getState().getOrder());
124+
for (CircuitBreaker.State state : states) {
125+
stateFamily.addMetric(asList(circuitBreaker.getName(), state.name().toLowerCase()),
126+
circuitBreaker.getState() == state ? 1 : 0);
127+
}
123128

124129
Metrics metrics = circuitBreaker.getMetrics();
125130
callsFamily.addMetric(asList(circuitBreaker.getName(), "successful"), metrics.getNumberOfSuccessfulCalls());

resilience4j-prometheus/src/main/java/io/github/resilience4j/prometheus/collectors/LabelNames.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ private LabelNames() {}
2626

2727
public static final List<String> NAME = Collections.singletonList("name");
2828
public static final List<String> NAME_AND_KIND = Arrays.asList("name", "kind");
29+
public static final List<String> NAME_AND_STATE = Arrays.asList("name", "state");
2930
}

resilience4j-prometheus/src/test/java/io/github/resilience4j/prometheus/collectors/CircuitBreakerMetricsCollectorTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515
*/
1616
package io.github.resilience4j.prometheus.collectors;
1717

18-
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
19-
import io.prometheus.client.CollectorRegistry;
20-
import org.junit.Before;
21-
import org.junit.Test;
22-
23-
2418
import static io.github.resilience4j.prometheus.collectors.CircuitBreakerMetricsCollector.MetricNames.DEFAULT_CIRCUIT_BREAKER_BUFFERED_CALLS;
2519
import static io.github.resilience4j.prometheus.collectors.CircuitBreakerMetricsCollector.MetricNames.DEFAULT_CIRCUIT_BREAKER_CALLS_METRIC_NAME;
2620
import static io.github.resilience4j.prometheus.collectors.CircuitBreakerMetricsCollector.MetricNames.DEFAULT_CIRCUIT_BREAKER_FAILURE_RATE;
@@ -29,6 +23,12 @@
2923
import static java.util.Collections.singletonList;
3024
import static org.assertj.core.api.Assertions.assertThat;
3125

26+
import org.junit.Before;
27+
import org.junit.Test;
28+
29+
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
30+
import io.prometheus.client.CollectorRegistry;
31+
3232
public class CircuitBreakerMetricsCollectorTest {
3333

3434
CollectorRegistry registry;
@@ -50,8 +50,8 @@ public void setup() {
5050
public void stateReportsCorrespondingValue() {
5151
double state = registry.getSampleValue(
5252
DEFAULT_CIRCUIT_BREAKER_STATE_METRIC_NAME,
53-
new String[]{"name"},
54-
new String[]{circuitBreaker.getName()}
53+
new String[]{"name", "state"},
54+
new String[]{circuitBreaker.getName(), circuitBreaker.getState().name().toLowerCase()}
5555
);
5656

5757
assertThat(state).isEqualTo(circuitBreaker.getState().getOrder());
@@ -155,8 +155,8 @@ public void customMetricNamesOverrideDefaultOnes() {
155155
)).isNotNull();
156156
assertThat(registry.getSampleValue(
157157
"custom_state",
158-
new String[]{"name"},
159-
new String[]{"backendA"}
158+
new String[]{"name", "state"},
159+
new String[]{"backendA", "closed"}
160160
)).isNotNull();
161161
assertThat(registry.getSampleValue(
162162
"custom_max_buffered_calls",

0 commit comments

Comments
 (0)