Migración a Java OpenTelemetry - AWS X-Ray

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Migración a Java OpenTelemetry

En esta sección se proporciona orientación sobre la migración del SDK de X-Ray al OpenTelemetry SDK para aplicaciones Java.

Solución de instrumentación automática sin código

With X-Ray Java agent

Para habilitar el agente Java X-Ray, era necesario modificar los argumentos de la JVM de la aplicación.

-javaagent:/path-to-disco/disco-java-agent.jar=pluginPath=/path-to-disco/disco-plugins
With OpenTelemetry-based Java agent

Para utilizar agentes Java OpenTelemetry basados en Java.

  • Utilice el agente Java AWS Distro for OpenTelemetry (ADOT) Auto-Instrumentation para la instrumentación automática con el agente Java ADOT. Para obtener más información, consulte Instrumentación automática de trazas y métricas con el agente Java. Si solo desea realizar un seguimiento, desactive la variable de OTEL_METRICS_EXPORTER=none entorno para exportar las métricas del agente Java.

    (Opcional) También puede habilitar CloudWatch Application Signals al instrumentar automáticamente sus aplicaciones AWS con la instrumentación automática de ADOT Java para monitorear el estado actual de las aplicaciones y realizar un seguimiento del rendimiento de las aplicaciones a largo plazo. Application Signals proporciona una visión unificada y centrada en las aplicaciones de sus aplicaciones, servicios y dependencias, y ayuda a supervisar y evaluar el estado de las aplicaciones. Para obtener más información, consulte Application Signals.

  • Utilice el agente OpenTelemetry Java para la instrumentación automática. Para obtener más información, consulte Instrumentación sin código con el agente Java.

Soluciones de instrumentación manual con el SDK

Tracing setup with X-Ray SDK

Para instrumentar el código con el X-Ray SDK for Java, primero era necesario configurar la AWSXRay clase con complementos de servicio y reglas de muestreo locales y, a continuación, se utilizó una grabadora proporcionada.

static { AWS XRayRecorderBuilder builder = AWS XRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ECSPlugin()); AWS XRay.setGlobalRecorder(builder.build()); }
Tracing setup with OpenTelemetry SDK

Se requieren las siguientes dependencias.

<dependencyManagement> <dependencies> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-bom</artifactId> <version>1.49.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-instrumentation-bom</artifactId> <version>2.15.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-sdk</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-api</artifactId> </dependency> <dependency> <groupId>io.opentelemetry.semconv</groupId> <artifactId>opentelemetry-semconv</artifactId> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp</artifactId> </dependency> <dependency> <groupId>io.opentelemetry.contrib</groupId> <artifactId>opentelemetry-aws-xray</artifactId> <version>1.46.0</version> </dependency> <dependency> <groupId>io.opentelemetry.contrib</groupId> <artifactId>opentelemetry-aws-xray-propagator</artifactId> <version>1.46.0-alpha</version> </dependency> <dependency> <groupId>io.opentelemetry.contrib</groupId> <artifactId>opentelemetry-aws-resources</artifactId> <version>1.46.0-alpha</version> </dependency> </dependencies>

Configure el OpenTelemetry SDK creando una instancia de un objeto TracerProvider y registrándolo globalmente. OpenTelemetrySdk Configura estos componentes:

  • Un exportador OTLP Span (por ejemplo, OtlpGrpcSpanExporter): necesario para exportar las trazas al CloudWatch agente o al recopilador OpenTelemetry

  • Un propagador de AWS rayos X: necesario para propagar el contexto de rastreo a AWS los servicios integrados con X-Ray

  • Un muestreador remoto de AWS rayos X: obligatorio si necesita muestrear solicitudes utilizando las reglas de muestreo de rayos X

  • Detectores de recursos (por ejemplo, EcsResource o Ec2Resource): detectan los metadatos del host que ejecuta la aplicación

    import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.contrib.aws.resource.Ec2Resource; import io.opentelemetry.contrib.aws.resource.EcsResource; import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSampler; import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.samplers.Sampler; import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; // ... private static final Resource otelResource = Resource.create(Attributes.of(SERVICE_NAME, "YOUR_SERVICE_NAME")) .merge(EcsResource.get()) .merge(Ec2Resource.get()); private static final SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(BatchSpanProcessor.create( OtlpGrpcSpanExporter.getDefault() )) .addResource(otelResource) .setSampler(Sampler.parentBased( AwsXrayRemoteSampler.newBuilder(otelResource).build() )) .build(); // Globally registering a TracerProvider makes it available throughout the application to create as many Tracers as needed. private static final OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(AwsXrayPropagator.getInstance())) .buildAndRegisterGlobal();

