Instrumentación del código Java en AWS Lambda - AWS Lambda

Instrumentación del código Java en AWS Lambda

Lambda se integra con AWS X-Ray para permitirle seguir, depurar y optimizar aplicaciones de Lambda. Puede utilizar X-Ray para seguir una solicitud mientras atraviesa los recursos de la aplicación, que pueden incluir funciones de Lambda y otros servicios de AWS.

Para enviar datos de seguimiento a X-Ray, puede utilizar una de estas dos bibliotecas de SDK:

Cada uno de los SDK ofrecen formas de enviar los datos de telemetría al servicio X-Ray. Tras ello, se puede utilizar X-Ray para consultar, filtrar y obtener información sobre las métricas de rendimiento de la aplicación con el fin de identificar problemas y oportunidades de optimización.

importante

Los SDK de X-Ray y Powertools para AWS Lambda son parte de una solución de instrumentación completamente integrada que ofrece AWS. Las capas Lambda de ADOT forman parte de un estándar que abarca todo el sector para la instrumentación de seguimiento que recopila más datos en general, pero es posible que no sean adecuadas para todos los casos de uso. Puede implementar el seguimiento integral en X-Ray con cualquiera de las soluciones. Para obtener más información sobre cuál elegir, consulte Elegir entre SDK de AWS Distro para OpenTelemetry y X-Ray.

Uso de Powertools para AWS Lambda (Java) y AWS SAM para el seguimiento

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de Java con módulos de Powertools para AWS Lambda (Java) integrados mediante AWS SAM. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje hello world.

Requisitos previos

Para completar los pasos de esta sección, debe disponer de lo siguiente:

Implementar una aplicación de ejemplo de AWS SAM
  1. Inicialice la aplicación con la plantilla “Hola, mundo” de Java.

    sam init --app-template hello-world-powertools-java --name sam-app --package-type Zip --runtime java11 --no-tracing
  2. Compile la aplicación.

    cd sam-app && sam build
  3. Implemente la aplicación.

    sam deploy --guided
  4. Siga las indicaciones que aparecen en pantalla. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima Enter.

    nota

    En HelloWorldFunction es posible que no tenga definida la autorización, ¿está bien?, asegúrese de ingresar y.

  5. Obtenga la URL de la aplicación implementada:

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. Invoque el punto de conexión de la API:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    Si se realiza de forma correcta, verá el siguiente resultado:

    {"message":"hello world"}
  7. Para obtener el seguimiento de la función, ejecute sam traces.

    sam traces

    El resultado del seguimiento tendrá este aspecto:

    New XRay Service Graph Start time: 2023-02-03 14:31:48+01:00 End time: 2023-02-03 14:31:48+01:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 5.587 Reference Id: 1 - client - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 3] at (2023-02-03T14:31:48.500000) with id (1-63dd0cc4-3c869dec72a586875da39777) and duration (5.603s) - 5.587s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD [HTTP: 200] - 4.053s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - 1.181s - Initialization - 4.037s - Invocation - 1.981s - ## handleRequest - 1.840s - ## getPageContents - 0.000s - Overhead
  8. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

    sam delete

Uso de Powertools para AWS Lambda (Java) y el AWS CDK para el seguimiento

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de Java con módulos de Powertools para AWS Lambda (Java) integrados mediante AWS CDK. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje hello world.

Requisitos previos

Para completar los pasos de esta sección, debe disponer de lo siguiente:

