Using Amazon CloudWatch logs with AWS Lambda - AWS Lambda

Using Amazon CloudWatch logs with AWS Lambda

AWS Lambda automatically monitors Lambda functions on your behalf to help you troubleshoot failures in your functions. As long as your function's execution role has the necessary permissions, Lambda captures logs for all requests handled by your function and sends them to Amazon CloudWatch Logs.

You can insert logging statements into your code to help you validate that your code is working as expected. Lambda automatically integrates with CloudWatch Logs and sends all logs from your code to a CloudWatch logs group associated with a Lambda function.

By default, Lambda sends logs to a log group named /aws/lambda/<function name>. If you want your function to send logs to another group, you can configure this using the Lambda console, the AWS Command Line Interface (AWS CLI) or the Lambda API. See Configuring CloudWatch log groups to learn more.

You can view logs for Lambda functions using the Lambda console, the CloudWatch console, the AWS Command Line Interface (AWS CLI), or the CloudWatch API.

Note

It may take 5 to 10 minutes for logs to show up after a function invocation.

Prerequisites

Your execution role needs permission to upload logs to CloudWatch Logs. You can add CloudWatch Logs permissions using the AWSLambdaBasicExecutionRole AWS managed policy provided by Lambda. To add this policy to your role, run the following command:

aws iam attach-role-policy --role-name your-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

For more information, see AWS managed policies for Lambda features.

Pricing

There is no additional charge for using Lambda logs; however, standard CloudWatch Logs charges apply. For more information, see CloudWatch pricing.

Configuring advanced logging controls for your Lambda function

To give you more control over how your functions’ logs are captured, processed, and consumed, Lambda offers the following logging configuration options:

  • Log format - select between plain text and structured JSON format for your function’s logs

  • Log level - for JSON structured logs, choose the detail level of the logs Lambda sends to CloudWatch, such as ERROR, DEBUG, or INFO

  • Log group - choose the CloudWatch log group your function sends logs to

Configuring JSON and plain text log formats

Capturing your log outputs as JSON key value pairs makes it easier to search and filter when debugging your functions. With JSON formatted logs, you can also add tags and contextual information to your logs. This can help you to perform automated analysis of large volumes of log data. Unless your development workflow relies on existing tooling that consumes Lambda logs in plain text, we recommend that you select JSON for your log format.

For all Lambda managed runtimes, you can choose whether your function's system logs are sent to CloudWatch Logs in unstructured plain text or JSON format. System logs are the logs that Lambda generates and are sometimes known as platform event logs.

For supported runtimes, when you use one of the supported built-in logging methods, Lambda can also output your function's application logs (the logs your function code generates) in structured JSON format. When you configure your function's log format for these runtimes, the configuration you choose applies to both system and application logs.

For supported runtimes, if your function uses a supported logging library or method, you don't need to make any changes to your existing code for Lambda to capture logs in structured JSON.

Note

Using JSON log formatting adds additional metadata and encodes log messages as JSON objects containing a series of key value pairs. Because of this, the size of your function's log messages can increase.

Supported runtimes and logging methods

Lambda currently supports the option to output JSON structured application logs for the following runtimes.

Runtime Supported versions
Java All Java runtimes except Java 8 on Amazon Linux 1
Node.js Node.js 16 and later
Python Python 3.7 and later

For Lambda to send your function's application logs to CloudWatch in structured JSON format, your function must use the following built-in logging tools to output logs:

  • Java - the LambdaLogger logger or Log4j2.

  • Node.js - The console methods console.trace, console.debug, console.log, console.info, console.error, and console.warn

  • Python - the standard Python logging library

For more information about using advanced logging controls with supported runtimes, see AWS Lambda function logging in Java, AWS Lambda function logging in Node.js, and AWS Lambda function logging in Python.

For other managed Lambda runtimes, Lambda currently only natively supports capturing system logs in structured JSON format. However, you can still capture application logs in structured JSON format in any runtime by using logging tools such as Powertools for AWS Lambda that output JSON formatted log outputs.

