Skip to content

Commit 493ae80

Browse files
committed
Make behavior opt-in
1 parent 8d74151 commit 493ae80

File tree

9 files changed

+52
-8
lines changed

9 files changed

+52
-8
lines changed

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java

+15-8
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public static <REQUEST, RESPONSE> InstrumenterBuilder<REQUEST, RESPONSE> builder
7878
private final ContextCustomizer<? super REQUEST>[] contextCustomizers;
7979
private final OperationListener[] operationListeners;
8080
private final ErrorCauseExtractor errorCauseExtractor;
81+
private final boolean propagateOperationListenersToOnEnd;
8182
private final boolean enabled;
8283
private final SpanSuppressor spanSuppressor;
8384

@@ -93,6 +94,7 @@ public static <REQUEST, RESPONSE> InstrumenterBuilder<REQUEST, RESPONSE> builder
9394
this.contextCustomizers = builder.contextCustomizers.toArray(new ContextCustomizer[0]);
9495
this.operationListeners = builder.buildOperationListeners().toArray(new OperationListener[0]);
9596
this.errorCauseExtractor = builder.errorCauseExtractor;
97+
this.propagateOperationListenersToOnEnd = builder.propagateOperationListenersToOnEnd;
9698
this.enabled = builder.enabled;
9799
this.spanSuppressor = builder.buildSpanSuppressor();
98100
}
@@ -202,10 +204,12 @@ private Context doStart(Context parentContext, REQUEST request, @Nullable Instan
202204
context = operationListeners[i].onStart(context, attributes, startNanos);
203205
}
204206
}
205-
// when start and end are not called on the same instrumenter we need to use the operation
206-
// listeners that were used during start and end to correctly handle metrics like
207-
// http.server.active_requests that is recorded both in start and end
208-
context = context.with(START_OPERATION_LISTENERS, operationListeners);
207+
if (propagateOperationListenersToOnEnd) {
208+
// when start and end are not called on the same instrumenter we need to use the operation
209+
// listeners that were used during start and end to correctly handle metrics like
210+
// http.server.active_requests that is recorded both in start and end
211+
context = context.with(START_OPERATION_LISTENERS, operationListeners);
212+
}
209213

210214
if (localRoot) {
211215
context = LocalRootSpan.store(context, span);
@@ -236,11 +240,14 @@ private void doEnd(
236240
}
237241
span.setAllAttributes(attributes);
238242

239-
OperationListener[] startOperationListeners = context.get(START_OPERATION_LISTENERS);
240-
if (startOperationListeners != null && startOperationListeners.length != 0) {
243+
OperationListener[] operationListeners = context.get(START_OPERATION_LISTENERS);
244+
if (operationListeners == null) {
245+
operationListeners = this.operationListeners;
246+
}
247+
if (operationListeners.length != 0) {
241248
long endNanos = getNanos(endTime);
242-
for (int i = startOperationListeners.length - 1; i >= 0; i--) {
243-
startOperationListeners[i].onEnd(context, attributes, endNanos);
249+
for (int i = operationListeners.length - 1; i >= 0; i--) {
250+
operationListeners[i].onEnd(context, attributes, endNanos);
244251
}
245252
}
246253

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java

+11
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
6666
SpanStatusExtractor<? super REQUEST, ? super RESPONSE> spanStatusExtractor =
6767
SpanStatusExtractor.getDefault();
6868
ErrorCauseExtractor errorCauseExtractor = ErrorCauseExtractor.getDefault();
69+
boolean propagateOperationListenersToOnEnd = false;
6970
boolean enabled = true;
7071

7172
InstrumenterBuilder(
@@ -370,6 +371,10 @@ private Set<SpanKey> getSpanKeysFromAttributesExtractors() {
370371
.collect(Collectors.toSet());
371372
}
372373

374+
private void propagateOperationListenersToOnEnd() {
375+
propagateOperationListenersToOnEnd = true;
376+
}
377+
373378
private interface InstrumenterConstructor<RQ, RS> {
374379
Instrumenter<RQ, RS> create(InstrumenterBuilder<RQ, RS> builder);
375380

@@ -406,6 +411,12 @@ public <RQ, RS> Instrumenter<RQ, RS> buildDownstreamInstrumenter(
406411
SpanKindExtractor<RQ> spanKindExtractor) {
407412
return builder.buildDownstreamInstrumenter(setter, spanKindExtractor);
408413
}
414+
415+
@Override
416+
public <RQ, RS> void propagateOperationListenersToOnEnd(
417+
InstrumenterBuilder<RQ, RS> builder) {
418+
builder.propagateOperationListenersToOnEnd();
419+
}
409420
});
410421
}
411422
}

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/InstrumenterBuilderAccess.java

+3
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> buildDownstreamInstrumenter(
2626
InstrumenterBuilder<REQUEST, RESPONSE> builder,
2727
TextMapSetter<REQUEST> setter,
2828
SpanKindExtractor<REQUEST> spanKindExtractor);
29+
30+
<REQUEST, RESPONSE> void propagateOperationListenersToOnEnd(
31+
InstrumenterBuilder<REQUEST,RESPONSE> builder);
2932
}

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/InstrumenterUtil.java

