{"_id":"@car-throttle/aws-cloudwatch-logger","_rev":"5-4d253a62ee64c56d57b03ba0c56e3a81","name":"@car-throttle/aws-cloudwatch-logger","description":"Send your application logs from your containers seamlessly to AWS Cloudwatch","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@car-throttle/aws-cloudwatch-logger","version":"1.0.0","description":"Send your application logs from your containers seamlessly to AWS Cloudwatch","main":"logger.js","scripts":{"dev":"nodemon example.js","lint":"eslint logger.js","mocha":"mocha *.test.js","posttest":"istanbul check-coverage","test":"istanbul cover -x *.test.js _mocha -- *.test.js","preversion":"npm test","postversion":"git push && git push --tags"},"repository":{"type":"git","url":"git+https://github.com/car-throttle/aws-cloudwatch-logger.git"},"keywords":["aws","cloudwatch","logger","docker","logging"],"files":["logger.js"],"author":{"name":"James Dryden","email":"james.dryden@carthrottle.com"},"license":"MIT","bugs":{"url":"https://github.com/car-throttle/aws-cloudwatch-logger/issues"},"homepage":"https://github.com/car-throttle/aws-cloudwatch-logger#readme","devDependencies":{"axios":"^0.16.2","body-parser":"^1.17.2","eslint":"^3.19.0","eslint-plugin-mocha":"^4.11.0","express":"^4.15.4","istanbul":"^0.4.5","lodash":"^4.17.4","mocha":"^3.5.0","nodemon":"^1.11.0"},"gitHead":"33eeeb111810aa616f852ad5d3a789bd6231d2e2","_id":"@car-throttle/aws-cloudwatch-logger@1.0.0","_npmVersion":"5.3.0","_nodeVersion":"8.1.4","_npmUser":{"name":"jdrydn","email":"james@jdrydn.com"},"dist":{"integrity":"sha512-ttjESgVdg1j1wGuzZ1eRcQ+apDUBtzLdGIe5x4LJL4oGCfNVi+nC0j2cI6WUvNbp6u2lv6VAC6i3IcTNtC+0lw==","shasum":"4cf6bfa8738f6937bce55965bc53f82df45560e6","tarball":"https://registry.npmjs.org/@car-throttle/aws-cloudwatch-logger/-/aws-cloudwatch-logger-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDL3jrXEdS42r4flxjStSJfSCKPOE3fMW32jSI/dckI3QIhAJNLknTRPRz1TzY/3R3TzjD72uqRTYwKkUfJe9aexoy3"}]},"maintainers":[{"name":"jdrydn","email":"james@jdrydn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aws-cloudwatch-logger-1.0.0.tgz_1503521191491_0.5090296873822808"},"directories":{},"deprecated":"This package is deprecated in favour of bunyan, winston, etc."},"1.1.0":{"name":"@car-throttle/aws-cloudwatch-logger","version":"1.1.0","description":"Send your application logs from your containers seamlessly to AWS Cloudwatch","main":"logger.js","scripts":{"dev":"nodemon example.js","lint":"eslint logger.js","mocha":"mocha *.test.js","posttest":"istanbul check-coverage","test":"istanbul cover -x *.test.js _mocha -- *.test.js","preversion":"npm test","postversion":"git push && git push --tags"},"repository":{"type":"git","url":"git+https://github.com/car-throttle/aws-cloudwatch-logger.git"},"keywords":["aws","cloudwatch","logger","docker","logging"],"files":["logger.js"],"author":{"name":"James Dryden","email":"james.dryden@carthrottle.com"},"license":"MIT","bugs":{"url":"https://github.com/car-throttle/aws-cloudwatch-logger/issues"},"homepage":"https://github.com/car-throttle/aws-cloudwatch-logger#readme","devDependencies":{"axios":"^0.16.2","body-parser":"^1.17.2","eslint":"^3.19.0","eslint-plugin-mocha":"^4.11.0","express":"^4.15.4","istanbul":"^0.4.5","lodash":"^4.17.4","mocha":"^3.5.0","nodemon":"^1.11.0"},"gitHead":"99b7997a39b7220071309c13fa2b998faf05c632","_id":"@car-throttle/aws-cloudwatch-logger@1.1.0","_npmVersion":"5.4.2","_nodeVersion":"8.1.4","_npmUser":{"name":"jdrydn","email":"james@jdrydn.com"},"dist":{"integrity":"sha512-oZFGT/Wfk+zf8xgxAHYucyv4980LghMX8XYHGPyBkEePNIZLuvkZOmKIZHqX1uVFcGLSmPFo3ArIQd1ma02GZA==","shasum":"548063e06510ca1a1b969bd4192121adf8230784","tarball":"https://registry.npmjs.org/@car-throttle/aws-cloudwatch-logger/-/aws-cloudwatch-logger-1.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHpjPCEQncwlO3QXzKAxPWu7SSEkpbc/XsEJfxCY822eAiEAip0lviOuAxg0PkCB5Lvoyu64kabldc2F4d+yHhcGUbE="}]},"maintainers":[{"name":"jdrydn","email":"james@jdrydn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/aws-cloudwatch-logger-1.1.0.tgz_1508494796334_0.3945298364851624"},"directories":{},"deprecated":"This package is deprecated in favour of bunyan, winston, etc."}},"readme":"# AWS Cloudwatch Logger\n\n[![NPM Version](https://badge.fury.io/js/%40car-throttle%2Faws-cloudwatch-logger.svg)](https://www.npmjs.com/package/@car-throttle/aws-cloudwatch-logger)\n[![Circle CI](https://circleci.com/gh/car-throttle/aws-cloudwatch-logger/tree/master.svg?style=shield)](https://circleci.com/gh/car-throttle/aws-cloudwatch-logger/tree/master)\n[![Coverage Status](https://coveralls.io/repos/github/car-throttle/aws-cloudwatch-logger/badge.svg?branch=master)](https://coveralls.io/github/car-throttle/aws-cloudwatch-logger?branch=master)\n\nSend your application logs from your Docker containers directly to [AWS Cloudwatch](https://aws.amazon.com/cloudwatch/).\nThis is particularly ideal if you're running containers on [AWS EC2 Container Service](https://aws.amazon.com/ecs/),\nalthough this has also been used to send logs from containers running on self-hosted hardware.\n\n## Usage\n\n```sh\n$ npm install --save @car-throttle/aws-cloudwatch-logger\n```\n\n```js\nconst CloudwatchLogger = require('@car-throttle/aws-cloudwatch-logger');\n\nconst logger = CloudwatchLogger.createLogger();\n\nlogger.debug('This is a lovely debug message!');\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'debug',\n//   message: 'This is a lovely debug message!' }\n\nlogger.info('Some information for you', { this: 'that' });\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'info',\n//   message: 'Some information for you',\n//   data: { this: 'that' } }\n\nlogger.warn('Important warning for you');\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'warn',\n//   message: 'Important warning for you' }\n\nlogger.error(new Error('Oh man, this errored'));\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'error',\n//   error:\n//    { code: null,\n//      name: 'Error',\n//      message: 'Oh man, this errored',\n//      stack:\n//       [ 'Error: Oh man, this errored',\n//         'at Object.<anonymous> (/workspace/example.js:17:14)',\n//         'at Module._compile (module.js:571:32)',\n//         '...', // Omitted\n//         'at bootstrap_node.js:538:3' ] } }\n```\n\nIn development, these will be lovely `util.inspect`'d objects, but in production the format will be minified to:\n\n```\n{\"timestamp\":\"2017-08-23T21:37:51.574Z\",\"type\":\"debug\",\"message\":\"This is a lovely debug message!\"}\n{\"timestamp\":\"2017-08-23T21:37:51.574Z\",\"type\":\"info\",\"message\":\"Some information for you\",\"data\":{\"this\":\"that\"}}\n{\"timestamp\":\"2017-08-23T21:37:51.574Z\",\"type\":\"warn\",\"message\":\"Important warning for you\"}\n{\"timestamp\":\"2017-08-23T21:37:51.574Z\",\"type\":\"error\",\"error\":{\"code\":null,\"name\":\"Error\",\"message\":\"Oh man, this errored\",\"stack\":[\"Error: Oh man, this errored\",\"at Object.<anonymous> (/Users/james/Sites/Car-Throttle/aws-cloudwatch-logger/example.js:17:14)\",\"at Module._compile (module.js:569:30)\",\"...\",\"at bootstrap_node.js:575:3\"]}}\n```\n\n### Middleware\n\n```js\nconst CloudwatchLogger = require('@car-throttle/aws-cloudwatch-logger');\nconst crypto = require('crypto');\nconst express = require('express');\n\nconst app = express();\nconst logger = CloudwatchLogger.createLogger();\n\napp.use(CloudwatchLogger.createMiddleware());\n\napp.get('/', (req, res) => res.json('Hello world!'));\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'req',\n//   id: 'f283e4b5b608ee7a42d9c239',\n//   req:\n//    { method: 'GET',\n//      url: '/?id=12&fields[]=id&fields[]=title&fields[]=content',\n//      headers:\n//       { accept: 'application/json, text/plain, */*',\n//         connection: 'close',\n//         host: '127.0.0.1:34685',\n//         'user-agent': 'axios/0.16.2' },\n//      path: '/',\n//      query: { id: '12', fields: [ 'id', 'title', 'content' ] },\n//      body: {} },\n//   res:\n//    { statusCode: 200,\n//      headers:\n//       { 'content-length': '14',\n//         'content-type': 'application/json; charset=utf-8',\n//         etag: 'W/\"e-nkbG/vEV8ab/vH4HRSEWq+7z/MU\"',\n//         'x-powered-by': 'Express' } } }\n\napp.post('/', (req, res) => res.status(201).json({\n  entry_id: crypto.randomBytes(12).toString('hex'),\n  success: true,\n}));\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'req',\n//   id: '5723372b27db8ad491e221da',\n//   req:\n//    { method: 'POST',\n//      url: '/',\n//      headers:\n//       { accept: 'application/json, text/plain, */*',\n//         connection: 'close',\n//         'content-length': '25',\n//         'content-type': 'application/json;charset=utf-8',\n//         host: '127.0.0.1:34685',\n//         'user-agent': 'axios/0.16.2' },\n//      path: '/',\n//      query: {},\n//      body: [ 'example', 'post', 'data' ] },\n//   res:\n//    { statusCode: 201,\n//      headers:\n//       { 'content-length': '54',\n//         'content-type': 'application/json; charset=utf-8',\n//         etag: 'W/\"36-2DtRf3MicJ/LCYV2dgBWg9MtJms\"',\n//         'x-powered-by': 'Express' } } }\n```\n\nAnd of course in production they will be minified.\n\n## API\n\n```js\nconst CloudwatchLogger = require('@car-throttle/aws-cloudwatch-logger');\nconst uuid = require('uuid');\n\n// Creates a logger with debug(), info(), warn() & error() methods\nconst logger = CloudwatchLogger.createLogger({\n  level: 'info', // Optionally set a base level, useful to ignore DEBUG messages in production\n  stream: writeStream, // Optionally set a stream to write to instead of process.stdout\n});\n\n// Create a middleware function to log requests as responses are sent\nconst middleware = CloudwatchLogger.createMiddleware({\n  logger, // Optionally include the CloudwatchLogger you previously instantiated\n  // stream: writeStream, // If you do not include a CloudwatchLogger then one will be created for you with this option\n\n  header: 'X-Request-ID', // Optionally attach an ID with the request\n  headerId: () => uuid.v4(), // And a function to generate a header, otherwise crypto.randomBytes will be used\n\n  // Overwrite the function used to create the logged request object\n  // Be wary of using this function & where you place the createMiddleware function\n  // E.g. placing this middleware before your authentication middleware means that req.user won't exist yet\n  req(req) {\n    return {\n      method: req.method,\n      url: req.originalUrl || req.url,\n      headers: req.headers,\n      path: req.path,\n      query: JSON.parse(JSON.stringify(req.query || {})),\n      body: JSON.parse(JSON.stringify(req.body || {})),\n    };\n  },\n  // Overwrite the function used to create the logged response object\n  res(res) {\n    return {\n      statusCode: res.statusCode,\n      headers: res._headers || {},\n    };\n  },\n  // Given that you may have other middleware functions that'll run after this, you can optionally append additional\n  // items to the logged data right before it's sent to Cloudwatch.\n  format(record, req, res) {\n    if (req.user && req.user.id) record.req.user = { id: req.user.id };\n  },\n});\n\n// Formats an error into an object, perfect for dropping into JSON.stringify\nCloudwatchLogger.formatErr(new Error('This is not the error you are looking for, move along!'));\n// { code: 'ROUTE_NOT_FOUND',\n//   name: 'NotFoundError',\n//   message: 'Route not found: /foobar',\n//   stack:\n//    [ 'NotFoundError: Route not found: /foobar',\n//      'at app.use (/workspace/example.js:39:15)',\n//      '...', // Omitted\n//      'at /workspace/node_modules/express/lib/router/index.js:284:7' ] }\n```\n\n## Interesting use cases\n\n### Attaching the error to the request log\n\nAttaching the error object to `res.error` and then reattaching it in the `format` function right before the record is\nsent to CloudWatch.\n\n```js\nconst CloudwatchLogger = require('@car-throttle/aws-cloudwatch-logger');\nconst express = require('express');\n\nconst app = express();\n\napp.use(CloudwatchLogger.createMiddleware({\n  format(record, req, res) {\n    if (res.error) record.res.error = res.error;\n  },\n}));\n\napp.use((req, res, next) => {\n  const err = new Error(`Route not found: ${req.url}`);\n  err.code = 'ROUTE_NOT_FOUND';\n  err.name = 'NotFoundError';\n  err.status = 404;\n  next(err);\n});\n\napp.use((err, req, res, next) => {\n  const output = {\n    code: err.code || null,\n    name: err.name || 'Error',\n    message: err.message || `${err}`,\n    status: err.status || 500,\n  };\n\n  res.error = CloudwatchLogger.formatErr(err);\n\n  res.status(output.status).json(output);\n});\n\n// { timestamp: 'Wed Aug 23 2017 21:37:51 GMT+0100 (BST)',\n//   type: 'req',\n//   req:\n//    { method: 'GET',\n//      url: '/foobar',\n//      headers:\n//       { accept: 'application/json, text/plain, */*',\n//         connection: 'close',\n//         host: '127.0.0.1:34685',\n//         'user-agent': 'axios/0.16.2' },\n//      path: '/foobar',\n//      query: '{}',\n//      body: '{}' },\n//   res:\n//    { statusCode: 404,\n//      headers:\n//       { 'content-length': '99',\n//         'content-type': 'application/json; charset=utf-8',\n//         etag: 'W/\"63-H7EMZzHMCMoTxCA4i0/u4Xhw7S0\"',\n//         'x-powered-by': 'Express' },\n//      error:\n//       { code: 'ROUTE_NOT_FOUND',\n//         name: 'NotFoundError',\n//         message: 'Route not found: /foobar',\n//         stack:\n//          [ 'NotFoundError: Route not found: /foobar',\n//            'at app.use (/workspace/example.js:39:15)',\n//            '...', // Omitted\n//            'at /workspace/node_modules/express/lib/router/index.js:284:7' ] } } }\n```\n\n## Configuring ECS\n\n- Enter the `awslogs-group` and `awslogs-region` when you change the container definition log configuration to\n  `awslogs`.\n- Create an ECS-task-definition IAM role and attach a policy to allow that role to add Cloudwatch logs.\n- Don't forget to [configure](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html) your ECS\n  instances!\n","maintainers":[{"email":"npm@npmjs.com","name":"npm"}],"time":{"modified":"2023-02-03T18:32:02.669Z","created":"2017-08-23T20:46:32.615Z","1.0.0":"2017-08-23T20:46:32.615Z","1.1.0":"2017-10-20T10:19:57.310Z"},"homepage":"https://github.com/car-throttle/aws-cloudwatch-logger#readme","keywords":["aws","cloudwatch","logger","docker","logging"],"repository":{"type":"git","url":"git+https://github.com/car-throttle/aws-cloudwatch-logger.git"},"author":{"name":"James Dryden","email":"james.dryden@carthrottle.com"},"bugs":{"url":"https://github.com/car-throttle/aws-cloudwatch-logger/issues"},"license":"MIT","readmeFilename":"README.md"}