Default log formats

Currently, the default log format for all Lambda runtimes is plain text.

If you’re already using logging libraries like Powertools for AWS Lambda to generate your function logs in JSON structured format, you don’t need to change your code if you select JSON log formatting. 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.

JSON format for system logs

When you configure your function's log format as JSON, each system log item (platform event) is captured as a JSON object that contains key value pairs with the following keys:

  • "time" - the time the log message was generated

  • "type" - the type of event being logged

  • "record" - the contents of the log output

The format of the "record" value varies according to the type of event being logged. For more information see Telemetry API Event object types. For more information about the log levels assigned to system log events, see System log level event mapping.

For comparison, the following two examples show the same log output in both plain text and structured JSON formats. Note that in most cases, system log events contain more information when output in JSON format than when output in plain text.

Example plain text:
2023-03-13 18:56:24.046000 fbe8c1 INIT_START Runtime Version: python:3.9.v18 Runtime Version ARN: arn:aws:lambda:eu-west-1::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0
Example structured JSON:
{ "time": "2023-03-13T18:56:24.046Z", "type": "platform.initStart", "record": { "initializationType": "on-demand", "phase": "init", "runtimeVersion": "python:3.9.v18", "runtimeVersionArn": "arn:aws:lambda:eu-west-1::runtime:edb5a058bfa782cb9cedc6d534ac8b8c193bc28e9a9879d9f5ebaaf619cd0fc0" } }
Note

The Lambda Telemetry API always emits platform events such as START and REPORT in JSON format. Configuring the format of the system logs Lambda sends to CloudWatch doesn’t affect Lambda Telemetry API behavior.

JSON format for application logs

When you configure your function's log format as JSON, application log outputs written using supported logging libraries and methods are captured as a JSON object that contains 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" (Python and Node.js) or "AWSrequestId" (Java) - the unique request ID for the function invocation

Depending on the runtime and logging method that your function uses, this JSON object may also contain additional key pairs. For example, in Node.js, 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. To learn more about JSON formatted logs in different Lambda runtimes, see AWS Lambda function logging in Python, AWS Lambda function logging in Node.js, and AWS Lambda function logging in Java.

Note

The key Lambda uses for the timestamp value is different for system logs and application logs. For system logs, Lambda uses the key "time" to maintain consistency with Telemetry API. For application logs, Lambda follows the conventions of the supported runtimes and uses "timestamp".

For comparison, the following two examples show the same log output in both plain text and structured JSON formats.

Example plain text:
2023-10-27T19:17:45.586Z 79b4f56e-95b1-4643-9700-2807f4e68189 INFO some log message
Example structured JSON:
{ "timestamp":"2023-10-27T19:17:45.586Z", "level":"INFO", "message":"some log message", "requestId":"79b4f56e-95b1-4643-9700-2807f4e68189" }

Setting your function's log format

To configure the log format for your function, you can use the Lambda console or the AWS Command Line Interface (AWS CLI). You can also configure a function’s log format using the CreateFunction and UpdateFunctionConfiguration Lambda API commands, the AWS Serverless Application Model (AWS SAM) AWS::Serverless::Function resource, and the AWS CloudFormation AWS::Lambda::Function resource.

Changing your function’s log format doesn’t affect existing logs stored in CloudWatch Logs. Only new logs will use the updated format.

If you change your function's log format to JSON and do not set log level, then Lambda automatically sets your function's application log level and system log level to INFO. This means that Lambda sends only log outputs of level INFO and lower to CloudWatch Logs. To learn more about application and system log-level filtering see Log-level filtering

Note

For Python runtimes, when your function's log format is set to plain text, the default log-level setting is WARN. This means that Lambda only sends log outputs of level WARN and lower to CloudWatch Logs. Changing your function's log format to JSON changes this default behavior. To learn more about logging in Python, see AWS Lambda function logging in Python.