Rastreo de las solicitudes entrantes (instrumentación de Spring Framework)

With X-Ray SDK

Para obtener información sobre cómo utilizar el SDK de X-Ray con el marco Spring para instrumentar su aplicación, consulte AOP with Spring y X-Ray SDK for Java. Para habilitar AOP en Spring, sigue estos pasos.

With OpenTelemetry SDK

OpenTelemetry proporciona bibliotecas de instrumentación para recopilar el seguimiento de las solicitudes entrantes de las aplicaciones Spring Boot. Para habilitar la instrumentación de Spring Boot con una configuración mínima, incluye la siguiente dependencia.

<dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-spring-boot-starter</artifactId> </dependency>

Para obtener más información sobre cómo habilitar y configurar la instrumentación de Spring Boot para su OpenTelemetry configuración, consulte Primeros OpenTelemetry pasos.

Using OpenTelemetry-based Java agents

El método recomendado por defecto para instrumentar las aplicaciones de Spring Boot es utilizar el agente OpenTelemetry Java con instrumentación de bytecode, que también proporciona más out-of-the-box instrumentaciones y configuraciones en comparación con el uso directo del SDK. Solución de instrumentación automática sin códigoPara empezar, consulte.

AWS Instrumentación del SDK v2

With X-Ray SDK

El X-Ray SDK for Java puede instrumentar automáticamente todos los clientes del AWS SDK v2 al añadir el aws-xray-recorder-sdk-aws-sdk-v2-instrumentor submódulo a la compilación.

Para instrumentar las llamadas de clientes individuales posteriores a AWS los servicios con el AWS SDK para Java 2.2 y versiones posteriores, se excluyó el aws-xray-recorder-sdk-aws-sdk-v2-instrumentor módulo de la configuración de compilación y se incluyó el aws-xray-recorder-sdk-aws-sdk-v2 módulo. Los clientes individuales se instrumentaron configurándolos con un. TracingInterceptor

import com.amazonaws.xray.interceptors.TracingInterceptor; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration import software.amazon.awssdk.services.dynamodb.DynamoDbClient; //... public class MyModel { private DynamoDbClient client = DynamoDbClient.builder() .region(Region.US_WEST_2) .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(new TracingInterceptor()) .build() ) .build(); //...
With OpenTelemetry SDK

Para instrumentar automáticamente todos los clientes AWS del SDK, añada el opentelemetry-aws-sdk-2.2-autoconfigure submódulo.

<dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-aws-sdk-2.2-autoconfigure</artifactId> <version>2.15.0-alpha</version> <scope>runtime</scope> </dependency>

Para instrumentar clientes de AWS SDK individuales, añada el opentelemetry-aws-sdk-2.2 submódulo.

<dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-aws-sdk-2.2</artifactId> <version>2.15.0-alpha</version> <scope>compile</scope> </dependency>

A continuación, registre un interceptor al crear un cliente de AWS SDK.

import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; // ... AwsSdkTelemetry telemetry = AwsSdkTelemetry.create(openTelemetry); private final S3Client S3_CLIENT = S3Client.builder() .overrideConfiguration(ClientOverrideConfiguration.builder() .addExecutionInterceptor(telemetry.newExecutionInterceptor()) .build()) .build();

Instrumentación de llamadas a HTTP salientes

With X-Ray SDK

Para instrumentar las solicitudes HTTP salientes con X-Ray, se necesitaba el SDK de X-Ray para la versión de Apache HttpClient de Java.