+6
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,11 @@ public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> buildDownstrea
6767
builder, setter, spanKindExtractor);
6868
}
6969

70+
public static <REQUEST, RESPONSE> void propagateOperationListenersToOnEnd(
71+
InstrumenterBuilder<REQUEST, RESPONSE> builder) {
72+
// instrumenterBuilderAccess is guaranteed to be non-null here
73+
instrumenterBuilderAccess.propagateOperationListenersToOnEnd(builder);
74+
}
75+
7076
private InstrumenterUtil() {}
7177
}

instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11Singletons.java

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class Jetty11Singletons {
2424
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
2525
.addContextCustomizer(
2626
(context, request, attributes) -> new AppServerBridge.Builder().init(context))
27+
.propagateOperationListenersToOnEnd()
2728
.build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE);
2829

2930
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =

instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class Jetty8Singletons {
2424
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
2525
.addContextCustomizer(
2626
(context, request, attributes) -> new AppServerBridge.Builder().init(context))
27+
.propagateOperationListenersToOnEnd()
2728
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
2829

2930
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =

instrumentation/liberty/liberty-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertySingletons.java

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class LibertySingletons {
2424
.addContextCustomizer(
2525
(context, request, attributes) ->
2626
new AppServerBridge.Builder().recordException().init(context))
27+
.propagateOperationListenersToOnEnd()
2728
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
2829

2930
private static final LibertyHelper<HttpServletRequest, HttpServletResponse> HELPER =

instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletInstrumenterBuilder.java

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
1515
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
1616
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
17+
import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil;
1718
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor;
1819
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesGetter;
1920
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerMetrics;
@@ -31,6 +32,8 @@ private ServletInstrumenterBuilder() {}
3132
private final List<ContextCustomizer<? super ServletRequestContext<REQUEST>>> contextCustomizers =
3233
new ArrayList<>();
3334

35+
private boolean propagateOperationListenersToOnEnd;
36+
3437
public static <REQUEST, RESPONSE> ServletInstrumenterBuilder<REQUEST, RESPONSE> create() {
3538
return new ServletInstrumenterBuilder<>();
3639
}
@@ -42,6 +45,12 @@ public ServletInstrumenterBuilder<REQUEST, RESPONSE> addContextCustomizer(
4245
return this;
4346
}
4447

48+
@CanIgnoreReturnValue
49+
public ServletInstrumenterBuilder<REQUEST, RESPONSE> propagateOperationListenersToOnEnd() {
50+
propagateOperationListenersToOnEnd = true;
51+
return this;
52+
}
53+
4554
public Instrumenter<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>> build(
4655
String instrumentationName,
4756
ServletAccessor<REQUEST, RESPONSE> accessor,
@@ -85,6 +94,9 @@ public Instrumenter<ServletRequestContext<REQUEST>, ServletResponseContext<RESPO
8594
.addAttributesExtractor(HttpExperimentalAttributesExtractor.create(httpAttributesGetter))
8695
.addOperationMetrics(HttpServerExperimentalMetrics.get());
8796
}
97+
if (propagateOperationListenersToOnEnd) {
98+
InstrumenterUtil.propagateOperationListenersToOnEnd(builder);
99+
}
88100
return builder.buildServerInstrumenter(new ServletRequestGetter<>(accessor));
89101
}
90102

instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatInstrumenterFactory.java

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpServerExperimentalMetrics;
1111
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
1212
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
13+
import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil;
1314
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor;
1415
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerMetrics;
1516
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute;
@@ -61,6 +62,7 @@ public static <REQUEST, RESPONSE> Instrumenter<Request, Response> create(
6162
.addAttributesExtractor(HttpExperimentalAttributesExtractor.create(httpAttributesGetter))
6263
.addOperationMetrics(HttpServerExperimentalMetrics.get());
6364
}
65+
InstrumenterUtil.propagateOperationListenersToOnEnd(builder);
6466
return builder.buildServerInstrumenter(TomcatRequestGetter.INSTANCE);
6567
}
6668
}

0 commit comments

Comments
 (0)