For Node.js functions that emit embedded metric format (EMF) logs, changing your function's log format to JSON could result in CloudWatch being unable to recognize your metrics.

Important

If your function uses Powertools for AWS Lambda (TypeScript) or the open-sourced EMF client libraries to emit EMF logs, update your Powertools and EMF libraries to the latest versions to ensure that CloudWatch can continue to parse your logs correctly. If you switch to the JSON log format, we also recommend that you carry out testing to ensure compatibility with your function's embedded metrics. For further advice about node.js functions that emit EMF logs, see Using embedded metric format (EMF) client libraries with structured JSON logs.

To configure a function’s log format (console)
  1. Open the Functions page of the Lambda console.

  2. Choose a function

  3. On the function configuration page, choose Monitoring and operations tools.

  4. In the Logging configuration pane, choose Edit.

  5. Under Log content, for Log format select either Text or JSON.

  6. Choose Save.

To change the log format of an existing function (AWS CLI)
  • To change the log format of an existing function, use the update-function-configuration command. Set the LogFormat option in LoggingConfig to either JSON or Text.

    aws lambda update-function-configuration \ --function-name myFunction --logging-config LogFormat=JSON
To set log format when you create a function (AWS CLI)
  • To configure log format when you create a new function, use the --logging-config option in the create-function command. Set LogFormat to either JSON or Text. The following example command creates a function using the Node.js 18 runtime that outputs logs in structured JSON.

    If you don’t specify a log format when you create a function, Lambda will use the default log format for the runtime version you select. For information about default logging formats, see Default log formats.

    aws lambda create-function --function-name myFunction --runtime nodejs18.x \ --handler index.handler --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/LambdaRole --logging-config LogFormat=JSON

Log-level filtering

Lambda can filter your function's logs so that only logs of a certain detail level or lower are sent to CloudWatch Logs. You can configure log-level filtering separately for your function's system logs (the logs that Lambda generates) and application logs (the logs that your function code generates).

For Supported runtimes and logging methods, you don't need to make any changes to your function code for Lambda to filter your function's application logs.

For all other runtimes and logging methods , your function code must output log events to stdout or stderr as JSON formatted objects that contain a key value pair with the key "level". For example, Lambda interprets the following output to stdout as a DEBUG level log.

print('{"level": "debug", "msg": "my debug log", "timestamp": "2023-11-02T16:51:31.587199Z"}')

If the "level" value field is invalid or missing, Lambda will assign the log output the level INFO. For Lambda to use the timestamp field, you must specify the time in valid RFC 3339 timestamp format. If you don't supply a valid timestamp, Lambda will assign the log the level INFO and add a timestamp for you.

When naming the timestamp key, follow the conventions of the runtime you are using. Lambda supports most common naming conventions used by the managed runtimes. For example, in functions that use the .NET runtime, Lambda recognizes the key "Timestamp".

Note

To use log-level filtering, your function must be configured to use the JSON log format. The default log format for all Lambda managed runtimes is currently plain text. To learn how to configure your function's log format to JSON, see Setting your function's log format.

For application logs (the logs generated by your function code), you can choose between the following log levels.

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

When you select a log level, Lambda sends logs at that level and lower to CloudWatch Logs. For example, if you set a function’s application log level to WARN, Lambda doesn’t send log outputs at the INFO and DEBUG levels. The default application log level for log filtering is INFO.

When Lambda filters your function’s application logs, log messages with no level will be assigned the log level INFO.

For system logs (the logs generated by the Lambda service), you can choose between the following log levels.

Log level Usage
DEBUG (most detail) Detailed information for system debugging
INFO Messages that record the normal operation of your function
WARN (least detail) Messages about potential errors that may lead to unexpected behavior if unaddressed

When you select a log level, Lambda sends logs at that level and lower. For example, if you set a function’s system log level to INFO, Lambda doesn’t send log outputs at the DEBUG level.

