HTTP request logger middleware for Node.js applications
npx @tessl/cli install tessl/npm-morgan@1.10.0Morgan is an HTTP request logger middleware for Node.js applications that provides flexible logging formats, custom token support, and configurable output streams. It offers predefined log formats suitable for development and production environments, along with the ability to create custom logging strategies.
npm install morganconst morgan = require('morgan');ES6 modules (if supported):
import morgan from 'morgan';const express = require('express');
const morgan = require('morgan');
const app = express();
// Use predefined format
app.use(morgan('combined'));
// Custom format string
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
// Custom format function
app.use(morgan((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(' ');
}));
app.get('/', (req, res) => {
res.send('Hello World!');
});Morgan is built around several key components:
morgan() function creates Express/Connect-compatible middlewareCreates HTTP request logger middleware with flexible configuration options.
/**
* Create a new morgan logger middleware function
* @param {string|Function} format - Format name, format string, or custom function
* @param {Object} [options] - Configuration options
* @param {boolean} [options.immediate] - Log on request instead of response
* @param {Function} [options.skip] - Function to determine if logging should be skipped
* @param {WritableStream} [options.stream] - Output stream (defaults to process.stdout)
* @param {number|boolean} [options.buffer] - Deprecated buffering support
* @returns {Function} Express/Connect middleware function
*/
function morgan(format, options);Compiles format strings into executable logging functions.
/**
* Compile a format string into a format function
* @param {string} format - Format string with token syntax
* @returns {Function} Format function that takes (tokens, req, res) and returns log line
* @throws {TypeError} When format is not a string
*/
function compile(format);Defines named formats for reuse across applications.
/**
* Define a format with the given name
* @param {string} name - Format name for later reference
* @param {string|Function} fmt - Format string or function
* @returns {Object} Morgan instance (chainable)
*/
function format(name, fmt);Registers custom token functions for use in format strings.
/**
* Define a token function with the given name
* @param {string} name - Token name for use in format strings
* @param {Function} fn - Token function that receives (req, res, ...args) and returns string
* @returns {Object} Morgan instance (chainable)
*/
function token(name, fn);Standard Apache combined log output with full request and response information.
// Usage
morgan('combined');
// Equivalent format string
':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
// Example output
'::1 - - [27/Nov/2024:06:21:42 +0000] "GET /api/users HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0"'Standard Apache common log output without referrer and user agent.
// Usage
morgan('common');
// Equivalent format string
':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]'
// Example output
'::1 - - [27/Nov/2024:06:21:46 +0000] "GET /api/users HTTP/1.1" 200 1234'Colored output optimized for development with response time information.
// Usage
morgan('dev');
// Equivalent format string with colors
':method :url :status :response-time ms - :res[content-length]'
// Example output (colored)
'GET /api/users 200 4.123 ms - 1234'Compact format including response time and basic request information.
// Usage
morgan('short');
// Equivalent format string
':remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
// Example output
'::1 - GET /api/users HTTP/1.1 200 1234 - 4.123 ms'Minimal output with essential request information.
// Usage
morgan('tiny');
// Equivalent format string
':method :url :status :res[content-length] - :response-time ms'
// Example output
'GET /api/users 200 1234 - 4.123 ms'Legacy default format, equivalent to combined format but with different date formatting. Deprecated in favor of combined format.
// Usage (deprecated)
morgan('default');
// Equivalent format string
':remote-addr - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
// Example output
'::1 - - [Wed, 27 Nov 2024 06:21:42 GMT] "GET /api/users HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0"'/**
* HTTP method of the request
* Usage: :method
*/
function method(req);
/**
* Request URL (uses originalUrl if available, otherwise url)
* Usage: :url
*/
function url(req);
/**
* HTTP version of the request
* Usage: :http-version
*/
function httpVersion(req);
/**
* Remote IP address (uses req.ip, falls back to connection.remoteAddress)
* Usage: :remote-addr
*/
function remoteAddr(req);
/**
* Basic auth username
* Usage: :remote-user
*/
function remoteUser(req);
/**
* User-Agent header value
* Usage: :user-agent
*/
function userAgent(req);
/**
* Referrer header (handles both referer and referrer spellings)
* Usage: :referrer
*/
function referrer(req);
/**
* Request header value
* Usage: :req[header-name]
* @param {string} field - Header name
*/
function req(req, res, field);/**
* HTTP response status code
* Usage: :status
*/
function status(req, res);
/**
* Response header value
* Usage: :res[header-name]
* @param {string} field - Header name
*/
function res(req, res, field);/**
* Response time in milliseconds (from request start to response headers written)
* Usage: :response-time[digits]
* @param {number} [digits=3] - Number of decimal places
*/
function responseTime(req, res, digits);
/**
* Total time in milliseconds (from request start to response complete)
* Usage: :total-time[digits]
* @param {number} [digits=3] - Number of decimal places
*/
function totalTime(req, res, digits);
/**
* Current date in various formats
* Usage: :date[format]
* @param {string} [format='web'] - Date format ('clf', 'iso', 'web')
*/
function date(req, res, format);const express = require('express');
const morgan = require('morgan');
const uuid = require('uuid');
// Define custom token
morgan.token('id', (req) => req.id);
const app = express();
// Assign unique ID to each request
app.use((req, res, next) => {
req.id = uuid.v4();
next();
});
// Use custom token in format
app.use(morgan(':id :method :url :response-time'));const fs = require('fs');
const path = require('path');
// Log only errors to console
app.use(morgan('dev', {
skip: (req, res) => res.statusCode < 400
}));
// Log all requests to file
app.use(morgan('combined', {
stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })
}));app.use(morgan((tokens, req, res) => {
const log = {
timestamp: new Date().toISOString(),
method: tokens.method(req, res),
url: tokens.url(req, res),
status: tokens.status(req, res),
responseTime: tokens['response-time'](req, res),
userAgent: tokens['user-agent'](req, res)
};
return JSON.stringify(log);
}));/**
* Morgan middleware function signature
* @callback MiddlewareFunction
* @param {IncomingMessage} req - HTTP request object
* @param {ServerResponse} res - HTTP response object
* @param {Function} next - Next middleware function
*/
/**
* Format function signature
* @callback FormatFunction
* @param {Object} tokens - Object containing all defined tokens
* @param {IncomingMessage} req - HTTP request object
* @param {ServerResponse} res - HTTP response object
* @returns {string|null|undefined} Log line or null/undefined to skip
*/
/**
* Token function signature
* @callback TokenFunction
* @param {IncomingMessage} req - HTTP request object
* @param {ServerResponse} res - HTTP response object
* @param {...any} args - Additional arguments from token usage
* @returns {string|undefined} Token value or undefined for default
*/
/**
* Skip function signature
* @callback SkipFunction
* @param {IncomingMessage} req - HTTP request object
* @param {ServerResponse} res - HTTP response object
* @returns {boolean} True to skip logging, false to log
*/
/**
* Morgan options interface
* @typedef {Object} MorganOptions
* @property {boolean} [immediate] - Log on request instead of response
* @property {SkipFunction} [skip] - Function to determine if logging should be skipped
* @property {WritableStream} [stream] - Output stream for log lines
* @property {number|boolean} [buffer] - Deprecated buffering support
*/