{"id":13473482,"url":"https://github.com/koajs/bunyan-logger","last_synced_at":"2025-04-12T13:28:32.005Z","repository":{"id":22605687,"uuid":"25947856","full_name":"koajs/bunyan-logger","owner":"koajs","description":"Koa middleware for bunyan request logging","archived":false,"fork":false,"pushed_at":"2025-04-09T13:45:30.000Z","size":219,"stargazers_count":108,"open_issues_count":3,"forks_count":32,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-04-09T14:21:29.700Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/koajs.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"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}},"created_at":"2014-10-30T00:35:54.000Z","updated_at":"2024-08-12T10:47:48.000Z","dependencies_parsed_at":"2023-02-13T03:45:33.530Z","dependency_job_id":"e2d2a4db-7fbd-4608-b08c-6214401bbbaf","html_url":"https://github.com/koajs/bunyan-logger","commit_stats":{"total_commits":58,"total_committers":18,"mean_commits":"3.2222222222222223","dds":0.7586206896551724,"last_synced_commit":"b8b27d3a6f57cdb840c68d8dd912ac6fb9cb4295"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koajs%2Fbunyan-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koajs%2Fbunyan-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koajs%2Fbunyan-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koajs%2Fbunyan-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koajs","download_url":"https://codeload.github.com/koajs/bunyan-logger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248429742,"owners_count":21101888,"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","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":"2024-07-31T16:01:04.084Z","updated_at":"2025-04-12T13:28:31.987Z","avatar_url":"https://github.com/koajs.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Middleware","仓库"],"sub_categories":["中间件"],"readme":"# bunyan-logger\n\n\u003e **Update:** Koa team member [@niftylettuce](https://github.com/niftylettuce) released a logging package alternative at \u003chttps://cabinjs.com\u003e!\n\n**NOTE:** that you're reading the README of the version which targets [Koa v2.x](https://github.com/koajs/koa/tree/v2.x), if you want to read about the old 1.X version, switch to Tag 1.3.0.\n\nFlexible log context and request logging middleware\nfor [koa](http://koajs.com/) using [bunyan](https://github.com/trentm/node-bunyan).\n\nInspired by [koa-bunyan](https://github.com/ivpusic/koa-bunyan),\n[koa-json-logger](https://github.com/rudijs/koa-json-logger),\n[bunyan-request](https://github.com/vvo/bunyan-request), and others.\n\n[![Build Status](https://travis-ci.org/koajs/bunyan-logger.svg?branch=master)](https://travis-ci.org/koajs/bunyan-logger)\n[![Coverage Status](https://coveralls.io/repos/koajs/bunyan-logger/badge.png)](https://coveralls.io/r/koajs/bunyan-logger)\n[![npm](http://img.shields.io/npm/v/koa-bunyan-logger.svg)](https://www.npmjs.org/package/koa-bunyan-logger)\n\nA primary goal of this module is to be as flexible as possible, while\nremaining relatively lightweight, leaving advanced functionality and\ncustomization the app.\n\n```js\nconst koa = require('koa');\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\nconst app = koa();\napp.use(koaBunyanLogger());\n\napp.use(function (ctx, next) {\n  ctx.log.info('Got a request from %s for %s', ctx.request.ip, ctx.path);\n  return next();\n});\n\napp.listen(8000);\n```\n\nServer:\n```\nnode examples/simple.js | ./node_modules/.bin/bunyan -o short`\n```\n\nClient:\n```\ncurl http://localhost:8000/\n```\n\nServer output:\n```\n07:50:14.014Z  INFO koa: Got a request from ::1 for /\n```\n\n### Request logging\n\n```js\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\napp.use(koaBunyanLogger.requestLogger());\n```\n\nServer:\n```\nnode examples/requests.js | ./node_modules/.bin/bunyan -o short\n```\n\nClient:\n```\ncurl -H \"X-Request-Id: 1234\" http://localhost:8000/\n```\n\nServer output:\n```\n20:19:24.526Z  INFO koa:   --\u003e GET / (req_id=1234)\n    GET / HTTP/1.1\n    --\n    req.header: {\n      \"user-agent\": \"curl/7.30.0\",\n      \"host\": \"localhost:8000\",\n      \"accept\": \"*/*\",\n      \"x-request-id\": \"1234\"\n    }\n20:19:24.527Z  INFO koa:   \u003c-- GET / 1ms (req_id=1234, duration=1, res.status=200, res.message=OK)\n    GET / HTTP/1.1\n    --\n    x-powered-by: koa\n    content-type: text/plain; charset=utf-8\n    content-length: 11\n    --\n    req.header: {\n      \"user-agent\": \"curl/7.30.0\",\n      \"host\": \"localhost:8000\",\n      \"accept\": \"*/*\",\n      \"x-request-id\": \"1234\"\n    }\n```\n\n### Ignoring specific path from logging\n\nIt is possible to skip logs from some endpoints with `ignorePath` option.\n\n```js\napp.use(koaBunyanLogger.requestLogger({ ignorePath: ['/ping'] }))\n```\n\n### Suppressing default error stack traces\n\nTo ensure that stack traces from request handling don't get logged in their\nraw non-JSON forms, you can disable the app's default error handler:\n\n```js\napp.on('error', function () {});\n```\n\n## API Reference\n\n### koaBunyanLogger(logger)\n\nParameters:\n- logger: bunyan logger instance or an object to pass to bunyan.createLogger()\n\n#### Examples\n\nUse an existing logger:\n\n```js\nconst bunyan = require('bunyan');\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\nconst appLogger = bunyan.createLogger({\n  name: 'myapp',\n  level: 'debug',\n  serializers: bunyan.stdSerializers\n});\n\napp.use(koaBunyanLogger(appLogger));\n```\n\nShortcut to create a new logger:\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger({\n  name: 'myapp',\n  level: 'debug'\n}));\n```\n\n### koaBunyanLogger.requestLogger(opts)\n\nOptions:\n- durationField: Name of field to store request duration in ms\n\n- levelFn: Function which will be called with (status, err) and should\n  return the name of a log level to be used for the response log entry.\n  The default function will log status 400-499 as warn, 500+ as error,\n  and all other responses as info.\n\n- updateLogFields: Function which will be called with a single argument,\n  an object containing the fields (req, res, err) to be logged with the\n  request and response message.\n\n  The function has the opportunity to add or remove fields from the object,\n  or return a different object to replace the default set of fields.\n  The function will be called using the koa 'this' context, once for the\n  request and again for the response.\n\n- updateRequestLogFields: Function which will be called with a request\n  fields object when logging a request, after processing updateLogFields.\n\n- updateResponseLogFields: Function which will be called with a response\n  fields object when logging a response, after processing updateLogFields.\n  It also receives a second argument, err, if an error was thrown.\n\n- formatRequestMessage: Function which will be called to generate a log message\n  for logging requests. The function will be called in the context of the\n  koa 'this' context and passed the request fields object. It should return\n  a string.\n\n- formatResponseMessage: Same as formatRequestLog, but for responses.\n\n#### Examples\n\nBasic usage:\n\n```js\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestLogger());\n```\n\nAdd custom fields to include in request and response logs:\n\n```js\napp.use(koaBunyanLogger.requestLogger({\n  // Custom fields for both request and response\n  updateLogFields: function (fields) {\n    fields.authorized_user = this.user.id;\n    fields.client_version = this.request.get('X-Client-Version');\n  },\n\n  // Custom fields for response only\n  updateResponseLogFields: function (fields, err) {\n    if (err) {\n      fields.last_db_query = this.db.lastDbQuery();\n    }\n  }\n}));\n```\n\n### koaBunyanLogger.requestIdContext(opts)\n\nGet X-Request-Id header, or if the header does not exist, generates a random\nunique id for each request.\n\nOptions:\n- header: name of header to get request id from\n- prop: property to store on context; defaults to 'reqId' e.g. this.reqId\n- requestProp: property to store on request; defaults to 'reqId' e.g. this.request.reqId\n- field: field to add to log messages in downstream middleware and handlers;\n  defaults to 'req_id'\n\n#### Examples\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\n```\n\nOr use a different header:\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext({\n  header: 'Request-Id'\n}));\n```\n\nBy default, the request id will be accessible as this.reqId and this.request.reqId:\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\n\napp.use(function (ctx) {\n  ctx.response.set('X-Server-Request-Id', ctx.reqId);\n  ctx.body = \"Hello world\";\n});\n```\n\n### koaBunyanLogger.timeContext(opts)\n\nAdds `time(label)` and `timeEnd(label)` methods to the koa\ncontext, which records the time between the time() and\ntimeEnd() calls for a given label.\n\nCalls to time() and timeEnd() can be nested or interleaved\nas long as they're balanced for each label.\n\nOptions:\n- logLevel: name of log level to use; defaults to 'trace'\n- updateLogFields: function which will be called with\n    arguments (fields) in koa context; can update fields or\n    return a new object.\n\n#### Examples\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\napp.use(koaBunyanLogger.timeContext());\n\napp.use(function (ctx) {\n  ctx.time('get data');\n\n  return getUser()\n  .then(u =\u003e {\n    return getFriend(u)\n    .then(f =\u003e [u, f]);\n  })\n  .then(data =\u003e {\n    let user = data[0];\n    let friends = data[1];\n\n    ctx.timeEnd('get data');\n    ctx.time('serialize');\n    ctx.body = serialize(user, friends);\n    ctx.timeEnd('serialize');\n  });\n});\n```\n\nThe same but using async functions\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\napp.use(koaBunyanLogger.timeContext());\n\napp.use(async function (ctx) {\n  ctx.time('get data');\n  let user = await getUser();\n  let friends = await getFriend(user);\n  ctx.timeEnd('get data');\n\n  ctx.time('serialize');\n  ctx.body = serialize(user, friends);\n  ctx.timeEnd('serialize');\n});\n```\n\nExample output:\n```json\n{\"name\":\"koa\",\"hostname\":\"localhost\",\"pid\":9228,\"level\":10,\"label\":\"get data\",\"duration\":102,\"msg\":\"\",\"time\":\"2014-11-07T01:45:53.711Z\",\"v\":0}\n{\"name\":\"koa\",\"hostname\":\"localhost\",\"pid\":9228,\"level\":10,\"label\":\"serialize\",\"duration\":401,\"msg\":\"\",\"time\":\"2014-11-07T01:45:54.116Z\",\"v\":0}\n```\n\nTo return different fields, such as nesting the data under\na single field, add a `updateLogFields` function to the options:\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\n\napp.use(koaBunyanLogger());\napp.use(koaBunyanLogger.requestIdContext());\napp.use(koaBunyanLogger.timeContext({\n  updateLogFields: function (fields) {\n    return {\n      request_trace: {\n        name: fields.label,\n        time: fields.duration\n      }\n    };\n  }\n}));\n```\n\n### bunyan export\n\nThe internal copy of bunyan is exported as `.bunyan`:\n\n```js\nconst koaBunyanLogger = require('koa-bunyan-logger');\nconst bunyan = koaBunyanLogger.bunyan;\n```\n\n## Sponsored by\n\n[Pebble Technology!](https://www.pebble.com)\n\n## License\n\n[MIT](https://github.com/koajs/bunyan-logger/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoajs%2Fbunyan-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoajs%2Fbunyan-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoajs%2Fbunyan-logger/lists"}