By default, Lambda sets the system log level to INFO. With this setting, Lambda automatically sends "start" and "report" log messages to CloudWatch. To receive more or less detailed system logs, change the log level to DEBUG or WARN. To see a list of the log levels that Lambda maps different system log events to, see System log level event mapping.

Configuring log-level filtering

To configure application and system log-level filtering for your function, you can use the Lambda console or the AWS Command Line Interface (AWS CLI). You can also configure a function’s log level using the CreateFunction and UpdateFunctionConfiguration Lambda API commands, the AWS Serverless Application Model (AWS SAM) AWS::Serverless::Function resource, and the AWS CloudFormation AWS::Lambda::Function resource.

Note that if you set your function's log level in your code, this setting takes precedence over any other log level settings you configure. For example, if you use the Python logging setLevel() method to set your function's logging level to INFO, this setting takes precedence over a setting of WARN that you configure using the Lambda console.

To configure an existing function’s application or system log level (console)
  1. Open the Functions page of the Lambda console.

  2. Choose a function.

  3. On the function configuration page, choose Monitoring and operations tools.

  4. In the Logging configuration pane, choose Edit.

  5. Under Log content, for Log format ensure JSON is selected.

  6. Using the radio buttons, select your desired Application log level and System log level for your function.

  7. Choose Save.

To configure an existing function’s application or system log level (AWS CLI)
  • To change the application or system log level of an existing function, use the update-function-configuration command. Set --system-log-level to one of DEBUG, INFO, or WARN. Set --application-log-level to one of DEBUG, INFO, WARN, ERROR, or FATAL.

    aws lambda update-function-configuration \ --function-name myFunction --system-log-level WARN \ --application-log-level ERROR
To configure log-level filtering when you create a function
  • To configure log-level filtering when you create a new function, use the --system-log-level and --application-log-level options in the create-function command. Set --system-log-level to one of DEBUG, INFO, or WARN. Set --application-log-level to one of DEBUG, INFO, WARN, WARN, or FATAL.

    aws lambda create-function --function-name myFunction --runtime nodejs18.x \ --handler index.handler --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/LambdaRole --system-log-level WARN \ --application-log-level ERROR

System log level event mapping

For system level log events generated by Lambda, the following table defines the log level assigned to each event. To learn more about the events listed in the table, see Lambda Telemetry API Event schema reference

Event name Condition Assigned log level
initStart runtimeVersion is set INFO
initStart runtimeVersion is not set DEBUG
initRuntimeDone status=success DEBUG
initRuntimeDone status!=success WARN
initReport initializationType=snapstart INFO
initReport initializationType!=snapstart DEBUG
initReport status!=success WARN
restoreStart runtimeVersion is set INFO
restoreStart runtimeVersion is not set DEBUG
restoreRuntimeDone status=success DEBUG
restoreRuntimeDone status!=success WARN
restoreReport status=success INFO
restoreReport status!=success WARN
start - INFO
runtimeDone status=success DEBUG
runtimeDone status!=success WARN
report status=success INFO
report status!=success WARN
extension state=success INFO
extension state!=success WARN
logSubscription - INFO
telemetrySubscription - INFO
logsDropped - WARN
Note

The Lambda Telemetry API always emits the complete set of platform events. Configuring the level of the system logs Lambda sends to CloudWatch doesn’t affect Lambda Telemetry API behavior.

Application log-level filtering with custom runtimes

When you configure application log-level filtering for your function, behind the scenes Lambda sets the application log level in the runtime using the AWS_LAMBDA_LOG_LEVEL environment variable. Lambda also sets your function's log format using the AWS_LAMBDA_LOG_FORMAT environment variable. You can use these variables to integrate Lambda advanced logging controls into a custom runtime.

