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.