Skip to content

Commit b1ca47a

Browse files
committed
Review comments addressed
1 parent 452be5d commit b1ca47a

5 files changed

Lines changed: 109 additions & 137 deletions

File tree

instrumentation/failsafe-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/failsafe/v3_0/RetryPolicyInstrumentation.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
package io.opentelemetry.javaagent.instrumentation.failsafe.v3_0;
77

8+
import static io.opentelemetry.instrumentation.failsafe.v3_0.internal.RetryPolicyEventListenerBuilders.buildInstrumentedFailureListener;
9+
import static io.opentelemetry.instrumentation.failsafe.v3_0.internal.RetryPolicyEventListenerBuilders.buildInstrumentedSuccessListener;
810
import static net.bytebuddy.matcher.ElementMatchers.named;
911
import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments;
1012

1113
import dev.failsafe.PolicyConfig;
1214
import dev.failsafe.internal.RetryPolicyImpl;
1315
import io.opentelemetry.api.GlobalOpenTelemetry;
14-
import io.opentelemetry.instrumentation.failsafe.v3_0.FailsafeTelemetry;
1516
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1617
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1718
import java.lang.reflect.Field;
@@ -53,20 +54,24 @@ public static final class BuildAdvice {
5354
}
5455

5556
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
56-
public static void onExit(@Advice.Return Object retryPolicyImpl) throws IllegalAccessException {
57+
public static void onExit(@Advice.Return Object retryPolicyImpl) {
5758
if (FAILURE_LISTENER_FIELD == null || SUCCESS_LISTENER_FIELD == null) {
5859
return;
5960
}
6061

61-
RetryPolicyImpl<?> impl = (RetryPolicyImpl<?>) retryPolicyImpl;
62-
FailsafeTelemetry failsafeTelemetry = FailsafeTelemetry.create(GlobalOpenTelemetry.get());
63-
64-
FAILURE_LISTENER_FIELD.set(
65-
impl.getConfig(),
66-
failsafeTelemetry.createInstrumentedFailureListener(impl.getConfig(), impl.toString()));
67-
SUCCESS_LISTENER_FIELD.set(
68-
impl.getConfig(),
69-
failsafeTelemetry.createInstrumentedSuccessListener(impl.getConfig(), impl.toString()));
62+
try {
63+
RetryPolicyImpl<?> impl = (RetryPolicyImpl<?>) retryPolicyImpl;
64+
FAILURE_LISTENER_FIELD.set(
65+
impl.getConfig(),
66+
buildInstrumentedFailureListener(
67+
GlobalOpenTelemetry.get(), impl.getConfig(), impl.toString()));
68+
SUCCESS_LISTENER_FIELD.set(
69+
impl.getConfig(),
70+
buildInstrumentedSuccessListener(
71+
GlobalOpenTelemetry.get(), impl.getConfig(), impl.toString()));
72+
} catch (IllegalAccessException ignored) {
73+
// Ignored
74+
}
7075
}
7176
}
7277
}

instrumentation/failsafe-3.0/library/src/main/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetry.java

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,24 @@
1010
import static io.opentelemetry.instrumentation.failsafe.v3_0.CircuitBreakerEventListenerBuilders.buildInstrumentedHalfOpenListener;
1111
import static io.opentelemetry.instrumentation.failsafe.v3_0.CircuitBreakerEventListenerBuilders.buildInstrumentedOpenListener;
1212
import static io.opentelemetry.instrumentation.failsafe.v3_0.CircuitBreakerEventListenerBuilders.buildInstrumentedSuccessListener;
13-
import static java.util.Arrays.asList;
1413

1514
import dev.failsafe.CircuitBreaker;
1615
import dev.failsafe.CircuitBreakerConfig;
1716
import dev.failsafe.RetryPolicy;
1817
import dev.failsafe.RetryPolicyConfig;
19-
import dev.failsafe.event.EventListener;
20-
import dev.failsafe.event.ExecutionCompletedEvent;
2118
import io.opentelemetry.api.OpenTelemetry;
2219
import io.opentelemetry.api.common.AttributeKey;
2320
import io.opentelemetry.api.common.Attributes;
2421
import io.opentelemetry.api.metrics.LongCounter;
25-
import io.opentelemetry.api.metrics.LongHistogram;
2622
import io.opentelemetry.api.metrics.Meter;
23+
import io.opentelemetry.instrumentation.failsafe.v3_0.internal.RetryPolicyEventListenerBuilders;
2724

