AWS Lambda function logging in TypeScript - AWS Lambda

AWS Lambda function logging in TypeScript

AWS Lambda automatically monitors Lambda functions and sends log entries 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 and other output from your function's code to the log stream. For more information about CloudWatch Logs, see Using Amazon CloudWatch logs with AWS Lambda.

To output logs from your function code, you can use methods on the console object. For more detailed logging, you can use any logging library that writes to stdout or stderr.

Tools and libraries

Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless best practices and increase developer velocity. The Logger utility provides a Lambda optimized logger which includes additional information about function context across all your functions with output structured as JSON. Use this utility to do the following:

  • Capture key fields from the Lambda context, cold start and structures logging output as JSON

  • Log Lambda invocation events when instructed (disabled by default)

  • Print all the logs only for a percentage of invocations via log sampling (disabled by default)

  • Append additional keys to structured log at any point in time

  • Use a custom log formatter (Bring Your Own Formatter) to output logs in a structure compatible with your organization’s Logging RFC

Using Powertools for AWS Lambda (TypeScript) and AWS SAM for structured logging

Follow the steps below to download, build, and deploy a sample Hello World TypeScript application with integrated Powertools for AWS Lambda (TypeScript) modules using the AWS SAM. This application implements a basic API backend and uses Powertools for emitting logs, metrics, and traces. It consists of an Amazon API Gateway endpoint and a Lambda function. When you send a GET request to the API Gateway endpoint, the Lambda function invokes, sends logs and metrics using Embedded Metric Format to CloudWatch, and sends traces to AWS X-Ray. The function returns a hello world message.

Prerequisites

To complete the steps in this section, you must have the following:

Deploy a sample AWS SAM application
  1. Initialize the application using the Hello World TypeScript template.

    sam init --app-template hello-world-powertools-typescript --name sam-app --package-type Zip --runtime nodejs18.x
  2. Build the app.

    cd sam-app && sam build
  3. Deploy the app.

    sam deploy --guided
  4. Follow the on-screen prompts. To accept the default options provided in the interactive experience, press Enter.

    Note

    For HelloWorldFunction may not have authorization defined, Is this okay?, make sure to enter y.

  5. Get the URL of the deployed application:

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. Invoke the API endpoint:

    curl <URL_FROM_PREVIOUS_STEP>

    If successful, you'll see this response:

    {"message":"hello world"}
  7. To get the logs for the function, run sam logs. For more information, see Working with logs in the AWS Serverless Application Model Developer Guide.

    sam logs --stack-name sam-app

    The log output looks like this:

    2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.552000 START RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb Version: $LATEST 2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.594000 2022-08-31T09:33:10.557Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"_aws":{"Timestamp":1661938390556,"CloudWatchMetrics":[{"Namespace":"sam-app","Dimensions":[["service"]],"Metrics":[{"Name":"ColdStart","Unit":"Count"}]}]},"service":"helloWorld","ColdStart":1} 2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.595000 2022-08-31T09:33:10.595Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"level":"INFO","message":"This is an INFO log - sending HTTP 200 - hello world response","service":"helloWorld","timestamp":"2022-08-31T09:33:10.594Z"} 2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.655000 2022-08-31T09:33:10.655Z 70693159-7e94-4102-a2af-98a6343fb8fb INFO {"_aws":{"Timestamp":1661938390655,"CloudWatchMetrics":[{"Namespace":"sam-app","Dimensions":[["service"]],"Metrics":[]}]},"service":"helloWorld"} 2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.754000 END RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb 2023/01/31/[$LATEST]4d53e8d279824834a1ccd35511a4949c 2022-08-31T09:33:10.754000 REPORT RequestId: 70693159-7e94-4102-a2af-98a6343fb8fb Duration: 201.55 ms Billed Duration: 202 ms Memory Size: 128 MB Max Memory Used: 66 MB Init Duration: 252.42 ms XRAY TraceId: 1-630f2ad5-1de22b6d29a658a466e7ecf5 SegmentId: 567c116658fbf11a Sampled: true
  8. This is a public API endpoint that is accessible over the internet. We recommend that you delete the endpoint after testing.

    sam delete

Managing log retention

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 CloudWatch automatically deletes the logs. To set up log retention, add the following to your AWS SAM template:

Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: # Omitting other properties LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}" RetentionInDays: 7