Implementar una aplicación de ejemplo de AWS CDK
  1. Cree un directorio de proyecto para la nueva aplicación.

    mkdir hello-world cd hello-world
  2. Inicialice la aplicación.

    cdk init app --language java
  3. Ejecute el siguiente comando para crear el proyecto de Maven:

    mkdir app cd app mvn archetype:generate -DgroupId=helloworld -DartifactId=Function -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  4. Abra pom.xml en el directorio hello-world\app\Function y sustituya el código existente por el siguiente código, el cual incluye dependencias y complementos de Maven para Powertools.

    <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>helloworld</groupId> <artifactId>Function</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>Function</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <log4j.version>2.17.2</log4j.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-tracing</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-metrics</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-logging</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> <complianceLevel>${maven.compiler.target}</complianceLevel> <aspectLibraries> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-tracing</artifactId> </aspectLibrary> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-metrics</artifactId> </aspectLibrary> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-logging</artifactId> </aspectLibrary> </aspectLibraries> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> </transformer> </transformers> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>function</finalName> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.15</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
  5. Cree el directorio hello-world\app\src\main\resource y cree log4j.xml para la configuración del registro.

    mkdir -p src/main/resource cd src/main/resource touch log4j.xml
  6. Abra log4j.xml y agregue el siguiente código.

    <?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="JsonAppender" target="SYSTEM_OUT"> <JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" /> </Console> </Appenders> <Loggers> <Logger name="JsonLogger" level="INFO" additivity="false"> <AppenderRef ref="JsonAppender"/> </Logger> <Root level="info"> <AppenderRef ref="JsonAppender"/> </Root> </Loggers> </Configuration>
  7. Abra App.java desde el directorio hello-world\app\Function\src\main\java\helloworld y sustituya el código existente por el siguiente código. Se trata del código de la función de Lambda.

    package helloworld; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import software.amazon.lambda.powertools.logging.Logging; import software.amazon.lambda.powertools.metrics.Metrics; import software.amazon.lambda.powertools.tracing.CaptureMode; import software.amazon.lambda.powertools.tracing.Tracing; import static software.amazon.lambda.powertools.tracing.CaptureMode.*; /** * Handler for requests to Lambda function. */ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { Logger log = LogManager.getLogger(App.class); @Logging(logEvent = true) @Tracing(captureMode = DISABLED) @Metrics(captureColdStart = true) public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() .withHeaders(headers); try { final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); return response .withStatusCode(200) .withBody(output); } catch (IOException e) { return response .withBody("{}") .withStatusCode(500); } } @Tracing(namespace = "getPageContents") private String getPageContents(String address) throws IOException { log.info("Retrieving {}", address); URL url = new URL(address); try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } }
  8. Abra HelloWorldStack.java desde el directorio hello-world\src\main\java\com\myorg y sustituya el código existente por el siguiente código. Este código utiliza el Constructor de Lambda y el Constructor de ApiGatewayV2 para crear una API de REST y una función de Lambda.

    package com.myorg; import software.amazon.awscdk.*; import software.amazon.awscdk.services.apigatewayv2.alpha.*; import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegration; import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegrationProps; import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.FunctionProps; import software.amazon.awscdk.services.lambda.Runtime; import software.amazon.awscdk.services.lambda.Tracing; import software.amazon.awscdk.services.logs.RetentionDays; import software.amazon.awscdk.services.s3.assets.AssetOptions; import software.constructs.Construct; import java.util.Arrays; import java.util.List; import static java.util.Collections.singletonList; import static software.amazon.awscdk.BundlingOutput.ARCHIVED; public class HelloWorldStack extends Stack { public HelloWorldStack(final Construct scope, final String id) { this(scope, id, null); } public HelloWorldStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); List<String> functionPackagingInstructions = Arrays.asList( "/bin/sh", "-c", "cd Function " + "&& mvn clean install " + "&& cp /asset-input/Function/target/function.jar /asset-output/" ); BundlingOptions.Builder builderOptions = BundlingOptions.builder() .command(functionPackagingInstructions) .image(Runtime.JAVA_11.getBundlingImage()) .volumes(singletonList( // Mount local .m2 repo to avoid download all the dependencies again inside the container DockerVolume.builder() .hostPath(System.getProperty("user.home") + "/.m2/") .containerPath("/root/.m2/") .build() )) .user("root") .outputType(ARCHIVED); Function function = new Function(this, "Function", FunctionProps.builder() .runtime(Runtime.JAVA_11) .code(Code.fromAsset("app", AssetOptions.builder() .bundling(builderOptions .command(functionPackagingInstructions) .build()) .build())) .handler("helloworld.App::handleRequest") .memorySize(1024) .tracing(Tracing.ACTIVE) .timeout(Duration.seconds(10)) .logRetention(RetentionDays.ONE_WEEK) .build()); HttpApi httpApi = new HttpApi(this, "sample-api", HttpApiProps.builder() .apiName("sample-api") .build()); httpApi.addRoutes(AddRoutesOptions.builder() .path("/") .methods(singletonList(HttpMethod.GET)) .integration(new HttpLambdaIntegration("function", function, HttpLambdaIntegrationProps.builder() .payloadFormatVersion(PayloadFormatVersion.VERSION_2_0) .build())) .build()); new CfnOutput(this, "HttpApi", CfnOutputProps.builder() .description("Url for Http Api") .value(httpApi.getApiEndpoint()) .build()); } }
  9. Abra pom.xml desde el directorio hello-world y sustituya el código existente por el siguiente código.

    <?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.myorg</groupId> <artifactId>hello-world</artifactId> <version>0.1</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cdk.version>2.70.0</cdk.version> <constructs.version>[10.0.0,11.0.0)</constructs.version> <junit.version>5.7.1</junit.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <configuration> <mainClass>com.myorg.HelloWorldApp</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <!-- AWS Cloud Development Kit --> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>aws-cdk-lib</artifactId> <version>${cdk.version}</version> </dependency> <dependency> <groupId>software.constructs</groupId> <artifactId>constructs</artifactId> <version>${constructs.version}</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>apigatewayv2-alpha</artifactId> <version>${cdk.version}-alpha.0</version> </dependency> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>apigatewayv2-integrations-alpha</artifactId> <version>${cdk.version}-alpha.0</version> </dependency> </dependencies> </project>
  10. Asegúrese de estar en el directorio hello-world e implemente la aplicación.

    cdk deploy
  11. Obtenga la URL de la aplicación implementada:

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`HttpApi`].OutputValue' --output text
  12. Invoque el punto de conexión de la API:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    Si se realiza de forma correcta, verá el siguiente resultado:

    {"message":"hello world"}
  13. Para obtener el seguimiento de la función, ejecute sam traces.

    sam traces

    El resultado del seguimiento tendrá este aspecto:

    New XRay Service Graph Start time: 2023-02-03 14:59:50+00:00 End time: 2023-02-03 14:59:50+00:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.924 Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.016 Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s) - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200] - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j - 0.739s - Initialization - 0.016s - Invocation - 0.013s - ## lambda_handler - 0.000s - ## app.hello - 0.000s - Overhead
  14. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

    cdk destroy

