Add InstrumenterBuilder.addRequestListener
MODIFY
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java
@@ -232,10 +232,11 @@ public class Instrumenter<REQUEST, RESPONSE> {
if (!requestListeners.isEmpty() || !requestMetricListeners.isEmpty()) {
long endNanos = getNanos(endTime);
- for (RequestListener requestListener : requestListeners) {
+ // TODO (trask) call end in the reverse order that start was called?
+ for (RequestListener requestListener : requestMetricListeners) {
requestListener.end(context, attributes, endNanos);
}
- for (RequestListener requestListener : requestMetricListeners) {
+ for (RequestListener requestListener : requestListeners) {
requestListener.end(context, attributes, endNanos);
}
}

MODIFY
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java
@@ -125,7 +125,13 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
return this;
}
- /** Adds a {@link RequestMetrics} whose metrics will be recorded for request start and stop. */
+ /** Adds a {@link RequestListener} which will be called for request start and end. */
+ public InstrumenterBuilder<REQUEST, RESPONSE> addRequestListener(RequestListener listener) {
+ requestListeners.add(listener);
+ return this;
+ }
+
+ /** Adds a {@link RequestMetrics} whose metrics will be recorded for request start and end. */
@UnstableApi
public InstrumenterBuilder<REQUEST, RESPONSE> addRequestMetrics(RequestMetrics factory) {
requestMetricListeners.add(factory.create(meter));

MODIFY
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java
@@ -431,6 +431,38 @@ class InstrumenterTest {
.hasParentSpanId("090a0b0c0d0e0f00")));
}
+ @Test
+ void requestListeners() {
+ AtomicReference<Boolean> startContext = new AtomicReference<>();
+ AtomicReference<Boolean> endContext = new AtomicReference<>();
+
+ RequestListener requestListener =
+ new RequestListener() {
+ @Override
+ public Context start(Context context, Attributes startAttributes, long startNanos) {
+ startContext.set(true);
+ return context;
+ }
+
+ @Override
+ public void end(Context context, Attributes endAttributes, long endNanos) {
+ endContext.set(true);
+ }
+ };
+
+ Instrumenter<Map<String, String>, Map<String, String>> instrumenter =
+ Instrumenter.<Map<String, String>, Map<String, String>>builder(
+ otelTesting.getOpenTelemetry(), "test", unused -> "span")
+ .addRequestListener(requestListener)
+ .newServerInstrumenter(new MapGetter());
+
+ Context context = instrumenter.start(Context.root(), REQUEST);
+ instrumenter.end(context, REQUEST, RESPONSE, null);
+
+ assertThat(startContext.get()).isTrue();
+ assertThat(endContext.get()).isTrue();
+ }
+
@Test
void requestMetrics() {
AtomicReference<Context> startContext = new AtomicReference<>();

Add InstrumenterBuilder.addRequestListener (#5655)