Record the AWS Lambda function log by lambda-log or @dazn/lambda-powertools-logger

AWS Lambda’s log will store in CloudWatch Logs. So we want to log the script data as a JSON format to se […]

広告ここから
広告ここまで

目次

    AWS Lambda’s log will store in CloudWatch Logs. So we want to log the script data as a JSON format to search in the CloudWatch Logs console or APIs.

    In this post, I’ll try to use two logging tools.

    lambda-log

    Install

    We can install the packages by npm.

    $ yarn add lambda-log 
    
    // [for typescript]
    $ yarn add -D @types/lambda-log 

    If you want to use it with TypeScript, we need to add @types one.

    Add logger to the handler

    Then, we can use the logger in our own Lambda handler.

    import { Handler } from 'aws-lambda'
    import * as log from 'lambda-log'
    
    export const handler: Handler = async (event) => {
      log.options.meta.event = event
      log.options.tags.push(process.env.NODE_ENV)
      log.info('info')
      log.warn('warn', {
        meta: {
          item1: 'hello'
        }
      })
      try {
        throw new Error('demo err')
      } catch (err) {
        log.error(err)
        throw err
      }
    }

    Log results

    When execute the function, we can get these logs.

    {"_logLevel":"info","msg":"info","event":{{"username": "dummy"}},"_tags":["log","info","development"]}
    
     {"_logLevel":"warn","msg":"warn","meta":true,"event":{{"username": "dummy"}},"_tags":["log","warn","development"]}
    
     {"_logLevel":"error","msg":"test","event":{{"username": "dummy"}},"stack":"Error: test\n    at handler (webpack-internal:///./handlers/updateCustomer.ts:42:54)\n    ...

    And the following JSON has prettified the log.error.

    {
       _logLevel: 'error',
       msg: 'test',
       event: {
         "username": "dummy"
       },
       stack: 'Error: test\n' +
         '    at handler (webpack-internal:///./handlers/updateCustomer.ts:42:54)\n' +
         '    at /Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:866:30\n' +
         '    at Promise._execute (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/debuggability.js:384:9)\n' +
         '    at Promise._resolveFromExecutor (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:518:18)\n' +
         '    at new Promise (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:103:10)\n' +
         '    at AwsInvokeLocal.invokeLocalNodeJs (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:819:12)\n' +
         '    at AwsInvokeLocal.invokeLocal (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:225:19)\n' +
         '    at AwsInvokeLocal.tryCatcher (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)\n' +
         '    at Promise._settlePromiseFromHandler (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:547:31)\n' +
         '    at Promise._settlePromise (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:604:18)\n' +
         '    at Promise._settlePromiseCtx (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:641:10)\n' +
         '    at _drainQueueStep (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:97:12)\n' +
         '    at _drainQueue (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:86:9)\n' +
         '    at Async._drainQueues (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:102:5)\n' +
         '    at Immediate.Async.drainQueues as _onImmediate\n' +
         '    at processImmediate (internal/timers.js:439:21)\n' +
         '    at process.topLevelDomainCallback (domain.js:130:23)',
       _tags: [ 'log', 'error', 'development' ]
     }

    @dazn/lambda-powertools-logger

    Install

    The package support TypeScript. So we just install the package.

    $ yarn add @dazn/lambda-powertools-lambda-client

    When we want to use it with TypeScript, we need to set allowSyntheticDefaultImports flag to be true.

    {
      "compilerOptions": {
        "allowSyntheticDefaultImports": true,

    Add logger to the handler

    import { Handler } from 'aws-lambda'
    import log from '@dazn/lambda-powertools-logger'
    
    export const handler: Handler = async (event) => {
      log.info('info')
      log.warn('warn', {
        meta: {
          item1: 'hello'
        }
      })
      try {
        throw new Error('demo err')
      } catch (err) {
        log.error('error', err)
        throw err
      }
    }

    Log results

    The package will add the function information automatically.

    {"message":"info","awsRegion":"us-east-1","functionName":"demo-function","functionVersion":"$LATEST","functionMemorySize":"256","environment":"development","level":30,"sLevel":"INFO"}
     {"message":"warn","meta":{"item1":"hello"},"awsRegion":"us-east-1","functionName":"demo-function","functionVersion":"$LATEST","functionMemorySize":"256","environment":"development","level":40,"sLevel":"WARN"}
     {"message":"error","errorName":"Error","errorMessage":"demo err","stackTrace":"Error: demo err\n    at handler (webpack-internal:///./handlers/updateCustomer.ts:44:15)\n  …

    And the following JSON has prettified the log.error.

    message: 'error',
       errorName: 'Error',
       errorMessage: 'demo err',
       stackTrace: 'Error: demo err\n' +
         '    at handler (webpack-internal:///./handlers/updateCustomer.ts:44:15)\n' +
         '    at /Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:866:30\n' +
         '    at Promise._execute (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/debuggability.js:384:9)\n' +
         '    at Promise._resolveFromExecutor (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:518:18)\n' +
         '    at new Promise (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:103:10)\n' +
         '    at AwsInvokeLocal.invokeLocalNodeJs (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:819:12)\n' +
         '    at AwsInvokeLocal.invokeLocal (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:225:19)\n' +
         '    at AwsInvokeLocal.tryCatcher (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)\n' +
         '    at Promise._settlePromiseFromHandler (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:547:31)\n' +
         '    at Promise._settlePromise (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:604:18)\n' +
         '    at Promise._settlePromiseCtx (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:641:10)\n' +
         '    at _drainQueueStep (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:97:12)\n' +
         '    at _drainQueue (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:86:9)\n' +
         '    at Async._drainQueues (/Users/develop/.anyenv/envs/nodenv/versions/12.14.1/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:102:5)\n' +
         '    at Immediate.Async.drainQueues as _onImmediate\n' +
         '    at processImmediate (internal/timers.js:439:21)\n' +
         '    at process.topLevelDomainCallback (domain.js:130:23)',
       awsRegion: 'us-east-1',
       functionName: 'demo-app',
       functionVersion: '$LATEST',
       functionMemorySize: '256',
       environment: 'development',
       level: 50,
       sLevel: 'ERROR'
     }

    What’s the difference?

    lambda-log can contain the request data into log.options.meta.

    And @dazn/lambda-powertools-logger contains the Lambda function environment automatically. And easy to integrate other powertools packages.

    広告ここから
    広告ここまで

    Random posts

    Home
    Search
    Bookmark