Log and monitor Node.js Lambda functions
AWS Lambda automatically monitors Lambda functions on your behalf and sends logs to Amazon CloudWatch. Your Lambda function comes with a CloudWatch Logs log group and a log stream for each instance of your function. The Lambda runtime environment sends details about each invocation to the log stream, and relays logs and other output from your function's code. For more information, see Using Amazon CloudWatch logs with AWS Lambda.
This page describes how to produce log output from your Lambda function's code, and access logs using the AWS Command Line Interface, the Lambda console, or the CloudWatch console.
Sections
Creating a function that returns logs
To output logs from your function code, you can use methods on the console objectstdout
or stderr
. The following example logs the values of environment variables
and the event object.
Example index.js file – Logging
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 }
Example log format
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
The Node.js runtime logs the START
, END
, and REPORT
lines for each
invocation. It adds a timestamp, request ID, and log level to each entry logged by the function. The report line
provides the following details.
REPORT line data fields
-
RequestId – The unique request ID for the invocation.
-
Duration – The amount of time that your function's handler method spent processing the event.
-
Billed Duration – The amount of time billed for the invocation.
-
Memory Size – The amount of memory allocated to the function.
-
Max Memory Used – The amount of memory used by the function.
-
Init Duration – For the first request served, the amount of time it took the runtime to load the function and run code outside of the handler method.
-
XRAY TraceId – For traced requests, the AWS X-Ray trace ID.
-
SegmentId – For traced requests, the X-Ray segment ID.
-
Sampled – For traced requests, the sampling result.
You can view logs in the Lambda console, in the CloudWatch Logs console, or from the command line.
Using Lambda advanced logging controls with Node.js
To give you more control over how your functions’ logs are captured, processed, and consumed, you can configure the following logging options for supported Node.js runtimes:
-
Log format - select between plain text and structured JSON format for your function’s logs
-
Log level - for logs in JSON format, choose the detail level of the logs Lambda sends to Amazon CloudWatch, such as ERROR, DEBUG, or INFO
-
Log group - choose the CloudWatch log group your function sends logs to
For more information about these logging options, and instructions on how to configure your function to use them, see Configuring advanced logging controls for Lambda functions.
To use the log format and log level options with your Node.js Lambda functions, see the guidance in the following sections.
Using structured JSON logs with Node.js
If you select JSON for your function’s log format, Lambda will send logs output using the console methods of console.trace
,
console.debug
, console.log
, console.info
, console.error
, and console.warn
to
CloudWatch as structured JSON. Each JSON log object contains at least four key value pairs with the following keys:
-
"timestamp"
- the time the log message was generated -
"level"
- the log level assigned to the message -
"message"
- the contents of the log message -
"requestId"
- the unique request ID for the function invocation
Depending on the logging method that your function uses, this JSON object may also contain additional key pairs. For example,
if your function uses console
methods to log error objects using multiple arguments, the JSON object will contain extra
key value pairs with the keys errorMessage
, errorType
, and stackTrace
.
If your code already uses another logging library, such as Powertools for AWS Lambda, to produce JSON structured logs, you don’t need to make any changes. Lambda doesn’t double-encode any logs that are already JSON encoded, so your function’s application logs will continue to be captured as before.
For more information about using the Powertools for AWS Lambda logging package to create JSON structured logs in the Node.js runtime, see Log and monitor TypeScript Lambda functions.
Example JSON formatted log outputs
The following examples shows how various log outputs generated using the console
methods with single and multiple
arguments are captured in CloudWatch Logs when you set your function's log format to JSON.
The first example uses the console.error
method to output a simple string.
Example Node.js logging code
export const handler = async (event) => { console.error("This is a warning message"); ... }
Example JSON log record
{ "timestamp":"2023-11-01T00:21:51.358Z", "level":"ERROR", "message":"This is a warning message", "requestId":"93f25699-2cbf-4976-8f94-336a0aa98c6f" }
You can also output more complex structured log messages using either single or multiple arguments with the console
methods.
In the next example, you use console.log
to output two key value pairs using a single argument. Note that the "message"
field in the JSON object Lambda sends to CloudWatch Logs is not stringified.
Example Node.js logging code
export const handler = async (event) => { console.log({data: 12.3, flag: false}); ... }
Example JSON log record
{ "timestamp": "2023-12-08T23:21:04.664Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": { "data": 12.3, "flag": false } }
In the next example, you again use the console.log
method to create a log output. This time, the method takes two arguments,
a map containing two key value pairs and an identifying string. Note that in this case, because you have supplied two arguments, Lambda stringifies the "message"
field.
Example Node.js logging code
export const handler = async (event) => { console.log('Some object - ', {data: 12.3, flag: false}); ... }
Example JSON log record
{ "timestamp": "2023-12-08T23:21:04.664Z", "level": "INFO", "requestId": "405a4537-9226-4216-ac59-64381ec8654a", "message": "Some object - { data: 12.3, flag: false }" }
Lambda assigns outputs generated using console.log
the log level INFO.
The final example shows how error objects can be output to CloudWatch Logs using the console
methods. Note that when you log error
objects using multiple arguments, Lambda adds the fields errorMessage
, errorType
, and stackTrace
to
the log output.
Example Node.js logging code
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); };
Example JSON log record
{ "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)" ] }
When logging multiple error types, the extra fields errorMessage
, errorType
, and stackTrace
are extracted from the first error type supplied to the console
method.
Using embedded metric format (EMF) client libraries with structured JSON logs
AWS provides open-sourced client libraries for Node.js which you can use to create embedded metric format (EMF) logs. If you have existing functions that use these libraries and you change your function's log format to JSON, CloudWatch may no longer recognize the metrics emitted by your code.
If your code currently emits EMF logs directly using console.log
or by using Powertools for AWS Lambda (TypeScript), CloudWatch will also be
unable to parse these if you change your function's log format to JSON.
Important
To ensure that your functions' EMF logs continue to be properly parsed by CloudWatch, update your EMFconsole.log
, change your code to output those metrics
directly to stdout
as shown in the following code example.
Example code emitting embedded metrics to 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")
Using log-level filtering with Node.js
For AWS Lambda to filter your application logs according to their log level, your function must use JSON formatted logs. You can achieve this in two ways:
-
Create log outputs using the standard console methods and configure your function to use JSON log formatting. AWS Lambda then filters your log outputs using the “level” key value pair in the JSON object described in Using structured JSON logs with Node.js. To learn how to configure your function’s log format, see Configuring advanced logging controls for Lambda functions.
-
Use another logging library or method to create JSON structured logs in your code that include a “level” key value pair defining the level of the log output. For example, you can use Powertools for AWS Lambda to generate JSON structured log outputs from your code. See Log and monitor TypeScript Lambda functions to learn more about using Powertools with the Node.js runtime.
For Lambda to filter your function's logs, you must also include a
"timestamp"
key value pair in your JSON log output. The time must be specified in valid RFC 3339timestamp format. If you don't supply a valid timestamp, Lambda will assign the log the level INFO and add a timestamp for you.
When you configure your function to use log-level filtering, you select the level of logs you want AWS Lambda to send to CloudWatch Logs from the following options:
Log level | Standard usage |
---|---|
TRACE (most detail) | The most fine-grained information used to trace the path of your code's execution |
DEBUG | Detailed information for system debugging |
INFO | Messages that record the normal operation of your function |
WARN | Messages about potential errors that may lead to unexpected behavior if unaddressed |
ERROR | Messages about problems that prevent the code from performing as expected |
FATAL (least detail) | Messages about serious errors that cause the application to stop functioning |
Lambda sends logs of the selected level and lower to CloudWatch. For example, if you configure a log level of WARN, Lambda will send logs corresponding to the WARN, ERROR, and FATAL levels.
Viewing logs in the Lambda console
You can use the Lambda console to view log output after you invoke a Lambda function.
If your code can be tested from the embedded Code editor, you will find logs in the execution results. When you use the console test feature to invoke a function, you'll find Log output in the Details section.
Viewing logs in the CloudWatch console
You can use the Amazon CloudWatch console to view logs for all Lambda function invocations.
To view logs on the CloudWatch console
-
Open the Log groups page
on the CloudWatch console. -
Choose the log group for your function (/aws/lambda/
your-function-name
). -
Choose a log stream.
Each log stream corresponds to an instance of your function. A log stream appears when you update your Lambda function, and when additional instances are created to handle multiple concurrent invocations. To find logs for a specific invocation, we recommend instrumenting your function with AWS X-Ray. X-Ray records details about the request and the log stream in the trace.
Viewing logs using the AWS Command Line Interface (AWS CLI)
The AWS CLI is an open-source tool that enables you to interact with AWS services using commands in your command line shell. To complete the steps in this section, you must have the following:
You can use the AWS CLI to retrieve logs for an invocation using the --log-type
command option. The response contains a LogResult
field that contains up to 4 KB of base64-encoded logs from the invocation.
Example retrieve a log ID
The following example shows how to retrieve a log ID from the LogResult
field for a function named my-function
.
aws lambda invoke --function-name my-function out --log-type Tail
You should see the following output:
{ "StatusCode": 200, "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...", "ExecutedVersion": "$LATEST" }
Example decode the logs
In the same command prompt, use the base64
utility to decode the logs. The following example shows how to retrieve base64-encoded logs for 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
The cli-binary-format option is required if you're using AWS CLI version 2. To make this the default setting, run aws configure set cli-binary-format raw-in-base64-out
. For more information, see AWS CLI supported global command line options in the AWS Command Line Interface User Guide for Version 2.
You should see the following output:
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
The base64
utility is available on Linux, macOS, and Ubuntu on Windowsbase64 -D
.
Example get-logs.sh script
In the same command prompt, use the following script to download the last five log events. The script uses sed
to remove quotes from the output file, and sleeps for 15 seconds to allow time for the logs to become available. The output includes the response from Lambda and the output from the get-log-events
command.
Copy the contents of the following code sample and save in your Lambda project directory as get-logs.sh
.
The cli-binary-format option is required if you're using AWS CLI version 2. To make this the default setting, run aws configure set cli-binary-format raw-in-base64-out
. For more information, see AWS CLI supported global command line options in the AWS Command Line Interface User Guide for Version 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-namestream1
--limit 5
Example macOS and Linux (only)
In the same command prompt, macOS and Linux users may need to run the following command to ensure the script is executable.
chmod -R 755 get-logs.sh
Example retrieve the last five log events
In the same command prompt, run the following script to get the last five log events.
./get-logs.sh
You should see the following output:
{ "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" }
Deleting logs
Log groups aren't deleted automatically when you delete a function. To avoid storing logs indefinitely, delete the log group, or configure a retention period after which logs are deleted automatically.