Registro y supervisión de las funciones de Lambda de Node.js - AWS Lambda

Registro y supervisión de las funciones de Lambda de Node.js

AWS Lambda supervisa automáticamente funciones de Lambda en su nombre y envía registros a Amazon CloudWatch. Su función de Lambda viene con un grupo de registros de Registros de CloudWatch y con un flujo de registro para cada instancia de su función. El entorno de tiempo de ejecución de Lambda envía detalles sobre cada invocación al flujo de registro y retransmite los registros y otras salidas desde el código de la función. Para obtener más información, consulte Uso de los Registros de CloudWatch con Lambda.

Esta página describe cómo producir resultados de registro a partir del código de la función de Lambda o registros de acceso mediante AWS Command Line Interface, la consola de Lambda o la consola de CloudWatch.

Crear una función que devuelve registros

Para generar registros desde el código de las funciones, puede utilizar los métodos del objeto de la consola o cualquier biblioteca de registro que escriba en stdout o en stderr. En el siguiente ejemplo, se registran los valores de las variables de entorno y el objeto de evento.

nota

Le recomendamos que utilice técnicas como la validación de entrada y la codificación de salida al registrar las entradas. Si registra los datos de entrada directamente, un atacante podría usar el código para dificultar la detección de la manipulación, falsificar las entradas de registro u omitir los monitores de registro. Para obtener más información, consulte Neutralización incorrecta de los resultados de los registros en Eenumeración de puntos débiles comunes.

ejemplo Archivo index.js: registro
exports.handler = async function(event, context) { console.log("ENVIRONMENT VARIABLES\n" + JSON.stringify(process.env, null, 2)) console.info("EVENT\n" + JSON.stringify(event, null, 2)) console.warn("Event not processed.") return context.logStreamName }
ejemplo formato de registro
START RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac Version: $LATEST 2019-06-07T19:11:20.562Z c793869b-ee49-115b-a5b6-4fd21e8dedac INFO ENVIRONMENT VARIABLES { "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST", "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/my-function", "AWS_LAMBDA_LOG_STREAM_NAME": "2019/06/07/[$LATEST]e6f4a0c4241adcd70c262d34c0bbc85c", "AWS_EXECUTION_ENV": "AWS_Lambda_nodejs12.x", "AWS_LAMBDA_FUNCTION_NAME": "my-function", "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin", "NODE_PATH": "/opt/nodejs/node10/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules", ... } 2019-06-07T19:11:20.563Z c793869b-ee49-115b-a5b6-4fd21e8dedac INFO EVENT { "key": "value" } 2019-06-07T19:11:20.564Z c793869b-ee49-115b-a5b6-4fd21e8dedac WARN Event not processed. END RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac REPORT RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac Duration: 128.83 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 74 MB Init Duration: 166.62 ms XRAY TraceId: 1-5d9d007f-0a8c7fd02xmpl480aed55ef0 SegmentId: 3d752xmpl1bbe37e Sampled: true

El tiempo de ejecución de Node.js registra las líneas START, END y REPORT de cada invocación. Se agrega una marca de tiempo, un ID de solicitud y el nivel de registro en cada entrada registrada por la función. La línea del informe proporciona los siguientes detalles.

Campos de datos de línea REPORT
  • RequestId: el ID de solicitud único para la invocación.

  • Duración: la cantidad de tiempo que el método de controlador de función pasó procesando el evento.

  • Duración facturada: la cantidad de tiempo facturado por la invocación.

  • Tamaño de memoria: la cantidad de memoria asignada a la función.

  • Máximo de memoria usada: la cantidad de memoria utilizada por la función. Cuando las invocaciones comparten un entorno de ejecución, Lambda informa de la memoria máxima utilizada en todas las invocaciones. Este comportamiento puede dar como resultado un valor notificado superior al esperado.

  • Duración de inicio: para la primera solicitud servida, la cantidad de tiempo que tardó el tiempo de ejecución en cargar la función y ejecutar código fuera del método del controlador.

  • TraceId de XRAY: para las solicitudes rastreadas, el ID de seguimientode AWS X-Ray.

  • SegmentId: para solicitudes rastreadas, el ID del segmento de X-Ray.

  • Muestras: para solicitudes rastreadas, el resultado del muestreo.

Puede ver los registros en la consola de Lambda o en la de Registros de CloudWatch, o bien en la línea de comandos.

Uso de controles de registro avanzados de Lambda con Node.js

