{"id":13800567,"url":"https://github.com/rudijs/koa-json-logger","last_synced_at":"2025-10-27T18:30:38.018Z","repository":{"id":19219335,"uuid":"22453526","full_name":"rudijs/koa-json-logger","owner":"rudijs","description":"KoaJS HTTP Request/Response/Error JSON format logger","archived":false,"fork":false,"pushed_at":"2022-02-14T12:04:09.000Z","size":787,"stargazers_count":24,"open_issues_count":3,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-09-27T21:41:03.766Z","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/rudijs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-31T02:40:53.000Z","updated_at":"2022-02-14T14:15:57.000Z","dependencies_parsed_at":"2022-09-10T21:51:21.112Z","dependency_job_id":null,"html_url":"https://github.com/rudijs/koa-json-logger","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudijs%2Fkoa-json-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudijs%2Fkoa-json-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudijs%2Fkoa-json-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudijs%2Fkoa-json-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rudijs","download_url":"https://codeload.github.com/rudijs/koa-json-logger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219860762,"owners_count":16556011,"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-08-04T00:01:13.803Z","updated_at":"2025-10-27T18:30:32.708Z","avatar_url":"https://github.com/rudijs.png","language":"JavaScript","funding_links":[],"categories":["仓库"],"sub_categories":["中间件"],"readme":"koa-json-logger\n===============\n\nKoaJS HTTP Request/Response/Error JSON format logger.\n\n[![Build Status](https://travis-ci.org/rudijs/koa-json-logger.svg?branch=master)](https://travis-ci.org/rudijs/koa-json-logger)\n[![Coverage Status](https://coveralls.io/repos/rudijs/koa-json-logger/badge.png?branch=master)](https://coveralls.io/r/rudijs/koa-json-logger?branch=master)\n[![NPM version](https://badge.fury.io/js/koa-json-logger.svg)](http://badge.fury.io/js/koa-json-logger)\n[![Dependency Status](https://gemnasium.com/rudijs/koa-json-logger.svg)](https://gemnasium.com/rudijs/koa-json-logger)\n\nThe actual logging is done with [node-bunyan](https://github.com/trentm/node-bunyan)\n\nCredits and inspired by:\n\n* [KoaJS](https://github.com/koajs)\n* [express-winston](https://github.com/heapsource/express-winston)\n* [node-bunyan](https://github.com/trentm/node-bunyan)\n* [koa-bunyan](https://github.com/ivpusic/koa-bunyan)\n* [KoaJS Logger](https://github.com/koajs/logger)\n\n\nCode review, suggestions and pull requests very much welcome - thanks!\n\n## Overview\n\nThe basic goal of this module is to create log entries in JSON format for each HTTP request.\n\nSuccess (\u003c400) log entries will contain Request and Response details.\n\nError (\u003e=400) log entries will contain Request, Response and Error details.\n\nSuccess and Error logs will have their own file (two files).\n\nIn NODE_ENV development errors will also be output to the console.\n\n500 error responses are logged in full detail but the HTTP user response will always be only 'Internal Server Error'.\n\nLess than 500 and greater than 500 error responses are logged and passed through as is to the user in the HTTP response.\n\nHigher level goals are:\n\n- Create uniform success and error log entries in JSON format for centralized logging\n- In particular tested and used with the ELK stack (Logstash, Elasticsearch and Kibana)\n- A unique ID (RFC4122 uuid v4) is also created for each log entry.\n- This uid can be used in other application logs, which end up in ELK, so you can correlate the request or error with other application log entries.\n- Support [JSON API](http://jsonapi.org/) response type\n\nBelow will be some sample log entries in pretty print and also some screen shots of how they look in Kibana.\n\n## Install\n\n`npm install koa-json-logger`\n\n## Usage\n\n`var koaJsonLogger = require('koa-json-logger');`\n\n`app.use(koaJsonLogger());`\n\nI suggest it's best to use this middleware high in the middleware stack so any and all downstream errors are logged.\n\nLogs will go into a `log/` directory relative to file that instruments the Koa app, so you'll need to create this folder.\n\nDefault use will create two log files:\n\n`log/app.log` will contain req/res log entries.\n\n`log/app_error.log` will contain error log entries.\n\nLog files are not auto rotated, recommend using system file rotation facility such as `logrotate` on Linux or `logadm` on SmartOS/Illumos.\n\nCurrent config options are:\n\n- `name` (String default: 'app') configures the log file name and name property of the log entry.\n\n- `path` (String default: 'log') configures the log directory (relative) to use.\n\n- `jsonapi` (Boolean default: false) will set the response Content-type to application/vnd.api+json and ensure 500 responses are in JSON API format\n\nExample:\n\n      app.use(koaJsonLogger({\n        name: 'myCoolApp',\n        path: 'logs',\n        jsonapi: true\n      }));\n\nWhen you throw an application error it's best to always use [throw](https://github.com/koajs/koa/blob/master/docs/api/context.md#ctxthrowmsg-status-properties)\n\nExample:\n\n    `this.throw(403, 'Access Denied');`\n\nSee the docs for [throw](https://github.com/koajs/koa/blob/master/docs/api/context.md#ctxthrowmsg-status-properties) details.\n\nYou can return errors this way (no throw) but without throwing this will end up in the standard log file - *not* the error log file.\n\nSo best *not* to do it this way (the error message in the body will *not* be logged):\n\n    // Not a good way to an return error\n    this.status = 401;\n    this.body = 'Access Denied';\n\nIf using [JSON API](http://jsonapi.org/) set `jsonapi: true` - response Content-type header will be set to application/vnd.api+json\n\nYou can then throw errors like this for example:\n\n    this.throw(401, {\n      message: {\n        status: 401,\n        title: 'Unauthorized',\n        detail: 'No Authorization header found'\n      }\n    }\n\nThe unique ID (uid) set for each request and can be accessed/used with `this.uuid`\n\nFor example using Bunyan elsewhere in your application for logging you could use the uid like so:\n\n`logger.info({uid: this.uuid}, 'Application log message here');`\n\nThen you can correlate http request/response/error log entries with you application log entries based on the uid.\n\nPlease review the test suite for further details.\n\n## Tests with code coverage report in `test/coverage`\n\nNote: Requires nodes at least v0.11.13 (earlier v0.11 versions may work, have not checked for this).\n\ngit clone the full repo: `git clone git@github.com:rudijs/koa-json-logger.git`\n\n`cd koa-json-logger`\n\n`npm install`\n\n`npm test`\n\n\n## Code Linting\n\n`npm run lint`\n\n\n## Sample Success Log Entry (pretty print)\n\n\t{\n\t   \"name\":\"rsm-api\",\n\t   \"hostname\":\"dev\",\n\t   \"pid\":30213,\n\t   \"level\":30,\n\t   \"uid\":\"37154307-aed2-4e10-b702-97ed9e7d4a3b\",\n\t   \"req\":{\n\t      \"url\":\"/users/539d77e8cd4e834b710a103a\",\n\t      \"headers\":{\n\t\t \"host\":\"127.0.0.1:3000\",\n\t\t \"connection\":\"keep-alive\",\n\t\t \"cache-control\":\"no-cache\",\n\t\t \"user-agent\":\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36\",\n\t\t \"content-type\":\"application/vnd.api+json\",\n\t\t \"accept\":\"*/*\",\n\t\t \"accept-encoding\":\"gzip,deflate,sdch\",\n\t\t \"accept-language\":\"en-US,en;q=0.8\"\n\t      },\n\t      \"method\":\"GET\",\n\t      \"ip\":\"::ffff:127.0.0.1\",\n\t      \"protocol\":\"http\",\n\t      \"originalUrl\":\"/users/539d77e8cd4e834b710a103a\",\n\t      \"query\":{}\n\t   },\n\t   \"res\":{\n\t      \"statusCode\":200,\n\t      \"responseTime\":15,\n\t      \"headers\":{\n\t\t \"cache-control\":\"no-store, no-cache\",\n\t\t \"x-content-type-options\":\"nosniff\",\n\t\t \"x-download-options\":\"noopen\",\n\t\t \"x-xss-protection\":\"1; mode=block\",\n\t\t \"x-frame-options\":\"DENY\",\n\t\t \"vary\":\"Accept-Encoding\",\n\t\t \"content-type\":\"application/json; charset=utf-8\",\n\t\t \"content-length\":\"66\"\n\t      }\n\t   },\n\t   \"msg\":\"\",\n\t   \"time\":\"2014-08-21T16:24:24.118Z\",\n\t   \"v\":0\n\t}\n\n## Sample Error Log Entry (pretty print)\n\n\t{\n\t   \"name\":\"rsm-api\",\n\t   \"hostname\":\"dev\",\n\t   \"pid\":30213,\n\t   \"level\":50,\n\t   \"uid\":\"ec874d07-dd94-4298-a4c3-8181a6803d4a\",\n\t   \"req\":{\n\t      \"url\":\"/users/539d77e8cd4e834b710a103a\",\n\t      \"headers\":{\n\t\t \"host\":\"127.0.0.1:3000\",\n\t\t \"connection\":\"keep-alive\",\n\t\t \"cache-control\":\"no-cache\",\n\t\t \"user-agent\":\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36\",\n\t\t \"content-type\":\"application/vnd.api+json\",\n\t\t \"accept\":\"*/*\",\n\t\t \"accept-encoding\":\"gzip,deflate,sdch\",\n\t\t \"accept-language\":\"en-US,en;q=0.8\"\n\t      },\n\t      \"method\":\"GET\",\n\t      \"ip\":\"::ffff:127.0.0.1\",\n\t      \"protocol\":\"http\",\n\t      \"originalUrl\":\"/users/539d77e8cd4e834b710a103a\",\n\t      \"query\":{}\n\t   },\n\t   \"res\":{\n\t      \"statusCode\":401,\n\t      \"responseTime\":3,\n\t      \"headers\":{\n\t\t \"cache-control\":\"no-store, no-cache\",\n\t\t \"x-content-type-options\":\"nosniff\",\n\t\t \"x-download-options\":\"noopen\",\n\t\t \"x-xss-protection\":\"1; mode=block\",\n\t\t \"x-frame-options\":\"DENY\",\n\t\t \"vary\":\"Accept-Encoding\"\n\t      }\n\t   },\n\t   \"err\":{\n\t      \"message\":{\n\t\t \"status\":401,\n\t\t \"title\":\"Unauthorized\",\n\t\t \"detail\":\"Please sign in to complete this request.\"\n\t      },\n\t      \"name\":\"Error\",\n\t      \"stack\":\"Error: Unauthorized\\n    at Object.module.exports [as throw] (/media/crypt2/projects/ride-share-market-api/node_modules/koa/lib/context.js:84:48)\\n    at Object.authorization (/media/crypt2/projects/ride-share-market-api/app/middlewares/authorization.js:49:19)\\n    at GeneratorFunctionPrototype.next (native)\\n    at Object.\u003canonymous\u003e (/media/crypt2/projects/ride-share-market-api/node_modules/koa-router/node_modules/koa-compose/index.js:29:12)\\n    at GeneratorFunctionPrototype.next (native)\\n    at next (/media/crypt2/projects/ride-share-market-api/node_modules/koa/node_modules/co/index.js:74:21)\\n    at Object.\u003canonymous\u003e (/media/crypt2/projects/ride-share-market-api/node_modules/koa/node_modules/co/index.js:45:5)\\n    at next (/media/crypt2/projects/ride-share-market-api/node_modules/koa/node_modules/co/index.js:90:21)\\n    at Object.\u003canonymous\u003e (/media/crypt2/projects/ride-share-market-api/node_modules/koa/node_modules/co/index.js:45:5)\\n    at next (/media/crypt2/projects/ride-share-market-api/node_modules/koa/node_modules/co/index.js:90:21)\"\n\t   },\n\t   \"msg\":\"\",\n\t   \"time\":\"2014-08-21T16:26:52.338Z\",\n\t   \"v\":0\n\t}\n\n## Kibana Success Screenshot example:\n\n\n![Kibana Success Screenshot](examples/kibana_success_log_entry.png)\n\n\n## Kibana Error Screenshot example:\n\n\n![Kibana Error Screenshot](examples/kibana_error_log_entry.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudijs%2Fkoa-json-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frudijs%2Fkoa-json-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudijs%2Fkoa-json-logger/lists"}