Skip to content

Commit

Permalink
feat: add opentelemetry instrumentation (#1051)
Browse files Browse the repository at this point in the history
  • Loading branch information
scrocquesel authored Dec 23, 2023
1 parent 2ea2652 commit 3608cd8
Show file tree
Hide file tree
Showing 38 changed files with 666 additions and 35 deletions.
15 changes: 15 additions & 0 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
<artifactId>aws-crt</artifactId>
<version>${awscrt.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-aws-sdk-2.2</artifactId>
<version>${awsotel.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-crt</artifactId>
Expand Down Expand Up @@ -57,6 +62,16 @@
<artifactId>quarkus-amazon-common-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-opentelemetry-internal</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-opentelemetry-internal-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-apache-client-internal</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
import io.quarkus.amazon.common.runtime.AmazonClientAwsCrtTransportRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientCommonRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientNettyTransportRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientOpenTelemetryRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientUrlConnectionTransportRecorder;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
Expand Down Expand Up @@ -156,16 +158,20 @@ void setupAwsCrtAsyncTransport(List<AmazonClientBuildItem> amazonClients, Cognit
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void createClientBuilders(CognitoUserPoolsRecorder recorder,
Capabilities capabilities,
AmazonClientCommonRecorder commonRecorder,
AmazonClientOpenTelemetryRecorder otelRecorder,
List<AmazonClientSyncTransportBuildItem> syncTransports,
List<AmazonClientAsyncTransportBuildItem> asyncTransports,
BuildProducer<SyntheticBeanBuildItem> syntheticBeans,
BuildProducer<AmazonClientSyncResultBuildItem> clientSync,
BuildProducer<AmazonClientAsyncResultBuildItem> clientAsync,
ExecutorBuildItem executorBuildItem) {

createClientBuilders(recorder,
createClientBuilders(capabilities,
recorder,
commonRecorder,
otelRecorder,
buildTimeConfig,
syncTransports,
asyncTransports,
Expand Down
42 changes: 42 additions & 0 deletions common/deployment-opentelemetry-internal/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-common-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<artifactId>quarkus-amazon-opentelemetry-internal-deployment</artifactId>
<name>Quarkus - Amazon Services - Apache Client - Internal - Deployment</name>
<description>This module only exists to house opentelemetry-aws-sdk-2.2 as a conditional dependency</description>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-opentelemetry-internal</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
10 changes: 10 additions & 0 deletions common/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-common</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-aws-sdk-2.2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-opentelemetry-internal-deployment</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-netty-client-internal-deployment</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@

import jakarta.enterprise.context.ApplicationScoped;

import org.jboss.jandex.ClassType;
import org.jboss.jandex.DotName;
import org.jboss.jandex.ParameterizedType;
import org.jboss.jandex.Type;

import io.netty.channel.EventLoopGroup;
import io.opentelemetry.api.OpenTelemetry;
import io.quarkus.amazon.common.runtime.AmazonClientApacheTransportRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientAwsCrtTransportRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientCommonRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientNettyTransportRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientOpenTelemetryRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientRecorder;
import io.quarkus.amazon.common.runtime.AmazonClientUrlConnectionTransportRecorder;
import io.quarkus.amazon.common.runtime.AsyncHttpClientBuildTimeConfig;
Expand All @@ -31,6 +34,8 @@
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.arc.processor.InjectionPointInfo;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.builditem.ExecutorBuildItem;
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
Expand Down Expand Up @@ -216,8 +221,11 @@ protected void createAwsCrtAsyncTransportBuilder(List<AmazonClientBuildItem> ama
});
}

protected void createClientBuilders(AmazonClientRecorder recorder,
protected void createClientBuilders(
Capabilities capabilities,
AmazonClientRecorder recorder,
AmazonClientCommonRecorder commonRecorder,
AmazonClientOpenTelemetryRecorder otelRecorder,
HasSdkBuildTimeConfig sdkBuildConfig,
List<AmazonClientSyncTransportBuildItem> syncTransports,
List<AmazonClientAsyncTransportBuildItem> asyncTransports,
Expand All @@ -234,7 +242,9 @@ protected void createClientBuilders(AmazonClientRecorder recorder,
presignerBuilder = recorder.createPresignerBuilder();
}

createClientBuilders(commonRecorder,
createClientBuilders(capabilities,
commonRecorder,
otelRecorder,
recorder.getAwsConfig(),
recorder.getSdkConfig(),
sdkBuildConfig,
Expand All @@ -253,7 +263,9 @@ protected void createClientBuilders(AmazonClientRecorder recorder,
}

private void createClientBuilders(
Capabilities capabilities,
AmazonClientCommonRecorder recorder,
AmazonClientOpenTelemetryRecorder otelRecorder,
RuntimeValue<AwsConfig> awsConfigRuntime,
RuntimeValue<SdkConfig> sdkConfigRuntime,
HasSdkBuildTimeConfig sdkBuildConfig,
Expand Down Expand Up @@ -294,25 +306,47 @@ private void createClientBuilders(
: null;

ScheduledExecutorService sharedExecutorService = executorBuildItem.getExecutorProxy();
var addOpenTelemetry = sdkBuildConfig.sdk().telemetry().orElse(false)
&& capabilities.isPresent(Capability.OPENTELEMETRY_TRACER);

if (syncClientBuilder != null) {
syncClientBuilder = recorder.configure(syncClientBuilder, awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, sharedExecutorService, configName());
syntheticBeans.produce(SyntheticBeanBuildItem.configure(syncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(syncClientBuilder)
.done());
if (addOpenTelemetry) {
syntheticBeans.produce(SyntheticBeanBuildItem
.configure(syncClientBuilderClass)
.defaultBean()
.scope(ApplicationScoped.class)
.setRuntimeInit()
.createWith(otelRecorder.configure(syncClientBuilder))
.addInjectionPoint(ClassType.create(OpenTelemetry.class)).done());
} else {
syntheticBeans.produce(SyntheticBeanBuildItem.configure(syncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(syncClientBuilder)
.done());
}
clientSync.produce(new AmazonClientSyncResultBuildItem(configName));
}
if (asyncClientBuilder != null) {
asyncClientBuilder = recorder.configure(asyncClientBuilder, awsConfigRuntime, sdkConfigRuntime,
sdkBuildConfig, sharedExecutorService, configName());
syntheticBeans.produce(SyntheticBeanBuildItem.configure(asyncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(asyncClientBuilder)
.done());
if (addOpenTelemetry) {
syntheticBeans.produce(SyntheticBeanBuildItem
.configure(asyncClientBuilderClass)
.defaultBean()
.scope(ApplicationScoped.class)
.setRuntimeInit()
.createWith(otelRecorder.configure(asyncClientBuilder))
.addInjectionPoint(ClassType.create(OpenTelemetry.class)).done());
} else {
syntheticBeans.produce(SyntheticBeanBuildItem.configure(asyncClientBuilderClass)
.setRuntimeInit()
.scope(ApplicationScoped.class)
.runtimeValue(asyncClientBuilder)
.done());
}
clientAsync.produce(new AmazonClientAsyncResultBuildItem(configName));
}
if (presignerBuilder != null) {
Expand Down
2 changes: 2 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
<module>runtime-apache-client-internal</module>
<module>runtime-netty-client-internal</module>
<module>runtime-crt-client-internal</module>
<module>runtime-opentelemetry-internal</module>
<module>runtime</module>
<module>deployment-devservices-spi</module>
<module>deployment-spi</module>
<module>deployment-apache-client-internal</module>
<module>deployment-netty-client-internal</module>
<module>deployment-crt-client-internal</module>
<module>deployment-opentelemetry-internal</module>
<module>deployment</module>
</modules>

Expand Down
60 changes: 60 additions & 0 deletions common/runtime-opentelemetry-internal/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-common-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<artifactId>quarkus-amazon-opentelemetry-internal</artifactId>
<name>Quarkus - Amazon Services - OpenTelemetry - Runtime - Internal</name>
<description>This module only exists to house opentelemetry-aws-sdk-2.2 as a conditional dependency</description>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-aws-sdk-2.2</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>extension-descriptor</goal>
</goals>
<configuration>
<dependencyCondition>
<artifact>io.quarkus:quarkus-opentelemetry</artifact>
</dependencyCondition>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
10 changes: 10 additions & 0 deletions common/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@
<groupId>software.amazon.awssdk</groupId>
<artifactId>auth</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-aws-sdk-2.2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.quarkiverse.amazonservices</groupId>
<artifactId>quarkus-amazon-opentelemetry-internal</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>http-client-spi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.quarkus.amazon.common.runtime;

import java.util.function.Function;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;
import io.quarkus.arc.SyntheticCreationalContext;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import software.amazon.awssdk.awscore.client.builder.AwsClientBuilder;

@Recorder
public class AmazonClientOpenTelemetryRecorder {

public Function<SyntheticCreationalContext<AwsClientBuilder>, AwsClientBuilder> configure(
RuntimeValue<AwsClientBuilder> clientBuilder) {
return new Function<SyntheticCreationalContext<AwsClientBuilder>, AwsClientBuilder>() {
@Override
public AwsClientBuilder apply(SyntheticCreationalContext<AwsClientBuilder> context) {
AwsClientBuilder builder = clientBuilder.getValue();
OpenTelemetry openTelemetry = context.getInjectedReference(OpenTelemetry.class);

builder.overrideConfiguration(
builder.overrideConfiguration().toBuilder()
.addExecutionInterceptor(AwsSdkTelemetry.create(openTelemetry).newExecutionInterceptor())
.build());

return builder;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithName;

/**
* AWS SDK specific configurations
Expand All @@ -21,4 +23,11 @@ public interface SdkBuildTimeConfig {
* @see software.amazon.awssdk.core.interceptor.ExecutionInterceptor
*/
Optional<List<String>> interceptors(); // cannot be classes as can be runtime initialized (e.g. XRay interceptor)

/**
* OpenTelemetry AWS SDK instrumentation will be enabled if the OpenTelemetry extension is present and this value is true.
*/
@WithName("telemetry.enabled")
@ConfigDocDefault("false")
Optional<Boolean> telemetry();
}
Loading

0 comments on commit 3608cd8

Please sign in to comment.