Para tener más control sobre cómo se capturan, procesan y consumen los registros de sus funciones, puede configurar las siguientes opciones de registro para los tiempos de ejecución de Node.js compatibles:

  • Formato de registro: seleccione entre texto sin formato y el formato JSON estructurado para los registros de su función

  • Nivel de registro: para los registros en formato JSON, elija el nivel de detalle de los registros que Lambda envía a Amazon CloudWatch, como ERROR, DEBUG o INFO

  • Grupo de registro: elija el grupo de registro de CloudWatch al que su función envía los registros

Para obtener más información sobre estas opciones de registro e instrucciones sobre cómo configurar la función para utilizarlas, consulte Configuración de controles de registro avanzados para las funciones de Lambda.

Para usar las opciones de formato y nivel de registro con las funciones de Lambda de Node.js, consulte las instrucciones de las siguientes secciones.

Uso de registros JSON estructurados con Node.js

Si selecciona JSON para el formato de registro de la función, Lambda enviará los registros que obtenga mediante los métodos consola console.trace, console.debug, console.log, console.info, console.error y console.warn a CloudWatch como JSON estructurado. Cada objeto de registro JSON contiene, por lo menos, cuatro pares clave-valor con las siguientes claves:

  • "timestamp": la hora en que se generó el mensaje de registro

  • "level": el nivel de registro asignado al mensaje

  • "message": el contenido del mensaje de registro

  • "requestId": el ID de solicitud único para la invocación de la función

Según el método de registro que use la función, este objeto JSON también puede contener pares de claves adicionales. Por ejemplo, si la función usa métodos console para registrar objetos de error con varios argumentos, el objeto JSON contendrá pares clave-valor adicionales junto con las claves errorMessage, errorType, y stackTrace.

Si su código ya usa otra biblioteca de registro, como Powertools para AWS Lambda, para producir registros JSON estructurados, no necesita realizar ningún cambio. Lambda no codifica dos veces ningún registro que ya esté codificado en JSON, por lo que los registros de la aplicación de su función seguirán capturándose como antes.

Para obtener más información sobre el uso del paquete de registro de Powertools para AWS Lambda a fin de crear registros JSON estructurados en el tiempo de ejecución de Node.js, consulte Registro y supervisión de las funciones de Lambda de TypeScript.

Ejemplo de salidas de registro con formato JSON

En los siguientes ejemplos, se muestra cómo se capturan en Registros de CloudWatch varias salidas de registro generadas con los métodos console con argumentos únicos y múltiples cuando se establece el formato de registro de la función en JSON.

En el primer ejemplo, se usa el método console.error para generar una cadena sencilla.

ejemplo Código de registro de Node.js
export const handler = async (event) => { console.error("This is a warning message"); ... }
ejemplo Entrada de registro JSON
{ "timestamp":"2023-11-01T00:21:51.358Z", "level":"ERROR", "message":"This is a warning message", "requestId":"93f25699-2cbf-4976-8f94-336a0aa98c6f" }

También se pueden generar mensajes de registro estructurados de manera más compleja mediante argumentos únicos o múltiples con los métodos console. En el siguiente ejemplo, se usa console.log para generar dos pares clave-valor con un único argumento. Tenga en cuenta que el campo "message" del objeto JSON que Lambda envía a Registros de CloudWatch no se representa en forma de cadena.

ejemplo Código de registro de Node.js
export const handler = async (event) => { console.log({data: 12.3, flag: false}); ... }
ejemplo Entrada de registro JSON
{ "timestamp": "2023-12-08T23:21:04.664Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": { "data": 12.3, "flag": false } }

En el siguiente ejemplo, se volverá a usar el método console.log para crear una salida de registro. Esta vez, el método utiliza dos argumentos: un mapa que contiene dos pares clave-valor y una cadena de identificación. Tenga en cuenta que, en este caso, dado que se proporcionaron dos argumentos, Lambda representa el campo "message" en forma de cadena.

ejemplo Código de registro de Node.js
export const handler = async (event) => { console.log('Some object - ', {data: 12.3, flag: false}); ... }
ejemplo Entrada de registro JSON
{ "timestamp": "2023-12-08T23:21:04.664Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": "Some object - { data: 12.3, flag: false }" }

Lambda asigna a las salidas generadas mediante console.log el nivel de registro INFO.

En el último ejemplo, se muestra cómo los objetos de error se pueden enviar a Registros de CloudWatch mediante los métodos console. Tenga en cuenta que, cuando registra objetos de error con varios argumentos, Lambda agrega los campos errorMessage, errorType y stackTrace a la salida del registro.