2825
/** Entrypoint for instrumenting Failsafe components. */
2926
public final class FailsafeTelemetry {
3027
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.failsafe-3.0";
3128

3229
private static final AttributeKey<String> CIRCUIT_BREAKER_NAME =
3330
AttributeKey.stringKey("failsafe.circuit_breaker.name");
34-
private static final AttributeKey<String> RETRY_POLICY_NAME =
35-
AttributeKey.stringKey("failsafe.retry_policy.name");
3631

3732
/** Returns a new {@link FailsafeTelemetry} configured with the given {@link OpenTelemetry}. */
3833
public static FailsafeTelemetry create(OpenTelemetry openTelemetry) {
@@ -89,72 +84,13 @@ public <R> CircuitBreaker<R> createCircuitBreaker(
8984
*/
9085
public <R> RetryPolicy<R> createRetryPolicy(RetryPolicy<R> delegate, String retryPolicyName) {
9186
RetryPolicyConfig<R> userConfig = delegate.getConfig();
92-
LongCounter executionCounter = buildRetryPolicyExecutionCounter();
93-
LongHistogram attemptsHistogram = buildRetryPolicyAttemptsHistogram();
94-
Attributes attributes = Attributes.of(RETRY_POLICY_NAME, retryPolicyName);
9587
return RetryPolicy.builder(userConfig)
9688
.onFailure(
9789
RetryPolicyEventListenerBuilders.buildInstrumentedFailureListener(
98-
userConfig, executionCounter, attemptsHistogram, attributes))
90+
openTelemetry, userConfig, retryPolicyName))
9991
.onSuccess(
10092
RetryPolicyEventListenerBuilders.buildInstrumentedSuccessListener(
101-
userConfig, executionCounter, attemptsHistogram, attributes))
102-
.build();
103-
}
104-
105-
/**
106-
* Returns an instrumented failure listener.
107-
*
108-
* @param delegate user policy configuration
109-
* @param retryPolicyName identifier for the policy being built
110-
* @param <R> {@link RetryPolicyConfig}'s result type
111-
* @return instrumented failure listener
112-
*/
113-
public <R> EventListener<ExecutionCompletedEvent<R>> createInstrumentedFailureListener(
114-
RetryPolicyConfig<R> delegate, String retryPolicyName) {
115-
LongCounter executionCounter = buildRetryPolicyExecutionCounter();
116-
LongHistogram attemptsHistogram = buildRetryPolicyAttemptsHistogram();
117-
Attributes attributes = Attributes.of(RETRY_POLICY_NAME, retryPolicyName);
118-
return RetryPolicyEventListenerBuilders.buildInstrumentedFailureListener(
119-
delegate, executionCounter, attemptsHistogram, attributes);
120-
}
121-
122-
/**
123-
* Returns an instrumented success listener.
124-
*
125-
* @param delegate user policy configuration
126-
* @param retryPolicyName identifier for the policy being built
127-
* @param <R> {@link RetryPolicyConfig}'s result type
128-
* @return instrumented success listener
129-
*/
130-
public <R> EventListener<ExecutionCompletedEvent<R>> createInstrumentedSuccessListener(
131-
RetryPolicyConfig<R> delegate, String retryPolicyName) {
132-
LongCounter executionCounter = buildRetryPolicyExecutionCounter();
133-
LongHistogram attemptsHistogram = buildRetryPolicyAttemptsHistogram();
134-
Attributes attributes = Attributes.of(RETRY_POLICY_NAME, retryPolicyName);
135-
return RetryPolicyEventListenerBuilders.buildInstrumentedSuccessListener(
136-
delegate, executionCounter, attemptsHistogram, attributes);
137-
}
138-
139-
private LongCounter buildRetryPolicyExecutionCounter() {
140-
return openTelemetry
141-
.getMeter(INSTRUMENTATION_NAME)
142-
.counterBuilder("failsafe.retry_policy.execution.count")
143-
.setDescription(
144-
"Count of execution attempts processed by the retry policy, "
145-
+ "where one execution represents the total number of attempts.")
146-
.setUnit("{execution}")
147-
.build();
148-
}
149-
150-
private LongHistogram buildRetryPolicyAttemptsHistogram() {
151-
return openTelemetry
152-
.getMeter(INSTRUMENTATION_NAME)
153-
.histogramBuilder("failsafe.retry_policy.attempts")
154-
.setDescription("Number of attempts for each execution.")
155-
.setUnit("{attempt}")
156-
.ofLongs()
157-
.setExplicitBucketBoundariesAdvice(asList(1L, 2L, 3L, 5L))
93+
openTelemetry, userConfig, retryPolicyName))
15894
.build();
15995
}
16096
}

