黑人生命也是命。
支持平等正義倡議.

morgan

NPM Version NPM Downloads Build Status Test Coverage

node.js 的 HTTP 要求記錄器中介軟體

Dexter 命名,這是一個你不應該看到結局的節目。

安裝

這是一個 Node.js 模組,可透過 npm 登錄檔 取得。安裝時使用 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 combined 記錄輸出。

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

標準 Apache common 記錄輸出。

: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 值 (socket 位址)。

:remote-user

要求中作為基本認證一部分驗證的使用者。

:req[header]

要求的指定 header。如果沒有標頭,值將在記錄中顯示為 "-"

:res[header]

回應的指定 header。如果沒有標頭,值將在記錄中顯示為 "-"

:response-time[digits]

請求進入 morgan 與回應標頭寫入之間的時間(以毫秒為單位)。

digits 參數是一個數字,用來指定數字中要包含的位數,預設為 3,提供微秒精度。

:status

回應的狀態碼。

如果在將回應傳送給用戶端之前,請求/回應週期完成(例如,當用戶端中止請求時,TCP Socket 提早關閉),則狀態將為空(在記錄中顯示為 "-")。

:total-time[digits]

請求進入 morgan 與回應完成寫入連線之間的時間(以毫秒為單位)。

digits 參數是一個數字,用來指定數字中要包含的位數,預設為 3,提供微秒精度。

:url

請求的 URL。如果存在,則會使用 req.originalUrl,否則會使用 req.url

:user-agent

請求的 User-Agent 標頭內容。

morgan.compile(format)

將格式字串編譯成 format 函數,供 morgan 使用。格式字串是一個代表單一記錄行的字串,可以使用標記語法。標記透過 :token-name 參照。如果標記接受參數,可以使用 [] 傳遞,例如::token-name[pretty] 會將字串 'pretty' 作為參數傳遞給標記 token-name

morgan.compile 傳回的函式會接收三個引數 tokensreqres,其中 tokens 是物件,包含所有已定義的 token,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!')
})

使用自訂 token 格式

範例應用程式會使用自訂 token 格式。這會將 ID 新增到所有要求,並使用 :id token 顯示它。

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