ejemplo Código de registro de Node.js
export const handler = async (event) => { let e1 = new ReferenceError("some reference error"); let e2 = new SyntaxError("some syntax error"); console.log(e1); console.log("errors logged - ", e1, e2); };
ejemplo Entrada de registro JSON
{ "timestamp": "2023-12-08T23:21:04.632Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": { "errorType": "ReferenceError", "errorMessage": "some reference error", "stackTrace": [ "ReferenceError: some reference error", " at Runtime.handler (file:///var/task/index.mjs:3:12)", " at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)" ] } } { "timestamp": "2023-12-08T23:21:04.646Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": "errors logged - ReferenceError: some reference error\n at Runtime.handler (file:///var/task/index.mjs:3:12)\n at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29) SyntaxError: some syntax error\n at Runtime.handler (file:///var/task/index.mjs:4:12)\n at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)", "errorType": "ReferenceError", "errorMessage": "some reference error", "stackTrace": [ "ReferenceError: some reference error", " at Runtime.handler (file:///var/task/index.mjs:3:12)", " at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)" ] }

Al registrar varios tipos de error, los campos adicionales errorMessage, errorType y stackTrace se extraen del primer tipo de error suministrado al método console.

Uso de bibliotecas cliente de formato de métricas integradas (EMF) con registros JSON estructurados

AWS proporciona bibliotecas cliente de código abierto para Node.js que puede utilizar para crear registros de formato de métricas integradas (EMF). Si tiene ya tiene funciones que utilizan estas bibliotecas y cambia el formato de registro de la función a JSON, es posible que CloudWatch deje de reconocer las métricas emitidas por el código.

Si, en este momento, su código emite registros EMF directamente con console.log o Powertools para AWS Lambda (TypeScript), CloudWatch tampoco podrá analizarlos si cambia el formato de registro de la función a JSON.

importante

Para asegurarse de que CloudWatch siga analizando correctamente los registros de EMF de sus funciones, actualice sus bibliotecas de EMF y Powertools para AWS Lambda a las versiones más recientes. Si cambia al formato de registro JSON, también le recomendamos que realice pruebas para garantizar la compatibilidad con las métricas integradas de su función. Si su código emite registros de EMF directamente con console.log, cámbielo para que genere esas métricas de forma directa a stdout, como se muestra en el siguiente ejemplo de código.

ejemplo Código que emite métricas integradas a stdout
process.stdout.write(JSON.stringify( { "_aws": { "Timestamp": Date.now(), "CloudWatchMetrics": [{ "Namespace": "lambda-function-metrics", "Dimensions": [["functionVersion"]], "Metrics": [{ "Name": "time", "Unit": "Milliseconds", "StorageResolution": 60 }] }] }, "functionVersion": "$LATEST", "time": 100, "requestId": context.awsRequestId } ) + "\n")

Uso del filtrado a nivel de registro con Node.js

Para que AWS Lambda filtre los registros de las aplicaciones según su nivel de registro, la función debe usar registros con formato JSON. Puede lograr esto de dos maneras:

  • Cree salidas de registro con los métodos consola estándar y configure su función para que utilice el formato de registro JSON. A continuación, AWS Lambda filtra las salidas de registro con el par clave-valor “nivel” del objeto JSON descrito en Uso de registros JSON estructurados con Node.js. Para obtener información sobre cómo configurar el formato de registro de la función, consulte Configuración de controles de registro avanzados para las funciones de Lambda.

  • Utilice otra biblioteca o método de registro para crear registros estructurados en JSON en su código que incluyan un par clave-valor “nivel” que defina el nivel de la salida del registro. Por ejemplo, puede utilizar Powertools para AWS Lambda con el objetivo de generar salidas de registros JSON estructurados a partir de su código. Consulte Registro y supervisión de las funciones de Lambda de TypeScript para obtener más información sobre el uso de Powertools con el tiempo de ejecución de Node.js.

    Para que Lambda filtre los registros de la función, también debe incluir un par clave-valor "timestamp" en la salida del registro JSON. La hora debe especificarse con un formato de marca de tiempo RFC 3339 válido. Si no proporciona una marca de tiempo válida, Lambda asignará al registro el nivel INFO y agregará una marca de tiempo por usted.

Cuando configura la función para que utilice el filtrado a nivel de registro, selecciona el nivel de registros que desea que AWS Lambda envíe a Registros de Amazon CloudWatch de las siguientes opciones:

Nivel de registro Uso estándar
TRACE (más detallado) La información más detallada que se utiliza para rastrear la ruta de ejecución del código
DEBUG Información detallada para la depuración del sistema
INFO Mensajes que registran el funcionamiento normal de su función
WARN Mensajes sobre posibles errores que pueden provocar un comportamiento inesperado si no se abordan
ERROR Mensajes sobre problemas que impiden que el código funcione según lo esperado
FATAL (menos detallado) Mensajes sobre errores graves que hacen que la aplicación deje de funcionar