Uso de ADOT para instrumentar las funciones de Java

ADOT proporciona capas de Lambda completamente administradas que empaquetan todo lo necesario para recopilar datos de telemetría mediante el OTel SDK. Utilizando esta capa, se pueden instrumentar las funciones de Lambda sin tener que modificar el código de ninguna función. También se puede configurar la capa para que realice una inicialización personalizada de OTel. Para obtener más información, consulte Configuración personalizada del recopilador de ADOT en Lambda en la documentación de ADOT.

Para los tiempos de ejecución de Java, puede elegir entre dos capas:

  • Capa de Lambda administrada de AWS para ADOT Java (agente de instrumentación automática): esta capa transforma automáticamente el código de la función durante el inicio para recopilar datos de seguimiento. Para obtener instrucciones detalladas sobre cómo utilizar esta capa junto con el agente de ADOT Java, consulte Soporte de Lambda de AWS Distro for OpenTelemetry para Java (agente de instrumentación automática) en la documentación de ADOT.

  • Capa de Lambda administrada de AWS para ADOT Java: esta capa también proporciona instrumentación integrada para las funciones de Lambda, pero requiere algunos cambios de código manuales para inicializar el OTel SDK. Para obtener instrucciones detalladas sobre cómo utilizar esta capa, consulte Soporte de Lambda de AWS Distro for OpenTelemetry para Java en la documentación de ADOT.

Uso del X-Ray SDK para instrumentar las funciones de Java

Para registrar datos sobre las llamadas que realiza la función a otros recursos y servicios de la aplicación, se puede agregar el X-Ray SDK para Java a la configuración de compilación. En el siguiente ejemplo, se muestra una configuración de compilación de Gradle que incluye las bibliotecas que activan la instrumentación automática de los clientes de AWS SDK for Java 2.x.

