Skip to content

Commit c477ecd

Browse files
committed
Review comments addressed
1 parent 7095e91 commit c477ecd

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
@@ -16,6 +16,7 @@
1616
import dev.failsafe.event.EventListener;
1717
import dev.failsafe.event.ExecutionCompletedEvent;
1818
import io.opentelemetry.instrumentation.failsafe.AbstractFailsafeInstrumentationTest;
19+
import io.opentelemetry.instrumentation.failsafe.v3_0.internal.RetryPolicyEventListenerBuilders;
1920
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
2021
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
2122
import io.opentelemetry.sdk.testing.assertj.LongPointAssert;
@@ -54,7 +55,6 @@ void captureRetryPolicyMetrics() {
5455
@SuppressWarnings("unchecked")
5556
void createInstrumentedFailureListener() throws Throwable {
5657
// given
57-
FailsafeTelemetry failsafeTelemetry = FailsafeTelemetry.create(testing.getOpenTelemetry());
5858
RetryPolicyConfig<Object> delegate =
5959
RetryPolicy.builder()
6060
.handleResultIf(Objects::isNull)
@@ -65,7 +65,8 @@ void createInstrumentedFailureListener() throws Throwable {
6565

6666
// when
6767
EventListener<ExecutionCompletedEvent<Object>> actual =
68-
failsafeTelemetry.createInstrumentedFailureListener(delegate, retryPolicyName);
68+
RetryPolicyEventListenerBuilders.buildInstrumentedFailureListener(
69+
testing.getOpenTelemetry(), delegate, retryPolicyName);
6970
ExecutionCompletedEvent<Object> event = mock(ExecutionCompletedEvent.class);
7071
when(event.getAttemptCount()).thenReturn(1);
7172
actual.accept(event);
@@ -87,7 +88,6 @@ void createInstrumentedFailureListener() throws Throwable {
8788
@SuppressWarnings("unchecked")
8889
void createInstrumentedSuccessListener() throws Throwable {
8990
// given
90-
FailsafeTelemetry failsafeTelemetry = FailsafeTelemetry.create(testing.getOpenTelemetry());
9191
RetryPolicyConfig<Object> delegate =
9292
RetryPolicy.builder()
9393
.handleResultIf(Objects::isNull)
@@ -98,7 +98,8 @@ void createInstrumentedSuccessListener() throws Throwable {
9898

9999
// when
100100
EventListener<ExecutionCompletedEvent<Object>> actual =
101-
failsafeTelemetry.createInstrumentedSuccessListener(delegate, retryPolicyName);
101+
RetryPolicyEventListenerBuilders.buildInstrumentedSuccessListener(
102+
testing.getOpenTelemetry(), delegate, retryPolicyName);
102103
ExecutionCompletedEvent<Object> event = mock(ExecutionCompletedEvent.class);
103104
when(event.getAttemptCount()).thenReturn(1);
104105
actual.accept(event);

0 commit comments

Comments
 (0)