morgan 基于 NodeJS 的 HTTP 请求日志中间件 - 文章教程

morgan 基于 NodeJS 的 HTTP 请求日志中间件

发布于 2021-08-11 字数 10362 浏览 1108 评论 0

node.js 的 HTTP 请求记录器中间件。

德克斯特的名字命名,一部你不应该在完成之前观看的节目。

安装

这是一个 Node.js 模块,可通过 npm registry 获得。安装是使用以下 npm install 命令完成的 :

$ npm install morgan

应用程序接口

var morgan = require('morgan')

morgan(format, options)

使用给定的format和创建一个新的摩根记录器中间件函数options。该format参数可以是一个预定义的名字的字符串(参见下面的名字),格式串一串,或将产生日志条目的功能。

format将使用三个参数tokensreq和调用该函数res,其中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

Tokens

Creating new tokens

要定义令牌,只需 morgan.token() 使用名称和回调函数进行调用。此回调函数应返回一个字符串值。在这种情况下,返回的值可以作为 :type 使用:

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

morgan.token() 使用与现有令牌相同的名称进行调用将覆盖该令牌定义。

令牌函数应使用参数 req and 调用 res,代表 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.originalUrlif 存在,否则使用req.url

:user-agent

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

morgan.compile(format)

将格式字符串编译为format函数以供morgan. 格式字符串是表示单个日志行并且可以使用令牌语法的字符串。令牌是由:token-name. 如果令牌接受参数,则可以使用 传递它们[],例如::token-name[pretty]将字符串 'pretty'作为参数传递给令牌token-name

from 返回的函数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!')
})

vanilla http server

将以 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!')
})

日志文件轮换

示例应用程序将每天 log/ 使用 旋转文件流模块 将 Apache 组合格式的所有请求记录到目录 中的一个日志文件中。

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()
}

项目地址:https://github.com/expressjs/morgan

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!