Skip to content

Commit

Permalink
Merge pull request quarkusio#28792 from brunobat/otel-autoconfigure-3
Browse files Browse the repository at this point in the history
Fix vertx otel sdk reload in devmode
  • Loading branch information
radcortez authored Dec 5, 2022
2 parents f4d156c + 71c6f7d commit be10ea3
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@
import io.quarkus.arc.deployment.InterceptorBindingRegistrarBuildItem;
import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.arc.processor.InterceptorBindingRegistrar;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
Expand All @@ -36,8 +33,7 @@
import io.quarkus.opentelemetry.runtime.QuarkusContextStorage;
import io.quarkus.opentelemetry.runtime.config.OpenTelemetryConfig;
import io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.reactivemessaging.ReactiveMessagingTracingDecorator;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.restclient.OpenTelemetryClientFilter;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.InstrumentationRecorder;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
Expand Down Expand Up @@ -130,31 +126,12 @@ public void transform(TransformationContext context) {
}));
}

@BuildStep
void registerRestClientClassicProvider(
Capabilities capabilities,
BuildProducer<AdditionalIndexedClassesBuildItem> additionalIndexed,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
if (capabilities.isPresent(Capability.REST_CLIENT) && capabilities.isMissing(Capability.REST_CLIENT_REACTIVE)) {
additionalIndexed.produce(new AdditionalIndexedClassesBuildItem(OpenTelemetryClientFilter.class.getName()));
additionalBeans.produce(new AdditionalBeanBuildItem(OpenTelemetryClientFilter.class));
}
}