import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder; ... public String randomName() throws IOException { CloseableHttpClient httpclient = HttpClientBuilder.create().build();
With OpenTelemetry SDK

Al igual que el SDK de Java X-Ray, OpenTelemetry proporciona una ApacheHttpClientTelemetry clase que tiene un método de creación que permite la creación de una instancia de un HttpClientBuilder para proporcionar OpenTelemetry intervalos basados y propagación de contexto para Apache HttpClient.

<dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-apache-httpclient-5.2</artifactId> <version>2.15.0-alpha</version> <scope>compile</scope> </dependency>

El siguiente es un ejemplo de código de opentelemetry-java-instrumentation. El cliente HTTP proporcionado por newHttpClient () generará seguimientos para las solicitudes ejecutadas.

import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.apachehttpclient.v5_2.ApacheHttpClientTelemetry; import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; public class ApacheHttpClientConfiguration { private OpenTelemetry openTelemetry; public ApacheHttpClientConfiguration(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; } // creates a new http client builder for constructing http clients with open telemetry instrumentation public HttpClientBuilder createBuilder() { return ApacheHttpClientTelemetry.builder(openTelemetry).build().newHttpClientBuilder(); } // creates a new http client with open telemetry instrumentation public HttpClient newHttpClient() { return ApacheHttpClientTelemetry.builder(openTelemetry).build().newHttpClient(); } }

Soporte de instrumentación para otras bibliotecas

Encuentre la lista completa de instrumentaciones de biblioteca compatibles con OpenTelemetry Java en su GitHub repositorio de instrumentación respectivo, en Bibliotecas, marcos, servidores de aplicaciones y. JVMs

También puede buscar en el OpenTelemetry Registro si OpenTelemetry es compatible con la instrumentación. Para empezar a buscar, consulte el Registro.

Creación manual de datos de rastreo

With X-Ray SDK

Con el SDK de X-Ray, se necesitan beginSubsegment los métodos beginSegment y métodos para crear manualmente segmentos y subsegmentos de rayos X.

Segment segment = xrayRecorder.beginSegment("ManualSegment"); segment.putAnnotation("annotationKey", "annotationValue"); segment.putMetadata("metadataKey", "metadataValue"); try { Subsegment subsegment = xrayRecorder.beginSubsegment("ManualSubsegment"); subsegment.putAnnotation("key", "value"); // Do something here } catch (Exception e) { subsegment.addException(e); } finally { xrayRecorder.endSegment(); }
With OpenTelemetry SDK

Puede utilizar intervalos personalizados para supervisar el rendimiento de las actividades internas que no se recopilan en las bibliotecas de instrumentación. Tenga en cuenta que solo los servidores de tipo tramo se convierten en segmentos de rayos X, todos los demás tramos se convierten en subsegmentos de rayos X.

En primer lugar, tendrás que crear un rastreador para generar intervalos, que puedes obtener mediante este método. openTelemetry.getTracer Esto proporcionará una instancia de Tracer de la TracerProvider que se registró globalmente en el ejemplo. Soluciones de instrumentación manual con el SDK Puede crear tantas instancias de Tracer como necesite, pero es habitual tener una sola instancia de Tracer para toda la aplicación.

Tracer tracer = openTelemetry.getTracer("my-app");

Puede usar el Tracer para crear intervalos.

import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; ... // SERVER span will become an X-Ray segment Span span = tracer.spanBuilder("get-token") .setKind(SpanKind.SERVER) .setAttribute("key", "value") .startSpan(); try (Scope ignored = span.makeCurrent()) { span.setAttribute("metadataKey", "metadataValue"); span.setAttribute("annotationKey", "annotationValue"); // The following ensures that "annotationKey: annotationValue" is an annotation in X-Ray raw data. span.setAttribute(AttributeKey.stringArrayKey("aws.xray.annotations"), List.of("annotationKey")); // Do something here } span.end();

Los tramos tienen un tipo predeterminado de INTERNO.

// Default span of type INTERNAL will become an X-Ray subsegment Span span = tracer.spanBuilder("process-header") .startSpan(); try (Scope ignored = span.makeCurrent()) { doProcessHeader(); }

Añadir anotaciones y metadatos a los seguimientos con el SDK OpenTelemetry

En el ejemplo anterior, el setAttribute método se utiliza para añadir atributos a cada tramo. De forma predeterminada, todos los atributos del intervalo se convertirán en metadatos en los datos sin procesar de X-Ray. Para garantizar que un atributo se convierta en una anotación y no en metadatos, en el ejemplo anterior se agrega la clave de ese atributo a la lista de aws.xray.annotations atributos. Para obtener más información, consulte Habilitar las anotaciones y anotaciones de rayos X personalizadas y los metadatos.

Con agentes Java OpenTelemetry basados

Si utiliza el agente Java para instrumentar automáticamente la aplicación, necesitará realizar la instrumentación manual en la aplicación. Por ejemplo, al código de instrumentos dentro de la aplicación para secciones que no están cubiertas por ninguna biblioteca de autoinstrumentación.

Para realizar la instrumentación manual con el agente, es necesario utilizar el artefacto. opentelemetry-api La versión del artefacto no puede ser más reciente que la versión del agente.

import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.trace.Span; // ... Span parentSpan = Span.current(); Tracer tracer = GlobalOpenTelemetry.getTracer("my-app"); Span span = tracer.spanBuilder("my-span-name") .setParent(io.opentelemetry.context.Context.current().with(parentSpan)) .startSpan(); span.end();

Instrumentación Lambda

With X-Ray SDK

Al usar el SDK de X-Ray, una vez que su Lambda tenga activado el rastreo activo, no se requiere ninguna configuración adicional para usar el SDK de X-Ray. Lambda creará un segmento que represente la invocación del controlador de Lambda y usted puede crear subsegmentos o bibliotecas de instrumentos mediante el SDK de X-Ray sin necesidad de realizar ninguna configuración adicional.

With OpenTelemetry-based solutions

Autoinstrumentación de capas Lambda: puede instrumentar automáticamente su Lambda con capas Lambda vendidas AWS mediante las siguientes soluciones:

  • CloudWatch Capa Lambda de Application Signals (recomendada)

    nota

    Esta capa Lambda tiene las señales de CloudWatch aplicación habilitadas de forma predeterminada, lo que permite monitorear el rendimiento y el estado de la aplicación Lambda mediante la recopilación de métricas y trazas. Solo para el seguimiento, defina la variable de entorno Lambda. OTEL_AWS_APPLICATION_SIGNALS_ENABLED=false

    • Permite la supervisión del rendimiento y el estado de su aplicación Lambda

    • Recopila tanto las métricas como los seguimientos de forma predeterminada

  • AWS capa Lambda gestionada para ADOT Java. Para obtener más información, consulte AWS Distro for OpenTelemetry Lambda Support For Java.

Para utilizar la instrumentación manual junto con la capa de autoinstrumentación, consulte. Soluciones de instrumentación manual con el SDK Para reducir los arranques en frío, considere la posibilidad de utilizar instrumentación OpenTelemetry manual para generar OpenTelemetry trazas para la función Lambda.

OpenTelemetry instrumentación manual para Lambda AWS

Considere el siguiente código de función de Lambda que realiza una llamada a Amazon S3 ListBuckets .

package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.ListBucketsRequest; import software.amazon.awssdk.services.s3.model.ListBucketsResponse; import software.amazon.awssdk.services.s3.model.S3Exception; public class ListBucketsLambda implements RequestHandler<String, String> { private final S3Client S3_CLIENT = S3Client.builder() .build(); @Override public String handleRequest(String input, Context context) { try { ListBucketsResponse response = makeListBucketsCall(); context.getLogger().log("response: " + response.toString()); return "Success"; } catch (Exception e) { throw new RuntimeException(e); } } private ListBucketsResponse makeListBucketsCall() { try { ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder() .build(); ListBucketsResponse response = S3_CLIENT.listBuckets(listBucketsRequest); return response; } catch (S3Exception e) { throw new RuntimeException("Failed to call S3 listBuckets" + e.awsErrorDetails().errorMessage(), e); } } }

Estas son las dependencias.

dependencies { implementation('com.amazonaws:aws-lambda-java-core:1.2.3') implementation('software.amazon.awssdk:s3:2.28.29') implementation('org.slf4j:slf4j-nop:2.0.16') }

Para instrumentar manualmente el controlador de Lambda y el cliente Amazon S3, haga lo siguiente.

  1. Sustituya las clases de funciones que implementan RequestHandler (o RequestStreamHandler) por las que amplían TracingRequestHandler (o TracingRequestStreamHandler).

  2. Cree una instancia de un objeto TracerProvider y regístrelo globalmente. OpenTelemetrySdk Se TracerProvider recomienda configurarlo con:

    1. Un procesador Span simple con un exportador de intervalos UDP de rayos X para enviar trazas al punto final UDP X-Ray de Lambda

    2. Un muestreador ParentBased siempre activo (predeterminado si no está configurado)

    3. Un recurso con service.name establecido en el nombre de la función Lambda

    4. Un propagador Lambda de X-Ray

  3. Cambia el handleRequest método a la clase base doHandleRequest y pasa el OpenTelemetrySdk objeto a ella.

  4. Instrumente el cliente Amazon S3 con la instrumentación del OpenTemetry AWS SDK registrando el interceptor al crear el cliente.

Necesita las siguientes dependencias OpenTelemetry relacionadas.

dependencies { ... implementation("software.amazon.distro.opentelemetry:aws-distro-opentelemetry-xray-udp-span-exporter:0.1.0") implementation(platform('io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.14.0')) implementation(platform('io.opentelemetry:opentelemetry-bom:1.48.0')) implementation('io.opentelemetry:opentelemetry-sdk') implementation('io.opentelemetry:opentelemetry-api') implementation('io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.45.0-alpha') implementation('io.opentelemetry.contrib:opentelemetry-aws-resources:1.45.0-alpha') implementation('io.opentelemetry.instrumentation:opentelemetry-aws-lambda-core-1.0:2.14.0-alpha') implementation('io.opentelemetry.instrumentation:opentelemetry-aws-sdk-2.2:2.14.0-alpha') }

El código siguiente muestra la función Lambda después de los cambios necesarios. Puede crear intervalos personalizados adicionales para complementar los intervalos que se proporcionan automáticamente.

package example; import java.time.Duration; import com.amazonaws.services.lambda.runtime.Context; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.contrib.aws.resource.LambdaResource; import io.opentelemetry.contrib.awsxray.propagator.AwsXrayLambdaPropagator; import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import io.opentelemetry.sdk.trace.samplers.Sampler; import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.ListBucketsRequest; import software.amazon.awssdk.services.s3.model.ListBucketsResponse; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.distro.opentelemetry.exporter.xray.udp.trace.AwsXrayUdpSpanExporterBuilder; public class ListBucketsLambda extends TracingRequestHandler<String, String> { private static final Resource lambdaResource = LambdaResource.get(); private static final SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create( new AwsXrayUdpSpanExporterBuilder().build() )) .addResource( lambdaResource .merge(Resource.create(Attributes.of(SERVICE_NAME, System.getenv("AWS_LAMBDA_FUNCTION_NAME")))) ) .setSampler(Sampler.parentBased(Sampler.alwaysOn())) .build(); private static final OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(AwsXrayLambdaPropagator.getInstance())) .buildAndRegisterGlobal(); private static final AwsSdkTelemetry telemetry = AwsSdkTelemetry.create(openTelemetry); private final S3Client S3_CLIENT = S3Client.builder() .overrideConfiguration(ClientOverrideConfiguration.builder() .addExecutionInterceptor(telemetry.newExecutionInterceptor()) .build()) .build(); public ListBucketsLambda() { super(openTelemetry, Duration.ofMillis(0)); } @Override public String doHandleRequest(String input, Context context) { try { ListBucketsResponse response = makeListBucketsCall(); context.getLogger().log("response: " + response.toString()); return "Success"; } catch (Exception e) { throw new RuntimeException(e); } } private ListBucketsResponse makeListBucketsCall() { try { ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder() .build(); ListBucketsResponse response = S3_CLIENT.listBuckets(listBucketsRequest); return response; } catch (S3Exception e) { throw new RuntimeException("Failed to call S3 listBuckets" + e.awsErrorDetails().errorMessage(), e); } } }

Al invocar la función Lambda, verá la siguiente traza en Trace Map en CloudWatch la consola.

Mapa de rastreo en CloudWatch la consola.