[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10186":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":18,"lastSyncTime":33,"discoverSource":34},10186,"morgan","expressjs\u002Fmorgan","expressjs","HTTP request logger middleware for node.js","",null,"JavaScript",8179,552,83,15,0,1,2,6,4,67.83,"MIT License",false,"master",[26,27,28,29],"express","javascript","logger","nodejs","2026-06-12 04:00:49","# morgan\n\n[![NPM Version][npm-version-image]][npm-url]\n[![NPM Downloads][npm-downloads-image]][npm-url]\n[![Build Status][ci-image]][ci-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n\nHTTP request logger middleware for node.js\n\n> Named after [Dexter](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDexter_Morgan), a show you should not watch until completion.\n\n## Installation\n\nThis is a [Node.js](https:\u002F\u002Fnodejs.org\u002Fen\u002F) module available through the\n[npm registry](https:\u002F\u002Fwww.npmjs.com\u002F). Installation is done using the\n[`npm install` command](https:\u002F\u002Fdocs.npmjs.com\u002Fgetting-started\u002Finstalling-npm-packages-locally):\n\n```sh\n$ npm install morgan\n```\n\n## API\n\n\u003C!-- eslint-disable no-unused-vars -->\n\n```js\nvar morgan = require('morgan')\n```\n\n### morgan(format, options)\n\nCreate a new morgan logger middleware function using the given `format` and `options`.\nThe `format` argument may be a string of a predefined name (see below for the names),\na string of a format string, or a function that will produce a log entry.\n\nThe `format` function will be called with three arguments `tokens`, `req`, and `res`,\nwhere `tokens` is an object with all defined tokens, `req` is the HTTP request and `res`\nis the HTTP response. The function is expected to return a string that will be the log\nline, or `undefined` \u002F `null` to skip logging.\n\n#### Using a predefined format string\n\n\u003C!-- eslint-disable no-undef -->\n\n```js\nmorgan('tiny')\n```\n\n#### Using format string of predefined tokens\n\n\u003C!-- eslint-disable no-undef -->\n\n```js\nmorgan(':method :url :status :res[content-length] - :response-time ms')\n```\n\n#### Using a custom format function\n\n\u003C!-- eslint-disable no-undef -->\n\n``` js\nmorgan(function (tokens, req, res) {\n  return [\n    tokens.method(req, res),\n    tokens.url(req, res),\n    tokens.status(req, res),\n    tokens.res(req, res, 'content-length'), '-',\n    tokens['response-time'](req, res), 'ms'\n  ].join(' ')\n})\n```\n\n#### Options\n\nMorgan accepts these properties in the options object.\n\n##### immediate\n\nWrite log line on request instead of response. This means that a requests will\nbe logged even if the server crashes, _but data from the response (like the\nresponse code, content length, etc.) cannot be logged_.\n\n##### skip\n\nFunction to determine if logging is skipped, defaults to `false`. This function\nwill be called as `skip(req, res)`.\n\n\u003C!-- eslint-disable no-undef -->\n\n```js\n\u002F\u002F EXAMPLE: only log error responses\nmorgan('combined', {\n  skip: function (req, res) { return res.statusCode \u003C 400 }\n})\n```\n\n##### stream\n\nOutput stream for writing log lines, defaults to `process.stdout`.\n\n#### Predefined Formats\n\nThere are various pre-defined formats provided:\n\n##### combined\n\nStandard Apache combined log output.\n```\n:remote-addr - :remote-user [:date[clf]] \":method :url HTTP\u002F:http-version\" :status :res[content-length] \":referrer\" \":user-agent\"\n# will output\n::1 - - [27\u002FNov\u002F2024:06:21:42 +0000] \"GET \u002Fcombined HTTP\u002F1.1\" 200 2 \"-\" \"curl\u002F8.7.1\"\n```\n\n##### common\n\nStandard Apache common log output.\n\n```\n:remote-addr - :remote-user [:date[clf]] \":method :url HTTP\u002F:http-version\" :status :res[content-length]\n# will output\n::1 - - [27\u002FNov\u002F2024:06:21:46 +0000] \"GET \u002Fcommon HTTP\u002F1.1\" 200 2\n```\n\n##### dev\n\nConcise output colored by response status for development use. The `:status`\ntoken will be colored green for success codes, red for server error codes,\nyellow for client error codes, cyan for redirection codes, and uncolored\nfor information codes.\n\n```\n:method :url :status :response-time ms - :res[content-length]\n# will output\nGET \u002Fdev 200 0.224 ms - 2\n```\n\n##### short\n\nShorter than default, also including response time.\n\n```\n:remote-addr :remote-user :method :url HTTP\u002F:http-version :status :res[content-length] - :response-time ms\n# will output\n::1 - GET \u002Fshort HTTP\u002F1.1 200 2 - 0.283 ms\n```\n\n##### tiny\n\nThe minimal output.\n\n```\n:method :url :status :res[content-length] - :response-time ms\n# will output\nGET \u002Ftiny 200 2 - 0.188 ms\n```\n\n#### Tokens\n\n##### Creating new tokens\n\nTo define a token, simply invoke `morgan.token()` with the name and a callback function.\nThis callback function is expected to return a string value. The value returned is then\navailable as \":type\" in this case:\n\n\u003C!-- eslint-disable no-undef -->\n\n```js\nmorgan.token('type', function (req, res) { return req.headers['content-type'] })\n```\n\nCalling `morgan.token()` using the same name as an existing token will overwrite that\ntoken definition.\n\nThe token function is expected to be called with the arguments `req` and `res`, representing\nthe HTTP request and HTTP response. Additionally, the token can accept further arguments of\nit's choosing to customize behavior.\n\n##### :date[format]\n\nThe current date and time in UTC. The available formats are:\n\n  - `clf` for the common log format (`\"10\u002FOct\u002F2000:13:55:36 +0000\"`)\n  - `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`)\n  - `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`)\n\nIf no format is given, then the default is `web`.\n\n##### :http-version\n\nThe HTTP version of the request.\n\n##### :method\n\nThe HTTP method of the request.\n\n##### :pid\n\nThe process ID of the Node.js process handling the request.\n\n##### :referrer\n\nThe Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer.\n\n##### :remote-addr\n\nThe remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address).\n\n##### :remote-user\n\nThe user authenticated as part of Basic auth for the request.\n\n##### :req[header]\n\nThe given `header` of the request. If the header is not present, the\nvalue will be displayed as `\"-\"` in the log.\n\n##### :res[header]\n\nThe given `header` of the response. If the header is not present, the\nvalue will be displayed as `\"-\"` in the log.\n\n##### :response-time[digits]\n\nThe time between the request coming into `morgan` and when the response\nheaders are written, in milliseconds.\n\nThe `digits` argument is a number that specifies the number of digits to\ninclude on the number, defaulting to `3`, which provides microsecond precision.\n\n##### :status\n\nThe status code of the response.\n\nIf the request\u002Fresponse cycle completes before a response was sent to the\nclient (for example, the TCP socket closed prematurely by a client aborting\nthe request), then the status will be empty (displayed as `\"-\"` in the log).\n\n##### :total-time[digits]\n\nThe time between the request coming into `morgan` and when the response\nhas finished being written out to the connection, in milliseconds.\n\nThe `digits` argument is a number that specifies the number of digits to\ninclude on the number, defaulting to `3`, which provides microsecond precision.\n\n##### :url\n\nThe URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.\n\n##### :user-agent\n\nThe contents of the User-Agent header of the request.\n\n### morgan.compile(format)\n\nCompile a format string into a `format` function for use by `morgan`. A format string\nis a string that represents a single log line and can utilize token syntax.\nTokens are references by `:token-name`. If tokens accept arguments, they can\nbe passed using `[]`, for example: `:token-name[pretty]` would pass the string\n`'pretty'` as an argument to the token `token-name`.\n\nThe function returned from `morgan.compile` takes three arguments `tokens`, `req`, and\n`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and\n`res` is the HTTP response. The function will return a string that will be the log line,\nor `undefined` \u002F `null` to skip logging.\n\nNormally formats are defined using `morgan.format(name, format)`, but for certain\nadvanced uses, this compile function is directly available.\n\n## Examples\n\n### express\u002Fconnect\n\nSample app that will log all request in the Apache combined format to STDOUT\n\n```js\nvar express = require('express')\nvar morgan = require('morgan')\n\nvar app = express()\n\napp.use(morgan('combined'))\n\napp.get('\u002F', function (req, res) {\n  res.send('hello, world!')\n})\n```\n\n### vanilla http server\n\nSample app that will log all request in the Apache combined format to STDOUT\n\n```js\nvar finalhandler = require('finalhandler')\nvar http = require('http')\nvar morgan = require('morgan')\n\n\u002F\u002F create \"middleware\"\nvar logger = morgan('combined')\n\nhttp.createServer(function (req, res) {\n  var done = finalhandler(req, res)\n  logger(req, res, function (err) {\n    if (err) return done(err)\n\n    \u002F\u002F respond to request\n    res.setHeader('content-type', 'text\u002Fplain')\n    res.end('hello, world!')\n  })\n})\n```\n\n### write logs to a file\n\n#### single file\n\nSample app that will log all requests in the Apache combined format to the file\n`access.log`.\n\n```js\nvar express = require('express')\nvar fs = require('fs')\nvar morgan = require('morgan')\nvar path = require('path')\n\nvar app = express()\n\n\u002F\u002F create a write stream (in append mode)\nvar accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })\n\n\u002F\u002F setup the logger\napp.use(morgan('combined', { stream: accessLogStream }))\n\napp.get('\u002F', function (req, res) {\n  res.send('hello, world!')\n})\n```\n\n#### log file rotation\n\nSample app that will log all requests in the Apache combined format to one log\nfile per day in the `log\u002F` directory using the\n[rotating-file-stream module](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Frotating-file-stream).\n\n```js\nvar express = require('express')\nvar morgan = require('morgan')\nvar path = require('path')\nvar rfs = require('rotating-file-stream') \u002F\u002F version 2.x\n\nvar app = express()\n\n\u002F\u002F create a rotating write stream\nvar accessLogStream = rfs.createStream('access.log', {\n  interval: '1d', \u002F\u002F rotate daily\n  path: path.join(__dirname, 'log')\n})\n\n\u002F\u002F setup the logger\napp.use(morgan('combined', { stream: accessLogStream }))\n\napp.get('\u002F', function (req, res) {\n  res.send('hello, world!')\n})\n```\n\n### split \u002F dual logging\n\nThe `morgan` middleware can be used as many times as needed, enabling\ncombinations like:\n\n  * Log entry on request and one on response\n  * Log all requests to file, but errors to console\n  * ... and more!\n\nSample app that will log all requests to a file using Apache format, but\nerror responses are logged to the console:\n\n```js\nvar express = require('express')\nvar fs = require('fs')\nvar morgan = require('morgan')\nvar path = require('path')\n\nvar app = express()\n\n\u002F\u002F log only 4xx and 5xx responses to console\napp.use(morgan('dev', {\n  skip: function (req, res) { return res.statusCode \u003C 400 }\n}))\n\n\u002F\u002F log all requests to access.log\napp.use(morgan('common', {\n  stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })\n}))\n\napp.get('\u002F', function (req, res) {\n  res.send('hello, world!')\n})\n```\n\n### use custom token formats\n\nSample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token.\n\n```js\nvar express = require('express')\nvar morgan = require('morgan')\nvar uuid = require('node-uuid')\n\nmorgan.token('id', function getId (req) {\n  return req.id\n})\n\nvar app = express()\n\napp.use(assignId)\napp.use(morgan(':id :method :url :response-time'))\n\napp.get('\u002F', function (req, res) {\n  res.send('hello, world!')\n})\n\nfunction assignId (req, res, next) {\n  req.id = uuid.v4()\n  next()\n}\n```\n\n## License\n\n[MIT](LICENSE)\n\n[ci-image]: https:\u002F\u002Fbadgen.net\u002Fgithub\u002Fchecks\u002Fexpressjs\u002Fmorgan\u002Fmaster?label=ci\n[ci-url]: https:\u002F\u002Fgithub.com\u002Fexpressjs\u002Fmorgan\u002Factions\u002Fworkflows\u002Fci.yml\n[coveralls-image]: https:\u002F\u002Fbadgen.net\u002Fcoveralls\u002Fc\u002Fgithub\u002Fexpressjs\u002Fmorgan\u002Fmaster\n[coveralls-url]: https:\u002F\u002Fcoveralls.io\u002Fr\u002Fexpressjs\u002Fmorgan?branch=master\n[npm-downloads-image]: https:\u002F\u002Fbadgen.net\u002Fnpm\u002Fdm\u002Fmorgan\n[npm-url]: https:\u002F\u002Fnpmjs.org\u002Fpackage\u002Fmorgan\n[npm-version-image]: https:\u002F\u002Fbadgen.net\u002Fnpm\u002Fv\u002Fmorgan\n","morgan 是一个用于 Node.js 的 HTTP 请求日志记录中间件。它支持多种预定义的日志格式（如 combined 和 common）以及自定义格式，用户可以通过简单的配置来调整输出内容。morgan 允许开发者通过设置选项来自定义日志的输出流、决定是否跳过某些请求的日志记录等，提供了极大的灵活性。适用于需要对 Web 应用访问情况进行监控和分析的各种场景，尤其是基于 Express 框架构建的应用程序。","2026-06-11 03:27:03","top_topic"]