Skip to content

Commit

Permalink
Disable instrumentation according with SDK config
Browse files Browse the repository at this point in the history
  • Loading branch information
brunobat committed Sep 26, 2024
1 parent ee69757 commit 6ccff48
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
Expand Down Expand Up @@ -34,7 +33,6 @@
import io.quarkus.resteasy.reactive.server.spi.PreExceptionMapperHandlerBuildItem;
import io.quarkus.resteasy.reactive.spi.CustomContainerRequestFilterBuildItem;
import io.quarkus.vertx.core.deployment.VertxOptionsConsumerBuildItem;
import io.vertx.core.VertxOptions;

@BuildSteps(onlyIf = TracerEnabled.class)
public class InstrumentationProcessor {
Expand Down Expand Up @@ -112,9 +110,7 @@ VertxOptionsConsumerBuildItem vertxTracingMetricsOptions(InstrumentationRecorder
@Record(ExecutionTime.RUNTIME_INIT)
VertxOptionsConsumerBuildItem vertxTracingOptions(
InstrumentationRecorder recorder) {
Consumer<VertxOptions> vertxTracingOptions;
vertxTracingOptions = recorder.getVertxTracingOptions();
return new VertxOptionsConsumerBuildItem(vertxTracingOptions, LIBRARY_AFTER);
return new VertxOptionsConsumerBuildItem(recorder.getVertxTracingOptions(), LIBRARY_AFTER);
}

// RESTEasy and Vert.x web
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package io.quarkus.opentelemetry.deployment;

import static org.junit.jupiter.api.Assertions.assertFalse;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.quarkus.opentelemetry.runtime.exporter.otlp.tracing.LateBoundBatchSpanProcessor;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.HttpInstrumenterVertxTracer;
import io.quarkus.test.QuarkusUnitTest;
import io.vertx.core.spi.observability.HttpRequest;
import io.vertx.core.spi.observability.HttpResponse;

@Disabled("Not implemented")
public class OpenTelemetryDisabledSdkTest {

@RegisterExtension
Expand All @@ -25,9 +30,48 @@ public class OpenTelemetryDisabledSdkTest {
@Inject
OpenTelemetry openTelemetry;

@Inject
OTelRuntimeConfig runtimeConfig;

@Test
void testNoTracer() {
// The OTel API doesn't provide a clear way to check if a tracer is an effective NOOP tracer.
Assertions.assertTrue(batchSpanProcessor.isDelegateNull(), "BatchSpanProcessor delegate must not be set");
}

@Test
void noReceiveRequestInstrumenter() {
HttpInstrumenterVertxTracer instrumenter = new HttpInstrumenterVertxTracer(openTelemetry, runtimeConfig);

Instrumenter<HttpRequest, HttpResponse> receiveRequestInstrumenter = instrumenter.getReceiveRequestInstrumenter();
assertFalse(receiveRequestInstrumenter.shouldStart(null, null),
"Instrumenter must not start, if it does, it will throw an exception because of the null objects we are passing");
}

@Test
void noReceiveResponseInstrumenter() {
HttpInstrumenterVertxTracer instrumenter = new HttpInstrumenterVertxTracer(openTelemetry, runtimeConfig);

Instrumenter<HttpRequest, HttpResponse> receiveRequestInstrumenter = instrumenter.getReceiveResponseInstrumenter();
assertFalse(receiveRequestInstrumenter.shouldStart(null, null),
"Instrumenter must not start, if it does, it will throw an exception because of the null objects we are passing");
}

@Test
void noSendRequestInstrumenter() {
HttpInstrumenterVertxTracer instrumenter = new HttpInstrumenterVertxTracer(openTelemetry, runtimeConfig);

Instrumenter<HttpRequest, HttpResponse> receiveRequestInstrumenter = instrumenter.getSendRequestInstrumenter();
assertFalse(receiveRequestInstrumenter.shouldStart(null, null),
"Instrumenter must not start, if it does, it will throw an exception because of the null objects we are passing");
}

@Test
void noSendResponseInstrumenter() {
HttpInstrumenterVertxTracer instrumenter = new HttpInstrumenterVertxTracer(openTelemetry, runtimeConfig);

Instrumenter<HttpRequest, HttpResponse> receiveRequestInstrumenter = instrumenter.getSendResponseInstrumenter();
assertFalse(receiveRequestInstrumenter.shouldStart(null, null),
"Instrumenter must not start, if it does, it will throw an exception because of the null objects we are passing");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.quarkus.arc.ArcInvocationContext;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.tuples.Functions;
Expand All @@ -38,12 +39,14 @@
public class WithSpanInterceptor {
private final Instrumenter<MethodRequest, Void> instrumenter;

public WithSpanInterceptor(final OpenTelemetry openTelemetry) {
public WithSpanInterceptor(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
InstrumenterBuilder<MethodRequest, Void> builder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME,
new MethodRequestSpanNameExtractor());

builder.setEnabled(!runtimeConfig.sdkDisabled());

MethodSpanAttributesExtractor<MethodRequest, Void> attributesExtractor = MethodSpanAttributesExtractor.create(
MethodRequest::getMethod,
new WithSpanParameterAttributeNamesExtractor(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ public InstrumentationRecorder(RuntimeValue<OTelRuntimeConfig> config) {
this.config = config;
}

/* RUNTIME INIT */
@RuntimeInit
public Consumer<VertxOptions> getVertxTracingOptions() {
if (config.getValue().sdkDisabled()) {
return vertxOptions -> {
};
}
TracingOptions tracingOptions = new TracingOptions()
.setFactory(FACTORY);
return vertxOptions -> vertxOptions.setTracingOptions(tracingOptions);
Expand All @@ -44,25 +49,30 @@ public Consumer<VertxOptions> getVertxTracingOptions() {
@RuntimeInit
public void setupVertxTracer(BeanContainer beanContainer, boolean sqlClientAvailable,
boolean redisClientAvailable) {

if (config.getValue().sdkDisabled()) {
return;
}

OpenTelemetry openTelemetry = beanContainer.beanInstance(OpenTelemetry.class);
List<InstrumenterVertxTracer<?, ?>> tracers = new ArrayList<>(4);
if (config.getValue().instrument().vertxHttp()) {
tracers.add(new HttpInstrumenterVertxTracer(openTelemetry));
tracers.add(new HttpInstrumenterVertxTracer(openTelemetry, config.getValue()));
}
if (config.getValue().instrument().vertxEventBus()) {
tracers.add(new EventBusInstrumenterVertxTracer(openTelemetry));
tracers.add(new EventBusInstrumenterVertxTracer(openTelemetry, config.getValue()));
}
if (sqlClientAvailable && config.getValue().instrument().vertxSqlClient()) {
tracers.add(new SqlClientInstrumenterVertxTracer(openTelemetry));
tracers.add(new SqlClientInstrumenterVertxTracer(openTelemetry, config.getValue()));
}
if (redisClientAvailable && config.getValue().instrument().vertxRedisClient()) {
tracers.add(new RedisClientInstrumenterVertxTracer(openTelemetry));
tracers.add(new RedisClientInstrumenterVertxTracer(openTelemetry, config.getValue()));
}
OpenTelemetryVertxTracer openTelemetryVertxTracer = new OpenTelemetryVertxTracer(tracers);
FACTORY.getVertxTracerDelegator().setDelegate(openTelemetryVertxTracer);
}

/* RUNTIME INIT */
/* STATIC INIT */
public Consumer<VertxOptions> getVertxTracingMetricsOptions() {
MetricsOptions metricsOptions = new MetricsOptions()
.setEnabled(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.quarkus.grpc.GlobalInterceptor;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;

@Singleton
@GlobalInterceptor
public class GrpcTracingClientInterceptor implements ClientInterceptor {
private final OpenTelemetry openTelemetry;
private final Instrumenter<GrpcRequest, Status> instrumenter;

public GrpcTracingClientInterceptor(final OpenTelemetry openTelemetry) {
public GrpcTracingClientInterceptor(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
this.openTelemetry = openTelemetry;

InstrumenterBuilder<GrpcRequest, Status> builder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME,
new GrpcSpanNameExtractor());

builder.setEnabled(!runtimeConfig.sdkDisabled());

builder.addAttributesExtractor(RpcClientAttributesExtractor.create(GrpcAttributesGetter.INSTANCE))
.addAttributesExtractor(new GrpcStatusCodeExtractor())
.setSpanStatusExtractor(new GrpcSpanStatusExtractor());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,21 @@
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter;
import io.quarkus.grpc.GlobalInterceptor;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;

@Singleton
@GlobalInterceptor
public class GrpcTracingServerInterceptor implements ServerInterceptor {
private final Instrumenter<GrpcRequest, Status> instrumenter;

public GrpcTracingServerInterceptor(final OpenTelemetry openTelemetry) {
public GrpcTracingServerInterceptor(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
InstrumenterBuilder<GrpcRequest, Status> builder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME,
new GrpcSpanNameExtractor());

builder.setEnabled(!runtimeConfig.sdkDisabled());

GrpcServerNetworkAttributesGetter getter = new GrpcServerNetworkAttributesGetter();

builder.addAttributesExtractor(RpcServerAttributesExtractor.create(GrpcAttributesGetter.INSTANCE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.ext.Provider;

import org.eclipse.microprofile.config.ConfigProvider;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
Expand All @@ -29,6 +31,8 @@
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanStatusExtractor;
import io.quarkus.arc.Unremovable;
import io.quarkus.opentelemetry.runtime.QuarkusContextStorage;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.smallrye.config.SmallRyeConfig;

/**
* A client filter for the JAX-RS Client and MicroProfile REST Client that records OpenTelemetry data. This is only used
Expand Down Expand Up @@ -56,18 +60,23 @@ public class OpenTelemetryClientFilter implements ClientRequestFilter, ClientRes
// RESTEasy requires no-arg constructor for CDI injection: https://issues.redhat.com/browse/RESTEASY-1538
// In Reactive Rest Client this is the constructor called. In the classic is the next one with injection.
public OpenTelemetryClientFilter() {
this(GlobalOpenTelemetry.get());
this(GlobalOpenTelemetry.get(),
ConfigProvider.getConfig()
.unwrap(SmallRyeConfig.class)
.getConfigMapping(OTelRuntimeConfig.class));
}

@Inject
public OpenTelemetryClientFilter(final OpenTelemetry openTelemetry) {
public OpenTelemetryClientFilter(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
ClientAttributesExtractor clientAttributesExtractor = new ClientAttributesExtractor();

InstrumenterBuilder<ClientRequestContext, ClientResponseContext> builder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(clientAttributesExtractor));

builder.setEnabled(!runtimeConfig.sdkDisabled());

this.instrumenter = builder
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(clientAttributesExtractor))
.addAttributesExtractor(HttpClientAttributesExtractor.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.quarkus.scheduler.spi.JobInstrumenter;

@Singleton
public class OpenTelemetryJobInstrumenter implements JobInstrumenter {

private final Instrumenter<JobInstrumentationContext, Void> instrumenter;

public OpenTelemetryJobInstrumenter(OpenTelemetry openTelemetry) {
public OpenTelemetryJobInstrumenter(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
InstrumenterBuilder<JobInstrumentationContext, Void> instrumenterBuilder = Instrumenter.builder(
openTelemetry, "io.quarkus.opentelemetry",
new SpanNameExtractor<JobInstrumentationContext>() {
Expand All @@ -27,6 +28,9 @@ public String extract(JobInstrumentationContext context) {
return context.getSpanName();
}
});

instrumenterBuilder.setEnabled(!runtimeConfig.sdkDisabled());

instrumenterBuilder.setErrorCauseExtractor(new ErrorCauseExtractor() {
@Override
public Throwable extract(Throwable throwable) {
Expand All @@ -39,13 +43,15 @@ public Throwable extract(Throwable throwable) {
@Override
public CompletionStage<Void> instrument(JobInstrumentationContext instrumentationContext) {
Context parentCtx = Context.current();
Context context = instrumenter.start(parentCtx, instrumentationContext);
try (Scope scope = context.makeCurrent()) {
return instrumentationContext
.executeJob()
.whenComplete(
(result, throwable) -> instrumenter.end(context, instrumentationContext, null, throwable));
if (instrumenter.shouldStart(parentCtx, instrumentationContext)) {
Context context = instrumenter.start(parentCtx, instrumentationContext);
try (Scope scope = context.makeCurrent()) {
return instrumentationContext
.executeJob()
.whenComplete(
(result, throwable) -> instrumenter.end(context, instrumentationContext, null, throwable));
}
}
return instrumentationContext.executeJob();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.opentelemetry.instrumentation.api.incubator.semconv.messaging.MessagingSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.vertx.core.eventbus.Message;
import io.vertx.core.spi.tracing.TagExtractor;

Expand All @@ -19,9 +20,9 @@ public class EventBusInstrumenterVertxTracer implements InstrumenterVertxTracer<
private final Instrumenter<Message, Message> consumerInstrumenter;
private final Instrumenter<Message, Message> producerInstrumenter;

public EventBusInstrumenterVertxTracer(final OpenTelemetry openTelemetry) {
this.consumerInstrumenter = getConsumerInstrumenter(openTelemetry);
this.producerInstrumenter = getProducerInstrumenter(openTelemetry);
public EventBusInstrumenterVertxTracer(final OpenTelemetry openTelemetry, final OTelRuntimeConfig runtimeConfig) {
this.consumerInstrumenter = getConsumerInstrumenter(openTelemetry, runtimeConfig);
this.producerInstrumenter = getProducerInstrumenter(openTelemetry, runtimeConfig);
}

@Override
Expand Down Expand Up @@ -49,11 +50,14 @@ public Instrumenter<Message, Message> getReceiveResponseInstrumenter() {
return producerInstrumenter;
}

private static Instrumenter<Message, Message> getConsumerInstrumenter(final OpenTelemetry openTelemetry) {
private static Instrumenter<Message, Message> getConsumerInstrumenter(final OpenTelemetry openTelemetry,
final OTelRuntimeConfig runtimeConfig) {
InstrumenterBuilder<Message, Message> serverBuilder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME, MessagingSpanNameExtractor.create(EventBusAttributesGetter.INSTANCE, RECEIVE));

serverBuilder.setEnabled(!runtimeConfig.sdkDisabled());

return serverBuilder
.addAttributesExtractor(MessagingAttributesExtractor.create(EventBusAttributesGetter.INSTANCE, RECEIVE))
.buildConsumerInstrumenter(new TextMapGetter<>() {
Expand All @@ -72,11 +76,14 @@ public String get(final Message message, final String key) {
});
}

private static Instrumenter<Message, Message> getProducerInstrumenter(final OpenTelemetry openTelemetry) {
private static Instrumenter<Message, Message> getProducerInstrumenter(final OpenTelemetry openTelemetry,
final OTelRuntimeConfig runtimeConfig) {
InstrumenterBuilder<Message, Message> serverBuilder = Instrumenter.builder(
openTelemetry,
INSTRUMENTATION_NAME, MessagingSpanNameExtractor.create(EventBusAttributesGetter.INSTANCE, PUBLISH));

serverBuilder.setEnabled(!runtimeConfig.sdkDisabled());

return serverBuilder
.addAttributesExtractor(MessagingAttributesExtractor.create(EventBusAttributesGetter.INSTANCE, PUBLISH))
.buildProducerInstrumenter((message, key, value) -> {
Expand Down
Loading

0 comments on commit 6ccff48

Please sign in to comment.