@BuildStep
void registerReactiveMessagingMessageDecorator(
Capabilities capabilities,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
if (capabilities.isPresent(Capability.SMALLRYE_REACTIVE_MESSAGING)) {
additionalBeans.produce(new AdditionalBeanBuildItem(ReactiveMessagingTracingDecorator.class));
}
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void createOpenTelemetry(
OpenTelemetryConfig openTelemetryConfig,
OpenTelemetryRecorder recorder,
InstrumentationRecorder instrumentationRecorder,
Optional<TracerProviderBuildItem> tracerProviderBuildItem,
LaunchModeBuildItem launchMode) {

Expand All @@ -166,6 +143,11 @@ void createOpenTelemetry(
.orElse(null);
recorder.createOpenTelemetry(tracerProvider, openTelemetryConfig);
recorder.eagerlyCreateContextStorage();

// just checking for live reload would bypass the OpenTelemetryDevModeTest
if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT) {
instrumentationRecorder.setTracerDevMode(instrumentationRecorder.createTracers());
}
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package io.quarkus.opentelemetry.deployment.tracing;

import static io.quarkus.bootstrap.classloading.QuarkusClassLoader.isClassPresentAtRuntime;
import static javax.interceptor.Interceptor.Priority.LIBRARY_AFTER;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BooleanSupplier;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;
Expand Down Expand Up @@ -43,10 +37,7 @@
import io.quarkus.opentelemetry.runtime.config.TracerRuntimeConfig;
import io.quarkus.opentelemetry.runtime.tracing.TracerRecorder;
import io.quarkus.opentelemetry.runtime.tracing.cdi.TracerProducer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.grpc.GrpcTracingClientInterceptor;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.grpc.GrpcTracingServerInterceptor;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.vertx.core.deployment.VertxOptionsConsumerBuildItem;
import io.quarkus.vertx.http.deployment.spi.FrameworkEndpointsBuildItem;
import io.quarkus.vertx.http.deployment.spi.StaticResourcesBuildItem;

Expand All @@ -58,38 +49,6 @@ public class TracerProcessor {
private static final DotName SPAN_EXPORTER = DotName.createSimple(SpanExporter.class.getName());
private static final DotName SPAN_PROCESSOR = DotName.createSimple(SpanProcessor.class.getName());

static class MetricsExtensionAvailable implements BooleanSupplier {
private static final boolean IS_MICROMETER_EXTENSION_AVAILABLE = isClassPresentAtRuntime(
"io.quarkus.micrometer.runtime.binder.vertx.VertxHttpServerMetrics");

@Override
public boolean getAsBoolean() {
Config config = ConfigProvider.getConfig();
if (IS_MICROMETER_EXTENSION_AVAILABLE) {
if (config.getOptionalValue("quarkus.micrometer.enabled", Boolean.class).orElse(true)) {
Optional<Boolean> httpServerEnabled = config
.getOptionalValue("quarkus.micrometer.binder.http-server.enabled", Boolean.class);
if (httpServerEnabled.isPresent()) {
return httpServerEnabled.get();
} else {
return config.getOptionalValue("quarkus.micrometer.binder-enabled-default", Boolean.class).orElse(true);
}
}
}
return false;
}
}

static class GrpcExtensionAvailable implements BooleanSupplier {
private static final boolean IS_GRPC_EXTENSION_AVAILABLE = isClassPresentAtRuntime(
"io.quarkus.grpc.runtime.GrpcServerRecorder");

@Override
public boolean getAsBoolean() {
return IS_GRPC_EXTENSION_AVAILABLE;
}
}

@BuildStep
UnremovableBeanBuildItem ensureProducersAreRetained(
CombinedIndexBuildItem indexBuildItem,
Expand Down Expand Up @@ -179,24 +138,6 @@ void dropNames(
dropStaticResources.produce(new DropStaticResourcesBuildItem(resources));
}

@BuildStep(onlyIf = GrpcExtensionAvailable.class)
void grpcTracers(BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
additionalBeans.produce(new AdditionalBeanBuildItem(GrpcTracingServerInterceptor.class));
additionalBeans.produce(new AdditionalBeanBuildItem(GrpcTracingClientInterceptor.class));
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
VertxOptionsConsumerBuildItem vertxTracingOptions(TracerRecorder recorder) {
return new VertxOptionsConsumerBuildItem(recorder.getVertxTracingOptions(), LIBRARY_AFTER);
}

@BuildStep(onlyIfNot = MetricsExtensionAvailable.class)
@Record(ExecutionTime.STATIC_INIT)
VertxOptionsConsumerBuildItem vertxTracingMetricsOptions(TracerRecorder recorder) {
return new VertxOptionsConsumerBuildItem(recorder.getVertxTracingMetricsOptions(), LIBRARY_AFTER + 1);
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
TracerProviderBuildItem createTracerProvider(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package io.quarkus.opentelemetry.deployment.tracing.instrumentation;

import static io.quarkus.bootstrap.classloading.QuarkusClassLoader.isClassPresentAtRuntime;
import static javax.interceptor.Interceptor.Priority.LIBRARY_AFTER;

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;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.opentelemetry.deployment.tracing.TracerEnabled;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.InstrumentationRecorder;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.grpc.GrpcTracingClientInterceptor;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.grpc.GrpcTracingServerInterceptor;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.reactivemessaging.ReactiveMessagingTracingDecorator;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.restclient.OpenTelemetryClientFilter;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.vertx.core.deployment.VertxOptionsConsumerBuildItem;
import io.vertx.core.VertxOptions;

@BuildSteps(onlyIf = TracerEnabled.class)
public class InstrumentationProcessor {
static class MetricsExtensionAvailable implements BooleanSupplier {
private static final boolean IS_MICROMETER_EXTENSION_AVAILABLE = isClassPresentAtRuntime(
"io.quarkus.micrometer.runtime.binder.vertx.VertxHttpServerMetrics");

@Override
public boolean getAsBoolean() {
Config config = ConfigProvider.getConfig();
if (IS_MICROMETER_EXTENSION_AVAILABLE) {
if (config.getOptionalValue("quarkus.micrometer.enabled", Boolean.class).orElse(true)) {
Optional<Boolean> httpServerEnabled = config
.getOptionalValue("quarkus.micrometer.binder.http-server.enabled", Boolean.class);
if (httpServerEnabled.isPresent()) {
return httpServerEnabled.get();
} else {
return config.getOptionalValue("quarkus.micrometer.binder-enabled-default", Boolean.class).orElse(true);
}
}
}
return false;
}
}

static class GrpcExtensionAvailable implements BooleanSupplier {
private static final boolean IS_GRPC_EXTENSION_AVAILABLE = isClassPresentAtRuntime(
"io.quarkus.grpc.runtime.GrpcServerRecorder");

@Override
public boolean getAsBoolean() {
return IS_GRPC_EXTENSION_AVAILABLE;
}
}

@BuildStep(onlyIf = GrpcExtensionAvailable.class)
void grpcTracers(BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
additionalBeans.produce(new AdditionalBeanBuildItem(GrpcTracingServerInterceptor.class));
additionalBeans.produce(new AdditionalBeanBuildItem(GrpcTracingClientInterceptor.class));
}

@BuildStep
void registerRestClientClassicProvider(
Capabilities capabilities,
BuildProducer<AdditionalIndexedClassesBuildItem> additionalIndexed,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
if (capabilities.isPresent(Capability.REST_CLIENT) && capabilities.isMissing(Capability.REST_CLIENT_REACTIVE)) {
additionalIndexed.produce(new AdditionalIndexedClassesBuildItem(OpenTelemetryClientFilter.class.getName()));
additionalBeans.produce(new AdditionalBeanBuildItem(OpenTelemetryClientFilter.class));
}
}

@BuildStep
void registerReactiveMessagingMessageDecorator(
Capabilities capabilities,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
if (capabilities.isPresent(Capability.SMALLRYE_REACTIVE_MESSAGING)) {
additionalBeans.produce(new AdditionalBeanBuildItem(ReactiveMessagingTracingDecorator.class));
}
}

@BuildStep(onlyIfNot = MetricsExtensionAvailable.class)
@Record(ExecutionTime.STATIC_INIT)
VertxOptionsConsumerBuildItem vertxTracingMetricsOptions(InstrumentationRecorder recorder) {
return new VertxOptionsConsumerBuildItem(recorder.getVertxTracingMetricsOptions(), LIBRARY_AFTER + 1);
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
VertxOptionsConsumerBuildItem vertxTracingOptions(InstrumentationRecorder recorder,
LaunchModeBuildItem launchMode) {
Consumer<VertxOptions> vertxTracingOptions;
if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT) {
// tracers are set in the OpenTelemetryProcessor
vertxTracingOptions = recorder.getVertxTracingOptionsDevMode();
} else {
vertxTracingOptions = recorder.getVertxTracingOptionsProd(recorder.createTracers());
}
return new VertxOptionsConsumerBuildItem(
vertxTracingOptions,
LIBRARY_AFTER);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public final class OpenTelemetryConfig {
@ConfigItem(defaultValue = "tracecontext,baggage")
public List<String> propagators;

/** Build / static runtime config for tracer */
/**
* Build / static runtime config for tracer
*/
public TracerConfig tracer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
Expand All @@ -21,31 +20,12 @@
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import io.quarkus.arc.Arc;
import io.quarkus.opentelemetry.runtime.config.TracerRuntimeConfig;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxMetricsFactory;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxTracingFactory;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.vertx.core.VertxOptions;
import io.vertx.core.metrics.MetricsOptions;
import io.vertx.core.tracing.TracingOptions;

@Recorder
public class TracerRecorder {
/* STATIC INIT */
public Consumer<VertxOptions> getVertxTracingOptions() {
TracingOptions tracingOptions = new TracingOptions()
.setFactory(new OpenTelemetryVertxTracingFactory());
return vertxOptions -> vertxOptions.setTracingOptions(tracingOptions);
}

public Consumer<VertxOptions> getVertxTracingMetricsOptions() {
MetricsOptions metricsOptions = new MetricsOptions()
.setEnabled(true)
.setFactory(new OpenTelemetryVertxMetricsFactory());
return vertxOptions -> vertxOptions.setMetricsOptions(metricsOptions);
}

/* STATIC INIT */
public RuntimeValue<SdkTracerProvider> createTracerProvider(
String quarkusVersion,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.quarkus.opentelemetry.runtime.tracing.intrumentation;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.EventBusInstrumenterVertxTracer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.HttpInstrumenterVertxTracer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.InstrumenterVertxTracer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxMetricsFactory;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxTracer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxTracingDevModeFactory;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.OpenTelemetryVertxTracingFactory;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.vertx.SqlClientInstrumenterVertxTracer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.vertx.core.VertxOptions;
import io.vertx.core.metrics.MetricsOptions;
import io.vertx.core.tracing.TracingOptions;

@Recorder
public class InstrumentationRecorder {

public static final OpenTelemetryVertxTracingDevModeFactory FACTORY = new OpenTelemetryVertxTracingDevModeFactory();

/* RUNTIME INIT */
public RuntimeValue<OpenTelemetryVertxTracer> createTracers() {
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
List<InstrumenterVertxTracer<?, ?>> instrumenterVertxTracers = new ArrayList<>();
instrumenterVertxTracers.add(new HttpInstrumenterVertxTracer(openTelemetry));
instrumenterVertxTracers.add(new EventBusInstrumenterVertxTracer(openTelemetry));
// TODO - Selectively register this in the recorder if the SQL Client is available.
instrumenterVertxTracers.add(new SqlClientInstrumenterVertxTracer(openTelemetry));
return new RuntimeValue<>(new OpenTelemetryVertxTracer(instrumenterVertxTracers));
}

/* RUNTIME INIT */
public Consumer<VertxOptions> getVertxTracingOptionsProd(
RuntimeValue<OpenTelemetryVertxTracer> tracer) {
TracingOptions tracingOptions = new TracingOptions()
.setFactory(new OpenTelemetryVertxTracingFactory(tracer.getValue()));
return vertxOptions -> vertxOptions.setTracingOptions(tracingOptions);
}

/* RUNTIME INIT */
public Consumer<VertxOptions> getVertxTracingOptionsDevMode() {
TracingOptions tracingOptions = new TracingOptions()
.setFactory(FACTORY);
return vertxOptions -> vertxOptions.setTracingOptions(tracingOptions);
}

/* RUNTIME INIT */
public void setTracerDevMode(RuntimeValue<OpenTelemetryVertxTracer> tracer) {
FACTORY.getVertxTracerDelegator().setDelegate(tracer.getValue());
}

/* RUNTIME INIT */
public Consumer<VertxOptions> getVertxTracingMetricsOptions() {
MetricsOptions metricsOptions = new MetricsOptions()
.setEnabled(true)
.setFactory(new OpenTelemetryVertxMetricsFactory());
return vertxOptions -> vertxOptions.setMetricsOptions(metricsOptions);
}
}
Loading

0 comments on commit be10ea3

Please sign in to comment.