黑人的命也是命。
支持平等司法倡议.

morgan

NPM Version NPM Downloads Build Status Test Coverage

用于 node.js 的 HTTP 请求日志记录中间件

Dexter 命名,这是一部你应该在看完之后再看的节目。

安装

这是一个通过 npm 注册表 可用的 Node.js 模块。安装使用 npm install 命令 完成

$ npm install morgan

API

var morgan = require('morgan')

morgan(format, options)

使用给定的 formatoptions 创建一个新的 morgan 日志记录中间件函数。format 参数可以是预定义名称的字符串(请参阅下面的名称)、格式字符串的字符串或将生成日志条目的函数。

format 函数将使用三个参数 tokensreqres 调用,其中 tokens 是一个包含所有定义的标记的对象,req 是 HTTP 请求,res 是 HTTP 响应。该函数应返回一个字符串,该字符串将是日志行,或返回 undefined / null 以跳过日志记录。

使用预定义的格式字符串

morgan('tiny')

使用预定义标记的格式字符串

morgan(':method :url :status :res[content-length] - :response-time ms')

使用自定义格式函数

morgan(function (tokens, req, res) {
  return [
    tokens.method(req, res),
    tokens.url(req, res),
    tokens.status(req, res),
    tokens.res(req, res, 'content-length'), '-',
    tokens['response-time'](req, res), 'ms'
  ].join(' ')
})

选项

Morgan 在选项对象中接受以下属性。

immediate

在请求而不是响应时写入日志行。这意味着即使服务器崩溃,请求也会被记录,但无法记录来自响应的数据(如响应代码、内容长度等)

skip

用于确定是否跳过日志记录的函数,默认为 false。此函数将以 skip(req, res) 的形式调用。

// EXAMPLE: only log error responses
morgan('combined', {
  skip: function (req, res) { return res.statusCode < 400 }
})
stream

用于写入日志行的输出流,默认为 process.stdout

预定义格式

提供了各种预定义格式

combined

标准 Apache 组合日志输出。

:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
common

标准 Apache 通用日志输出。

:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
dev

简洁的输出,根据响应状态进行颜色区分,用于开发使用。:status 标记将根据成功代码显示绿色,服务器错误代码显示红色,客户端错误代码显示黄色,重定向代码显示青色,信息代码显示无色。

:method :url :status :response-time ms - :res[content-length]
short

比默认值更短,还包括响应时间。

:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
tiny

最小的输出。

:method :url :status :res[content-length] - :response-time ms

标记

创建新标记

要定义一个标记,只需使用名称和回调函数调用 morgan.token()。此回调函数应返回一个字符串值。返回的值在此情况下将作为“:type”使用

morgan.token('type', function (req, res) { return req.headers['content-type'] })

使用与现有标记相同的名称调用 morgan.token() 将覆盖该标记定义。

标记函数应使用参数 reqres 调用,分别代表 HTTP 请求和 HTTP 响应。此外,标记可以接受其选择的其他参数来定制行为。

:date[format]

UTC 中的当前日期和时间。可用的格式为

  • clf 用于通用日志格式 ("10/Oct/2000:13:55:36 +0000")
  • iso 用于通用 ISO 8601 日期时间格式 (2000-10-10T13:55:36.000Z)
  • web 用于通用 RFC 1123 日期时间格式 (Tue, 10 Oct 2000 13:55:36 GMT)

如果未提供格式,则默认值为 web

:http-version

请求的 HTTP 版本。

:method

请求的 HTTP 方法。

:referrer

请求的 Referrer 头部。如果存在,将使用标准的拼写错误的 Referer 头部,否则使用 Referrer。

:remote-addr

请求的远程地址。这将使用 req.ip,否则使用标准的 req.connection.remoteAddress 值(套接字地址)。

:remote-user

作为请求的基本身份验证的一部分进行身份验证的用户。

:req[header]

请求的给定 header。如果头部不存在,则该值将在日志中显示为 "-"

:res[header]

响应的给定 header。如果头部不存在,则该值将在日志中显示为 "-"

:response-time[digits]