Lambda envía los registros del nivel seleccionado y en un nivel inferior a CloudWatch. Por ejemplo, si configura un nivel de registro de WARN, Lambda enviará los registros correspondientes a los niveles WARN, ERROR y FATAL.

Visualización de los registros en la consola de Lambda

Puede utilizar la consola de Lambda para ver la salida del registro después de invocar una función de Lambda.

Si su código se puede probar desde el editor de código integrado, encontrará los registros en los resultados de ejecución. Cuando utilice la característica de prueba de la consola para invocar una función, encontrará la Salida de registro en la sección de Detalles.

Visualización de los registros de en la consola de CloudWatch

Puede utilizar la consola Amazon CloudWatch para ver los registros de todas las invocaciones de funciones de Lambda.

Visualización de los registros en la consola CloudWatch
  1. En la consola de CloudWatch, abra la página de grupos de registro.

  2. Seleccione el grupo de registros para su función (/aws/lambda/your-function-name).

  3. Elija una secuencia de registro.

Cada flujo de registro se corresponde con una instancia de su función. Aparece un flujo de registro cuando actualiza la función de Lambda y cuando se crean instancias adicionales para manejar varias invocaciones simultáneas. Para encontrar registros para una invocación específica, le recomendamos que interfiera su función con AWS X-Ray. X-Ray registra los detalles sobre la solicitud y el flujo de registro en el seguimiento.

Visualización de los registros mediante la AWS Command Line Interface (AWS CLI)

La AWS CLI es una herramienta de código abierto que lo habitlita para interactuar con los servicios de AWS mediante el uso de comandos en el shell de la línea de comandos. Para completar los pasos de esta sección, debe disponer de la versión 2 de la AWS CLI.

Puede utilizar la CLI de AWS CLI para recuperar registros de una invocación mediante la opción de comando --log-type. La respuesta contiene un campo LogResult que contiene hasta 4 KB de registros con codificación base64 a partir de la invocación.

ejemplo recuperar un ID de registro

En el ejemplo siguiente se muestra cómo recuperar un ID de registro del campo LogResult para una función denominada my-function.

aws lambda invoke --function-name my-function out --log-type Tail

Debería ver los siguientes datos de salida:

{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
ejemplo decodificar los registros

En el mismo símbolo del sistema, utilice la utilidad base64 para decodificar los registros. En el ejemplo siguiente se muestra cómo recuperar registros codificados en base64 para my-function.

aws lambda invoke --function-name my-function out --log-type Tail \ --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode

La opción cli-binary-format es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute aws configure set cli-binary-format raw-in-base64-out. Para obtener más información, consulte Opciones de la línea de comandos globales compatibles con AWS CLI en la Guía del usuario de la AWS Command Line Interface versión 2.

Debería ver los siguientes datos de salida:

START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB

La utilidad base64 está disponible en Linux, macOS y Ubuntu en Windows. Es posible que los usuarios de macOS necesiten usar base64 -D.

ejemplo get-logs.sh script

En el mismo símbolo del sistema, utilice el siguiente script para descargar los últimos cinco eventos de registro. El script utiliza sed para eliminar las comillas del archivo de salida y permanece inactivo durante 15 segundos para dar tiempo a que los registros estén disponibles. La salida incluye la respuesta de Lambda y la salida del comando get-log-events.

Copie el contenido de la siguiente muestra de código y guárdelo en su directorio de proyecto Lambda como get-logs.sh.

La opción cli-binary-format es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute aws configure set cli-binary-format raw-in-base64-out. Para obtener más información, consulte Opciones de la línea de comandos globales compatibles con AWS CLI en la Guía del usuario de la AWS Command Line Interface versión 2.

#!/bin/bash aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out sed -i'' -e 's/"//g' out sleep 15 aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
ejemplo macOS y Linux (solamente)

En el mismo símbolo del sistema, es posible que los usuarios de macOS y Linux necesiten ejecutar el siguiente comando para asegurarse de que el script es ejecutable.

chmod -R 755 get-logs.sh
ejemplo recuperar los últimos cinco eventos de registro

En el mismo símbolo del sistema, ejecute el siguiente script para obtener los últimos cinco eventos de registro.

./get-logs.sh

Debería ver los siguientes datos de salida:

{ "StatusCode": 200, "ExecutedVersion": "$LATEST" } { "events": [ { "timestamp": 1559763003171, "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n", "ingestionTime": 1559763003309 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r \"key\": \"value\"\r}\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n", "ingestionTime": 1559763018353 } ], "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795", "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080" }

Eliminación de registros

Los grupos de registro no se eliminan automáticamente cuando se elimina una función. Para evitar almacenar registros indefinidamente, elimine el grupo de registros o configure un periodo de retención después de lo cual los registros se eliminan automáticamente.