instrumentation/failsafe-3.0/library/src/main/java/io/opentelemetry/instrumentation/failsafe/v3_0/RetryPolicyEventListenerBuilders.java

Lines changed: 0 additions & 55 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.failsafe.v3_0.internal;
7+
8+
import static io.opentelemetry.api.common.AttributeKey.stringKey;
9+
import static java.util.Arrays.asList;
10+
11+
import dev.failsafe.RetryPolicyConfig;
12+
import dev.failsafe.event.EventListener;
13+
import dev.failsafe.event.ExecutionCompletedEvent;
14+
import io.opentelemetry.api.OpenTelemetry;
15+
import io.opentelemetry.api.common.AttributeKey;
16+
import io.opentelemetry.api.common.Attributes;
17+
import io.opentelemetry.api.metrics.LongCounter;
18+
import io.opentelemetry.api.metrics.LongHistogram;
19+
20+
/**
21+
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
22+
* any time.
23+
*/
24+
public final class RetryPolicyEventListenerBuilders {
25+
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.failsafe-3.0";
26+
27+
private static final AttributeKey<String> OUTCOME_KEY =
28+
stringKey("failsafe.retry_policy.outcome");
29+
private static final AttributeKey<String> RETRY_POLICY_NAME =
30+
AttributeKey.stringKey("failsafe.retry_policy.name");
31+
32+
private RetryPolicyEventListenerBuilders() {}
33+
34+
public static <R> EventListener<ExecutionCompletedEvent<R>> buildInstrumentedFailureListener(
35+
OpenTelemetry openTelemetry, RetryPolicyConfig<R> userConfig, String policyName) {
36+
LongCounter executionCounter = buildRetryPolicyExecutionCounter(openTelemetry);
37+
LongHistogram attemptsHistogram = buildRetryPolicyAttemptsHistogram(openTelemetry);
38+
Attributes attributes = Attributes.of(RETRY_POLICY_NAME, policyName, OUTCOME_KEY, "failure");
39+
EventListener<ExecutionCompletedEvent<R>> userFailureListener = userConfig.getFailureListener();
40+
return e -> {
41+
executionCounter.add(1, attributes);
42+
attemptsHistogram.record(e.getAttemptCount(), attributes);
43+
if (userFailureListener != null) {
44+
userFailureListener.accept(e);
45+
}
46+
};
47+
}
48+
49+
public static <R> EventListener<ExecutionCompletedEvent<R>> buildInstrumentedSuccessListener(
50+
OpenTelemetry openTelemetry, RetryPolicyConfig<R> userConfig, String policyName) {
51+
LongCounter executionCounter = buildRetryPolicyExecutionCounter(openTelemetry);
52+
LongHistogram attemptsHistogram = buildRetryPolicyAttemptsHistogram(openTelemetry);
53+
Attributes attributes = Attributes.of(RETRY_POLICY_NAME, policyName, OUTCOME_KEY, "success");
54+
EventListener<ExecutionCompletedEvent<R>> userSuccessListener = userConfig.getSuccessListener();
55+
return e -> {
56+
executionCounter.add(1, attributes);
57+
attemptsHistogram.record(e.getAttemptCount(), attributes);
58+
if (userSuccessListener != null) {
59+
userSuccessListener.accept(e);
60+
}
61+
};
62+
}
63+
64+
private static LongCounter buildRetryPolicyExecutionCounter(OpenTelemetry openTelemetry) {
65+
return openTelemetry
66+
.getMeter(INSTRUMENTATION_NAME)
67+
.counterBuilder("failsafe.retry_policy.execution.count")
68+
.setDescription(
69+
"Count of execution attempts processed by the retry policy, "
70+
+ "where one execution represents the total number of attempts.")
71+
.setUnit("{execution}")
72+
.build();
73+
}
74+
75+
private static LongHistogram buildRetryPolicyAttemptsHistogram(OpenTelemetry openTelemetry) {
76+
return openTelemetry
77+
.getMeter(INSTRUMENTATION_NAME)
78+
.histogramBuilder("failsafe.retry_policy.attempts")
79+
.setDescription("Number of attempts for each execution.")
80+
.setUnit("{attempt}")
81+
.ofLongs()
82+
.setExplicitBucketBoundariesAdvice(asList(1L, 2L, 3L, 5L))
83+
.build();
84+
}
85+
}