For the ability to configure logging settings for a function using a custom runtime with the Lambda console, AWS CLI, and Lambda APIs, configure your custom runtime to check the value of these environment variables. You can then configure your runtime's loggers in accordance with the log format and log levels you select.

Configuring CloudWatch log groups

By default, CloudWatch automatically creates a log group named /aws/lambda/<function name> for your function when it's first invoked. To configure your function to send logs to an existing log group, or to create a new log group for your function, you can use the Lambda console or the AWS CLI. You can also configure custom log groups using the CreateFunction and UpdateFunctionConfiguration Lambda API commands and the AWS Serverless Application Model (AWS SAM) AWS::Serverless::Function resource.

You can configure multiple Lambda functions to send logs to the same CloudWatch log group. For example, you could use a single log group to store logs for all of the Lambda functions that make up a particular application. When you use a custom log group for a Lambda function, the log streams Lambda creates include the function name and function version. This ensures that the mapping between log messages and functions is preserved, even if you use the same log group for multiple functions.

The log stream naming format for custom log groups follows this convention:

YYYY/MM/DD/<function_name>[<function_version>][<execution_environment_GUID>]

Note that when configuring a custom log group, the name you select for your log group must follow the CloudWatch Logs naming rules. Additionally, custom log group names mustn't begin with the string aws/. If you create a custom log group beginning with aws/, Lambda won't be able to create the log group. As a result of this, your function's logs won't be sent to CloudWatch.

To change a function’s log group (console)
  1. Open the Functions page of the Lambda console.

  2. Choose a function.

  3. On the function configuration page, choose Monitoring and operations tools.

  4. In the Logging configuration pane, choose Edit.

  5. In the Logging group pane, for CloudWatch log group, choose Custom.

  6. Under Custom log group, enter the name of the CloudWatch log group you want your function to send logs to. If you enter the name of an existing log group, then your function will use that group. If no log group exists with the name that you enter, then Lambda will create a new log group for your function with that name.

To change a function's log group (AWS CLI)
  • To change the log group of an existing function, use the update-function-configuration command. If you specify the name of an existing log group, then your function will use that group. If no log group exists with the name that you specify, then Lambda will create a new log group for your function with that name.

    aws lambda update-function-configuration \ --function-name myFunction --log-group myLogGroup
To specify a custom log group when you create a function (AWS CLI)
  • To specify a custom log group when you create a new Lambda function using the AWS CLI, use the --log-group option. If you specify the name of an existing log group, then your function will use that group. If no log group exists with the name that you specify, then Lambda will create a new log group for your function with that name.

    The following example command creates a Node.js Lambda function that sends logs to a log group named myLogGroup.

    aws lambda create-function --function-name myFunction --runtime nodejs18.x \ --handler index.handler --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/LambdaRole --log-group myLogGroup

Execution role permissions

For your function to send logs to CloudWatch Logs, it must have the logs:PutLogEvents permission. When you configure your function's log group using the Lambda console, if your function doesn't have this permission, Lambda adds it to the function's execution role by default. When Lambda adds this permission, it gives the function permission to send logs to any CloudWatch Logs log group.

To prevent Lambda from automatically updating the function's execution role and edit it manually instead, expand Permissions and uncheck Add required permissions.

When you configure your function's log group using the AWS CLI, Lambda won't automatically add the logs:PutLogEvents permission. Add the permission to your function's execution role if it doesn't already have it. This permission is included in the AWSLambdaBasicExecutionRole managed policy.

Accessing logs with the Lambda console

To view logs using the Lambda console
  1. Open the Functions page of the Lambda console.

  2. Choose a function.

  3. Choose Monitor.

  4. Choose View logs in CloudWatch.

Accessing logs with the 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 Windows. macOS users may need to use base64 -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-name stream1 --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" }

Runtime function logging

To debug and validate that your code is working as expected, you can output logs with the standard logging functionality for your programming language. The Lambda runtime uploads your function's log output to CloudWatch Logs. For language-specific instructions, see the following topics:

What's next?