function compile(format) { if (typeof format !== 'string') { throw new TypeError('argument format must be a string') } var fmt = format.replace(/"/g, '\\"') var js = ' "use strict"\n return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function (_, name, arg) { var tokenArguments = 'req, res' var tokenFunction = 'tokens[' + String(JSON.stringify(name)) + ']' if (arg !== undefined) { tokenArguments += ', ' + String(JSON.stringify(arg)) } return '" +\n (' + tokenFunction + '(' + tokenArguments + ') || "-") + "' }) + '"' // eslint-disable-next-line no-new-func return new Function('tokens, req, res', js) }
...
The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`.
##### :user-agent
The contents of the User-Agent header of the request.
### morgan.compile(format)
Compile a format string into a `format` function for use by `morgan`. A format string
is a string that represents a single log line and can utilize token syntax.
Tokens are references by `:token-name`. If tokens accept arguments, they can
be passed using `[]`, for example: `:token-name[pretty]` would pass the string
`'pretty'` as an argument to the token `token-name`.
...
function getDateToken(req, res, format) { var date = new Date() switch (format || 'web') { case 'clf': return clfdate(date) case 'iso': return date.toISOString() case 'web': return date.toUTCString() } }
n/a
function developmentFormatLine(tokens, req, res) { // get the status code if response written var status = res._header ? res.statusCode : undefined // get status color var color = status >= 500 ? 31 // red : status >= 400 ? 33 // yellow : status >= 300 ? 36 // cyan : status >= 200 ? 32 // green : 0 // no color // get colored function var fn = developmentFormatLine[color] if (!fn) { // compile fn = developmentFormatLine[color] = compile('\x1b[0m:method :url \x1b[' + color + 'm:status \x1b[0m:response-time ms - :res[content-length]\x1b[0m') } return fn(tokens, req, res) }
n/a
function format(name, fmt) { morgan[name] = fmt return this }
...
`'pretty'` as an argument to the token `token-name`.
The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and
`res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and
`res` is the HTTP response. The function will return a string that will be the log line,
or `undefined` / `null` to skip logging.
Normally formats are defined using `morgan.format(name, format)`, but for certain
advanced uses, this compile function is directly available.
## Examples
### express/connect
Simple app that will log all request in the Apache combined format to STDOUT
...
function getHttpVersionToken(req) { return req.httpVersionMajor + '.' + req.httpVersionMinor }
n/a
function getMethodToken(req) { return req.method }
...
#### Using a custom format function
<!-- eslint-disable no-undef -->
``` js
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(' ')
})
```
...
function getReferrerToken(req) { return req.headers['referer'] || req.headers['referrer'] }
n/a
function getip(req) { return req.ip || req._remoteAddress || (req.connection && req.connection.remoteAddress) || undefined }
n/a
function getRemoteUserToken(req) { // parse basic credentials var credentials = auth(req) // return username return credentials ? credentials.name : undefined }
n/a
function getRequestToken(req, res, field) { // get header var header = req.headers[field.toLowerCase()] return Array.isArray(header) ? header.join(', ') : header }
n/a
function getResponseHeader(req, res, field) { if (!res._header) { return undefined } // get header var header = res.getHeader(field) return Array.isArray(header) ? header.join(', ') : header }
...
``` js
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(' ')
})
```
#### Options
...
function getResponseTimeToken(req, res, digits) { if (!req._startAt || !res._startAt) { // missing request and/or response start time return } // calculate diff var ms = (res._startAt[0] - req._startAt[0]) * 1e3 + (res._startAt[1] - req._startAt[1]) * 1e-6 // return truncated value return ms.toFixed(digits === undefined ? 3 : digits) }
n/a
function getStatusToken(req, res) { return res._header ? String(res.statusCode) : undefined }
...
<!-- eslint-disable no-undef -->
``` js
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(' ')
})
```
#### Options
...
function token(name, fn) { morgan[name] = fn return this }
...
:method :url :status :res[content-length] - :response-time ms
```
#### Tokens
##### Creating new tokens
To define a token, simply invoke `morgan.token()` with the name and a callback function
.
This callback function is expected to return a string value. The value returned is then
available as ":type" in this case:
<!-- eslint-disable no-undef -->
```js
morgan.token('type', function (req, res) { return req.headers['content-type'] })
...
function getUrlToken(req) { return req.originalUrl || req.url }
...
<!-- eslint-disable no-undef -->
``` js
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(' ')
})
```
...
function getUserAgentToken(req) { return req.headers['user-agent'] }
n/a