instrumentation/failsafe-3.0/library/src/test/java/io/opentelemetry/instrumentation/failsafe/v3_0/FailsafeTelemetryTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import dev.failsafe.event.EventListener;
1515
import dev.failsafe.event.ExecutionCompletedEvent;
1616
import io.opentelemetry.instrumentation.failsafe.AbstractFailsafeInstrumentationTest;
17+
import io.opentelemetry.instrumentation.failsafe.v3_0.internal.RetryPolicyEventListenerBuilders;
1718
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
1819
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
1920
import java.util.Objects;
@@ -50,7 +51,6 @@ void captureRetryPolicyMetrics() {
5051
@SuppressWarnings("unchecked")
5152
void createInstrumentedFailureListener() throws Throwable {
5253
// given
53-
FailsafeTelemetry failsafeTelemetry = FailsafeTelemetry.create(testing.getOpenTelemetry());
5454
RetryPolicyConfig<Object> delegate =
5555
RetryPolicy.builder()
5656
.handleResultIf(Objects::isNull)
@@ -61,7 +61,8 @@ void createInstrumentedFailureListener() throws Throwable {
6161

6262
// when
6363
EventListener<ExecutionCompletedEvent<Object>> actual =
64-
failsafeTelemetry.createInstrumentedFailureListener(delegate, retryPolicyName);
64+
RetryPolicyEventListenerBuilders.buildInstrumentedFailureListener(
65+
testing.getOpenTelemetry(), delegate, retryPolicyName);
6566
ExecutionCompletedEvent<Object> event = mock(ExecutionCompletedEvent.class);
6667
when(event.getAttemptCount()).thenReturn(1);
6768
actual.accept(event);
@@ -83,7 +84,6 @@ void createInstrumentedFailureListener() throws Throwable {
8384
@SuppressWarnings("unchecked")
8485
void createInstrumentedSuccessListener() throws Throwable {
8586
// given
86-
FailsafeTelemetry failsafeTelemetry = FailsafeTelemetry.create(testing.getOpenTelemetry());
8787
RetryPolicyConfig<Object> delegate =
8888
RetryPolicy.builder()
8989
.handleResultIf(Objects::isNull)
@@ -94,7 +94,8 @@ void createInstrumentedSuccessListener() throws Throwable {
9494

9595
// when
9696
EventListener<ExecutionCompletedEvent<Object>> actual =
97-
failsafeTelemetry.createInstrumentedSuccessListener(delegate, retryPolicyName);
97+
RetryPolicyEventListenerBuilders.buildInstrumentedSuccessListener(
98+
testing.getOpenTelemetry(), delegate, retryPolicyName);
9899
ExecutionCompletedEvent<Object> event = mock(ExecutionCompletedEvent.class);
99100
when(event.getAttemptCount()).thenReturn(1);
100101
actual.accept(event);

0 commit comments

Comments
 (0)