请求进入 morgan 到响应头写入完成之间的时间,以毫秒为单位。

digits 参数是一个数字,指定要包含在数字上的位数,默认为 3,提供微秒精度。

:status

响应的状态码。

如果请求/响应周期在向客户端发送响应之前完成(例如,TCP 套接字被客户端中止请求提前关闭),则状态将为空(在日志中显示为 "-")。

:total-time[digits]

请求进入 morgan 到响应完成写入连接之间的时间,以毫秒为单位。

digits 参数是一个数字,指定要包含在数字上的位数,默认为 3,提供微秒精度。

:url

请求的 URL。如果存在,这将使用 req.originalUrl,否则使用 req.url

:user-agent

请求的 User-Agent 头部的内容。

morgan.compile(format)

将格式字符串编译成 morgan 使用的 format 函数。格式字符串是一个表示单个日志行的字符串,可以使用标记语法。标记通过 :token-name 引用。如果标记接受参数,则可以使用 [] 传递它们,例如::token-name[pretty] 将字符串 'pretty' 作为参数传递给标记 token-name

morgan.compile 返回的函数接受三个参数 tokensreqres,其中 tokens 是包含所有定义的标记的对象,req 是 HTTP 请求,res 是 HTTP 响应。该函数将返回一个字符串,该字符串将作为日志行,或者返回 undefined / null 以跳过日志记录。

通常,格式是使用 morgan.format(name, format) 定义的,但对于某些高级用途,此编译函数可以直接使用。

示例

express/connect

将所有请求以 Apache 组合格式记录到 STDOUT 的示例应用程序

var express = require('express')
var morgan = require('morgan')

var app = express()

app.use(morgan('combined'))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

普通 http 服务器

将所有请求以 Apache 组合格式记录到 STDOUT 的示例应用程序

var finalhandler = require('finalhandler')
var http = require('http')
var morgan = require('morgan')

// create "middleware"
var logger = morgan('combined')

http.createServer(function (req, res) {
  var done = finalhandler(req, res)
  logger(req, res, function (err) {
    if (err) return done(err)

    // respond to request
    res.setHeader('content-type', 'text/plain')
    res.end('hello, world!')
  })
})

将日志写入文件

单个文件

将所有请求以 Apache 组合格式记录到 access.log 文件的示例应用程序。

var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')

var app = express()

// create a write stream (in append mode)
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })

// setup the logger
app.use(morgan('combined', { stream: accessLogStream }))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

日志文件轮转

将所有请求以 Apache 组合格式记录到 log/ 目录中每天一个日志文件的示例应用程序,使用 rotating-file-stream 模块

var express = require('express')
var morgan = require('morgan')
var path = require('path')
var rfs = require('rotating-file-stream') // version 2.x

var app = express()

// create a rotating write stream
var accessLogStream = rfs.createStream('access.log', {
  interval: '1d', // rotate daily
  path: path.join(__dirname, 'log')
})

// setup the logger
app.use(morgan('combined', { stream: accessLogStream }))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

拆分/双重日志记录

morgan 中间件可以根据需要使用多次,从而实现以下组合:

  • 在请求和响应时记录条目
  • 将所有请求记录到文件,但将错误记录到控制台
  • … 等等!

将所有请求以 Apache 格式记录到文件的示例应用程序,但将错误响应记录到控制台

var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')

var app = express()

// log only 4xx and 5xx responses to console
app.use(morgan('dev', {
  skip: function (req, res) { return res.statusCode < 400 }
}))

// log all requests to access.log
app.use(morgan('common', {
  stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })
}))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

使用自定义标记格式

将使用自定义标记格式的示例应用程序。这将为所有请求添加一个 ID,并使用 :id 标记显示它。

var express = require('express')
var morgan = require('morgan')
var uuid = require('node-uuid')

morgan.token('id', function getId (req) {
  return req.id
})

var app = express()

app.use(assignId)
app.use(morgan(':id :method :url :response-time'))

app.get('/', function (req, res) {
  res.send('hello, world!')
})

function assignId (req, res, next) {
  req.id = uuid.v4()
  next()
}

许可证

MIT