Using Powertools for AWS Lambda (TypeScript) and the AWS CDK for structured logging

Follow the steps below to download, build, and deploy a sample Hello World TypeScript application with integrated Powertools for AWS Lambda (TypeScript) modules using the AWS CDK. This application implements a basic API backend and uses Powertools for emitting logs, metrics, and traces. It consists of an Amazon API Gateway endpoint and a Lambda function. When you send a GET request to the API Gateway endpoint, the Lambda function invokes, sends logs and metrics using Embedded Metric Format to CloudWatch, and sends traces to AWS X-Ray. The function returns a hello world message.

Prerequisites

To complete the steps in this section, you must have the following:

Deploy a sample AWS CDK application
  1. Create a project directory for your new application.

    mkdir hello-world cd hello-world
  2. Initialize the app.

    cdk init app --language typescript
  3. Add the @types/aws-lambda package as a development dependency.

    npm install -D @types/aws-lambda
  4. Install the Powertools Logger utility.

    npm install @aws-lambda-powertools/logger
  5. Open the lib directory. You should see a file called hello-world-stack.ts. Create new two new files in this directory: hello-world.function.ts and hello-world.ts.

  6. Open hello-world.function.ts and add the following code to the file. This is the code for the Lambda function.

    import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; import { Logger } from '@aws-lambda-powertools/logger'; const logger = new Logger(); export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { logger.info('This is an INFO log - sending HTTP 200 - hello world response'); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
  7. Open hello-world.ts and add the following code to the file. This contains the NodejsFunction construct, which creates the Lambda function, configures environment variables for Powertools, and sets log retention to one week. It also includes the LambdaRestApi construct, which creates the REST API.

    import { Construct } from 'constructs'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway'; import { RetentionDays } from 'aws-cdk-lib/aws-logs'; import { CfnOutput } from 'aws-cdk-lib'; export class HelloWorld extends Construct { constructor(scope: Construct, id: string) { super(scope, id); const helloFunction = new NodejsFunction(this, 'function', { environment: { Powertools_SERVICE_NAME: 'helloWorld', LOG_LEVEL: 'INFO', }, logRetention: RetentionDays.ONE_WEEK, }); const api = new LambdaRestApi(this, 'apigw', { handler: helloFunction, }); new CfnOutput(this, 'apiUrl', { exportName: 'apiUrl', value: api.url, }); } }
  8. Open hello-world-stack.ts. This is the code that defines your AWS CDK stack. Replace the code with the following:

    import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { HelloWorld } from './hello-world'; export class HelloWorldStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new HelloWorld(this, 'hello-world'); } }
  9. Go back to the project directory.

    cd hello-world
  10. Deploy your application.

    cdk deploy
  11. Get the URL of the deployed application:

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?ExportName==`apiUrl`].OutputValue' --output text
  12. Invoke the API endpoint:

    curl <URL_FROM_PREVIOUS_STEP>

    If successful, you'll see this response:

    {"message":"hello world"}
  13. To get the logs for the function, run sam logs. For more information, see Working with logs in the AWS Serverless Application Model Developer Guide.

    sam logs --stack-name HelloWorldStack

    The log output looks like this:

    2023/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2022-08-31T14:48:37.047000 START RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c Version: $LATEST 2023/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2022-08-31T14:48:37.050000 { "level": "INFO", "message": "This is an INFO log - sending HTTP 200 - hello world response", "service": "helloWorld", "timestamp": "2022-08-31T14:48:37.048Z", "xray_trace_id": "1-630f74c4-2b080cf77680a04f2362bcf2" } 2023/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2022-08-31T14:48:37.082000 END RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c 2023/01/31/[$LATEST]2ca67f180dcd4d3e88b5d68576740c8e 2022-08-31T14:48:37.082000 REPORT RequestId: 19ad1007-ff67-40ce-9afe-0af0a9eb512c Duration: 34.60 ms Billed Duration: 35 ms Memory Size: 128 MB Max Memory Used: 57 MB Init Duration: 173.48 ms
  14. This is a public API endpoint that is accessible over the internet. We recommend that you delete the endpoint after testing.

    cdk destroy

Using 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.

Using 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
  1. Open the Log groups page on the CloudWatch console.

  2. Choose the log group for your function (/aws/lambda/your-function-name).

  3. 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.