{"id":31392847,"url":"https://github.com/formidablelabs/pino-lambda","last_synced_at":"2025-09-29T04:48:02.673Z","repository":{"id":41848583,"uuid":"325101034","full_name":"FormidableLabs/pino-lambda","owner":"FormidableLabs","description":"Send pino logs to cloudwatch with aws-lambda","archived":false,"fork":false,"pushed_at":"2024-10-23T18:04:08.000Z","size":1239,"stargazers_count":134,"open_issues_count":4,"forks_count":15,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-09-19T19:52:31.696Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FormidableLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.MD","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-28T19:39:10.000Z","updated_at":"2025-09-04T16:43:05.000Z","dependencies_parsed_at":"2023-11-08T00:00:23.383Z","dependency_job_id":"e4c9c34a-a891-4d7c-90c6-430eec5d09ab","html_url":"https://github.com/FormidableLabs/pino-lambda","commit_stats":{"total_commits":75,"total_committers":8,"mean_commits":9.375,"dds":"0.31999999999999995","last_synced_commit":"a13aec8886c2ee5bc8696cbde5018703921f8d16"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/FormidableLabs/pino-lambda","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FormidableLabs%2Fpino-lambda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FormidableLabs%2Fpino-lambda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FormidableLabs%2Fpino-lambda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FormidableLabs%2Fpino-lambda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FormidableLabs","download_url":"https://codeload.github.com/FormidableLabs/pino-lambda/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FormidableLabs%2Fpino-lambda/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277467480,"owners_count":25822917,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-29T02:00:09.175Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-29T04:48:01.629Z","updated_at":"2025-09-29T04:48:02.667Z","avatar_url":"https://github.com/FormidableLabs.png","language":"TypeScript","readme":"[![pino-lambda — Formidable, We build the modern web](https://raw.githubusercontent.com/FormidableLabs/pino-lambda/master/pino-lambda-Hero.png)](https://formidable.com/open-source/)\n\n[![npm version](https://badge.fury.io/js/pino-lambda.svg)](https://badge.fury.io/js/pino-lambda)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Maintenance Status][maintenance-image]](#maintenance-status)\n\nA custom destination for [pino](https://github.com/pinojs/pino) that takes advantage of the unique environment in AWS Lambda functions. [ref](https://github.com/pinojs/pino/blob/master/docs/api.md#destination)\n\nBy default, this destination reformats the log output so it matches the existing Cloudwatch format. The default pino log format [loses some of the built in support for request ID tracing](https://github.com/pinojs/pino/issues/648) that lambda has built into to support Cloudwatch insights and Xray tracing.\n\nIt also automatically tracks the request id, correlation ids, and xray tracing from upstream services.\n\n### Conceptually based on the following\n\n- [Capture and forward correlation IDs through different Lambda event sources](https://theburningmonk.com/2017/09/capture-and-forward-correlation-ids-through-different-lambda-event-sources/)\n- [Decorated Lambda Handlers](https://tlvince.com/decorated-lambda-handlers)\n\n## Usage\n\nBasic usage for most applications\n\n```ts\nimport pino from 'pino';\nimport { lambdaRequestTracker, pinoLambdaDestination } from 'pino-lambda';\n\n// custom destination formatter\nconst destination = pinoLambdaDestination();\nconst logger = pino(\n  {\n    // typical pino options\n  },\n  destination,\n);\nconst withRequest = lambdaRequestTracker();\n\nasync function handler(event, context) {\n  // automatic request tracing across all instances of pino\n  // called once at the beginning of your Lambda handler\n  withRequest(event, context);\n\n  // typical logging methods\n  logger.info({ data: 'Some data' }, 'A log message');\n}\n```\n\nCloudwatch output will now match the native `console.log` output, correctly preserving\n`@requestid`, `@timestamp`, and `@message` properties for use in Cloudwatch Insights and\nother Cloudwatch aware tools such as Datadog and Splunk.\n\n```\n2018-12-20T17:05:25.330Z    6fccb00e-0479-11e9-af91-d7ab5c8fe19e    INFO  A log message\n{\n   \"awsRequestId\": \"6fccb00e-0479-11e9-af91-d7ab5c8fe19e\",\n   \"x-correlation-id\": \"238da608-0542-11e9-8eb2-f2801f1b9fd1\",\n   \"x-correlation-trace-id\": \"Root=1-5c1bcbd2-9cce3b07143efd5bea1224f2;Parent=07adc05e4e92bf13;Sampled=1\",\n   \"level\": 30,\n   \"message\": \"A log message\",\n   \"data\": \"Some data\"\n}\n```\n\n## Context Updates\n\nThe request logging context can be updated downstream by calling the `updateContext` function. Any duplicate values will overwrite previous values.\n\n_Note: If you provide a custom storage context, you will need to update that storage context directly (this is not typical)_\n\n```\nimport { GlobalContextStorageProvider } from 'pino-lambda';\nGlobalContextStorageProvider.updateContext({ userId: '12' });\n```\n\n## Lambda request tracing\n\nWith context tracing enabled, all instances of `pino` that use one of the built in formatters will automatically log the request id and other details so you don't need to pass an instance of a logger to all of your functions.\n\n| Property               | Value                                      | Info                                                                     |\n| ---------------------- | ------------------------------------------ | ------------------------------------------------------------------------ |\n| awsRequestId           | context.awsRequestId                       | The unique request id for this request                                   |\n| apiRequestId           | context.requestContext.requestId           | The API Gateway RequestId                                                |\n| x-correlation-id       | event.headers['x-correlation-id']          | The upstream request id for tracing                                      |\n| x-correlation-trace-id | process.env.\\_X_AMZN_TRACE_ID              | The AWS Xray tracking id                                                 |\n| x-correlation-\\*       | event.headers.startsWith('x-correlation-') | Any header that starts with `x-correlation-` will be automatically added |\n\nEvery AWS Lambda request contains a unique request ID, `context.awsRequestId`. If the request originated outside of the AWS platform,\nthe request ID will match the `event.header.x-correlation-id` value. However, if the request originated from within the AWS platform,\nthe `event.header.x-correlation-id` will be set to the request ID of the calling service. This allows you to trace a request\nacross the entire platform.\n\nAmazon XRAY also has a unique tracing ID that is propagated across the requests and can be tracked as well.\n\n## Customize request tracing\n\nYou can customize the data that is tracked for each request by adding a per-request mixin.\nThe request mixin takes the Lambda `event` and `context` and returns an object.\n\nThis differs from the built in [pino mixin](https://github.com/pinojs/pino/blob/master/docs/api.md#mixin-function) as it only executes\nonce per request where the built in pino mixin runs once per log entry.\n\n```ts\nimport pino from 'pino';\nimport { lambdaRequestTracker, pinoLambdaDestination } from 'pino-lambda';\n\nconst destination = pinoLambdaDestination();\nconst logger = pino(destination);\nconst withRequest = lambdaRequestTracker({\n  requestMixin: (event, context) =\u003e {\n    return {\n      // add request header host name\n      host: event.headers?.host,\n\n      // you can also set any request property to undefined\n      // which will remove it from the output\n      'x-correlation-id': undefined,\n\n      // add any type of static data\n      brand: 'famicom',\n    };\n  },\n});\n\nasync function handler(event, context) {\n  withRequest(event, context);\n  logger.info({ data: 'Some data' }, 'A log message');\n}\n```\n\nOutput\n\n```\n2018-12-20T17:05:25.330Z    6fccb00e-0479-11e9-af91-d7ab5c8fe19e    INFO  A log message\n{\n   \"awsRequestId\": \"6fccb00e-0479-11e9-af91-d7ab5c8fe19e\",\n   \"x-correlation-trace-id\": \"Root=1-5c1bcbd2-9cce3b07143efd5bea1224f2;Parent=07adc05e4e92bf13;Sampled=1\",\n   \"level\": 30,\n   \"host\": \"www.host.com\",\n   \"brand\": \"famicom\",\n   \"message\": \"A log message\",\n   \"data\": \"Some data\"\n}\n```\n\n### Lambda Structured Log Format\n\nBy default, the `pinoLambdaDestination` uses the `CloudwatchLogFormatter`. \n\nIf you would like to use the new [AWS Lambda Advanced Logging Controls](https://aws.amazon.com/blogs/compute/introducing-advanced-logging-controls-for-aws-lambda-functions/) format for your logs, ensure your Lambda function is properly configured and enable `StructuredLogFormatter` in `pino-lambda`.\n\n```ts\nimport pino from 'pino';\nimport { lambdaRequestTracker, pinoLambdaDestination, StructuredLogFormatter } from 'pino-lambda';\n\nconst destination = pinoLambdaDestination({\n  formatter: new StructuredLogFormatter()\n});\nconst logger = pino(destination);\nconst withRequest = lambdaRequestTracker();\n\nasync function handler(event, context) {\n  withRequest(event, context);\n  logger.info({ data: 'Some data' }, 'A log message');\n}\n```\n\nOutput\n\n```json\n{\n  \"timestamp\": \"2016-12-01T06:00:00.000Z\",\n  \"requestId\": \"6fccb00e-0479-11e9-af91-d7ab5c8fe19e\",\n  \"level\": \"INFO\",\n  \"message\": {\n    \"msg\": \"A log message\",\n    \"data\": \"Some data\",\n    \"x-correlation-trace-id\": \"Root=1-5c1bcbd2-9cce3b07143efd5bea1224f2;Parent=07adc05e4e92bf13;Sampled=1\"\n  }\n}\n```\n\n### Pino Log Format\n\nIf you want the request tracing features of `pino-lambda`, but don't need the Cloudwatch format, you can use the `PinoLogFormatter` which matches the default object output format of `pino`.\n\n```ts\nimport pino from 'pino';\nimport { lambdaRequestTracker, pinoLambdaDestination, PinoLogFormatter } from 'pino-lambda';\n\nconst destination = pinoLambdaDestination({\n  formatter: new PinoLogFormatter(),\n});\nconst logger = pino(destination);\nconst withRequest = lambdaRequestTracker();\n\nasync function handler(event, context) {\n  withRequest(event, context);\n  logger.info({ data: 'Some data' }, 'A log message');\n}\n```\n\nOutput\n\n```json\n{\n  \"awsRequestId\": \"6fccb00e-0479-11e9-af91-d7ab5c8fe19e\",\n  \"x-correlation-trace-id\": \"Root=1-5c1bcbd2-9cce3b07143efd5bea1224f2;Parent=07adc05e4e92bf13;Sampled=1\",\n  \"level\": 30,\n  \"time\": 1480572000000,\n  \"msg\": \"A log message\",\n  \"data\": \"Some data\"\n}\n```\n\n### Custom Log Format\n\nThe formatter function can also be replaced with any custom implementation you need by using the supplied interface.\n\n```ts\nimport { LogData, ILogFormatter } from 'pino-lambda';\n\nclass BananaLogFormatter implements ILogFormatter {\n  format(data: LogData) {\n    return `[BANANA] ${JSON.stringify(data)}`;\n  }\n}\n\nconst destination = pinoLambdaDestination({\n  formatter: new BananaLogFormatter(),\n});\nconst logger = pino(destination);\n```\n\nOutput\n\n```\n[BANANA]\n{\n   \"awsRequestId\": \"6fccb00e-0479-11e9-af91-d7ab5c8fe19e\",\n   \"x-correlation-trace-id\": \"Root=1-5c1bcbd2-9cce3b07143efd5bea1224f2;Parent=07adc05e4e92bf13;Sampled=1\",\n   \"level\": 30,\n   \"msg\": \"A log message\",\n   \"data\": \"Some data\"\n}\n```\n\n## Best Practices\n\nUnless your application is small, it can be useful to split the logger into its own module for easier reuse across your application code. This ensures that all your logging calls receive the correct formatting and context across the request.\n\n```ts\n// logger.ts\nimport pino from 'pino';\nimport { pinoLambdaDestination } from 'pino-lambda';\n\nconst destination = pinoLambdaDestination();\nexport const logger = pino(destination);\n```\n\n```ts\n// handler.ts\nimport { lambdaRequestTracker } from 'pino-lambda';\nimport { logger } from './logger';\n\nconst withRequest = lambdaRequestTracker();\n\nasync function handler(event, context) {\n  // automatic request tracing across all instances of pino\n  // called once at the beginning of your Lambda handler\n  withRequest(event, context);\n\n  // typical logging methods\n  logger.info({ data: 'Some data' }, 'A log message');\n}\n```\n\n## Usage outside of Lambda handlers\n\nYou can use the this wrapper outside of the AWS lambda function in any place you want. This is especially useful in private npm modules that will be used by your AWS Lambda function. The default logger context is a shared instance, so it inherits all properties the default is configured for, and will emit request information for all logs. This effectively allows you to track a request across its entire set of log entries.\n\n## Contributing\n\nPlease see our [contributing guide](CONTRIBUTING.md).\n\n## Maintenance Status\n\n**Active:** Formidable is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.\n\n[maintenance-image]: https://img.shields.io/badge/maintenance-active-green.svg?color=brightgreen\u0026style=flat\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformidablelabs%2Fpino-lambda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fformidablelabs%2Fpino-lambda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformidablelabs%2Fpino-lambda/lists"}