ejemplo build.gradle: dependencias de seguimiento.
dependencies { implementation platform('software.amazon.awssdk:bom:2.16.1') implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0') ... implementation 'com.amazonaws:aws-xray-recorder-sdk-core' implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk' implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor' ... }

Una vez agregadas las dependencias correctas y realizados los cambios de código necesarios, active el seguimiento en la configuración de la función mediante la consola de Lambda o la API.

Activación del seguimiento con la consola de Lambda

Para activar el seguimiento activo de la función Lambda mediante la consola, siga estos pasos:

Cómo activar el seguimiento activo
  1. Abra la página de Funciones en la consola de Lambda.

  2. Elija una función.

  3. Elija Configuration (Configuración), y luego Monitoring and operations tools (Herramientas de supervisión y operaciones).

  4. Elija Editar.

  5. En X-Ray, active Rastreo activo.

  6. Seleccione Guardar.

Activación del seguimiento con la API de Lambda

Configure el rastreo en la función Lambda con AWS CLI o SDK de AWS, utilice las siguientes operaciones de API:

El siguiente comando de ejemplo de la AWS CLI habilita el seguimiento activo en una función llamada my-function.

aws lambda update-function-configuration \ --function-name my-function \ --tracing-config Mode=Active

El modo de seguimiento forma parte de la configuración específica de la versión, cuando se publica una versión de la función. No se puede cambiar el modo de seguimiento de una versión publicada.

Activación del seguimiento con AWS CloudFormation

Para activar el seguimiento en un recurso de AWS::Lambda::Function de una plantilla de AWS CloudFormation, utilice la propiedad TracingConfig.

ejemplo función-inline.yml: configuración de rastreo
Resources: function: Type: AWS::Lambda::Function Properties: TracingConfig: Mode: Active ...

Para un recurso AWS::Serverless::Function de AWS Serverless Application Model (AWS SAM) , utilice la propiedad Tracing.

ejemplo template.yml: configuración de rastreo
Resources: function: Type: AWS::Serverless::Function Properties: Tracing: Active ...

Interpretación de un seguimiento de X-Ray

La función necesita permiso para cargar datos de rastreo en X-Ray. Cuando activa el rastreo activo en la consola de Lambda, Lambda agrega los permisos necesarios al rol de ejecución de la función. De lo contrario, agregue la política AWSXRayDaemonWriteAccess al rol de ejecución.

Después de configurar el seguimiento activo, se pueden observar solicitudes específicas a través de la aplicación. El gráfico de servicios de X-Ray muestra información sobre la aplicación y todos sus componentes. La siguiente imagen muestra una aplicación con dos funciones. La función principal procesa eventos y, a veces, devuelve errores. La segunda función de la cadena procesa los errores que aparecen en el primer grupo de registros y utiliza el SDK de AWS para llamar a X-Ray, Amazon Simple Storage Service (Amazon S3) y Registros de Amazon CloudWatch.

Diagrama que muestra dos aplicaciones independientes y sus respectivos mapas de servicios en X-Ray

X-Ray no sigue todas las solicitudes realizadas a la aplicación. X-Ray aplica un algoritmo de muestreo para garantizar que el seguimiento sea eficiente, a la vez que proporciona una muestra representativa de todas las solicitudes. La tasa de muestreo es 1 solicitud por segundo y un 5 por ciento de las solicitudes adicionales.

nota

La frecuencia de muestreo de X-Ray no se puede configurar para las funciones.

En X-Ray, un seguimiento registra información sobre una solicitud procesada por uno o varios servicios. Lambda registra 2 segmentos por seguimiento, lo que crea dos nodos en el gráfico de servicios. La siguiente imagen resalta estos dos nodos:

Un mapa de servicio X-Ray con una sola función.

El primer nodo, situado a la izquierda, representa el servicio de Lambda, que recibe la solicitud de invocación. El segundo nodo representa la función Lambda específica. En el siguiente ejemplo, se muestra un seguimiento con estos dos segmentos. Ambos se denominan my-function, pero uno tiene un origen de AWS::Lambda y el otro tiene origen de AWS::Lambda::Function. Si el segmento AWS::Lambda muestra un error, el servicio Lambda tuvo un problema. Si el segmento AWS::Lambda::Function muestra un error, la función tuvo un problema.

Seguimiento de X-Ray que muestra la latencia de cada subsegmento de una invocación de Lambda específica.

En este ejemplo, el segmento AWS::Lambda::Function aparece ampliado para mostrar los tres subsegmentos:

  • Inicialización: representa el tiempo dedicado a cargar la función y ejecutar el código de inicialización. Este subsegmento aparece únicamente para el primer evento que procesa cada instancia de la función.

  • Invocación: representa el tiempo dedicado a ejecutar el código del controlador.

  • Sobrecarga: representa el tiempo que el tiempo de ejecución de Lambda dedica a prepararse para gestionar el siguiente evento.

nota

Las funciones de Lambda SnapStart también incluyen un subsegmento Restore. El subsegmento Restore muestra el tiempo que tarda Lambda en restaurar una instantánea, cargar el tiempo de ejecución (JVM) y ejecutar cualquier enlace de tiempo de ejecución de afterRestore. El proceso de restauración de instantáneas puede incluir el tiempo dedicado a actividades fuera de la micro VM. Esta vez se informa en el subsegmento Restore. No se le cobrará por el tiempo que pase fuera de la micro VM para restaurar una instantánea.

También puede instrumentar clientes HTTP, registrar consultas SQL y crear subsegmentos personalizados con anotaciones y metadatos. Para obtener más información, consulte AWS X-Ray SDK para Java en la Guía para desarrolladores de AWS X-Ray.

Precios

Puede utilizar el seguimiento de X-Ray de manera gratuita cada mes hasta un límite determinado como parte del nivel Gratuito de AWS. A partir de ese umbral, X-Ray realiza cargos por almacenamiento y recuperación del seguimiento. Para más información, consulte Precios de AWS X-Ray.

Almacenamiento de dependencias de tiempo de ejecución en una capa (X-Ray SDK)

Si utiliza el X-Ray SDK para instrumentar el código de las funciones de los clientes del SDK de AWS, el paquete de implementación puede llegar a ser bastante grande. Para evitar que se carguen dependencias en tiempo de ejecución cada vez que se actualice el código de las funciones, empaquete el X-Ray SDK en una capa de Lambda.

En el siguiente ejemplo, se muestra un recurso de AWS::Serverless::LayerVersion que almacena el AWS SDK for Java y el X-Ray SDK.

ejemplo template.yml: capa de dependencias.
Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/blank-java.zip Tracing: Active Layers: - !Ref libs ... libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-java-lib Description: Dependencies for the blank-java sample app. ContentUri: build/blank-java-lib.zip CompatibleRuntimes: - java21

Con esta configuración, solo se actualiza la capa de la biblioteca si se modifican las dependencias del tiempo de ejecución. Dado que el paquete de implementación de la función contiene únicamente el código, esto puede ayudar a reducir los tiempos de carga.

Para crear una capa de dependencias, es necesario realizar cambios en la configuración de compilación para generar el archivo de capas antes de la implementación. Para ver un ejemplo práctico, consulte la aplicación de ejemplo java-basic en GitHub.

Seguimiento de X-Ray en aplicaciones de ejemplo (X-Ray SDK)

En el repositorio de GitHub correspondiente a esta guía hay aplicaciones de ejemplo que muestran cómo utilizar el seguimiento de X-Ray. Cada una de las aplicaciones de ejemplo contiene scripts para facilitar la implementación y la limpieza, una plantilla de AWS SAM y recursos de soporte.

Aplicaciones de Lambda de ejemplo en Java
  • java17-examples: una función de Java que demuestra cómo utilizar un registro de Java para representar un objeto de datos de eventos de entrada.

  • java-basic: una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.

  • java-events: una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca aws-lambda-java-events (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.

  • s3-java: una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.

  • Uso de API Gateway para invocar una función de Lambda: una función Java que escanea una tabla de Amazon DynamoDB que contiene información sobre los empleados. Luego, utiliza Amazon Simple Notification Service para enviar un mensaje de texto a los empleados que celebran sus aniversarios laborales. En este ejemplo, se utiliza API Gateway para invocar la función.

Todas las aplicaciones de ejemplo tienen activado el seguimiento activo de las funciones de Lambda. Por ejemplo, en la aplicación s3-java, se muestra la instrumentación automática de los clientes de AWS SDK for Java 2.x, la administración de segmentos para pruebas, subsegmentos personalizados y el uso de capas de Lambda para almacenar dependencias en tiempo de ejecución.