### Install Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Install the Morgan package using npm. ```bash npm install morgan ``` -------------------------------- ### Install Morgan Middleware Source: https://github.com/expressjs/morgan/blob/master/README.md Install the morgan package using npm. This is the first step to integrate request logging into your Node.js application. ```sh $ npm install morgan ``` -------------------------------- ### Response Time Token Examples Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Demonstrates the usage of the :response-time token with different precision arguments. ```javascript morgan(':method :url :response-time ms') ``` ```javascript morgan(':method :url :response-time[0] ms') ``` ```javascript morgan(':method :url :response-time[5] ms') ``` -------------------------------- ### Use Predefined Format 'tiny' Source: https://github.com/expressjs/morgan/blob/master/README.md Initialize Morgan with the 'tiny' predefined format for minimal logging output. This is a quick way to start logging requests. ```js morgan('tiny') ``` -------------------------------- ### Total Time Token Examples Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Shows how to log both response header time and total elapsed time using :response-time and :total-time tokens. ```javascript morgan(':method :url :total-time ms') ``` ```javascript morgan(':response-time ms (total: :total-time ms)') ``` -------------------------------- ### Basic Usage with Predefined Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Log all requests using the Apache combined format. This is a common starting point for logging. ```javascript const express = require('express') const morgan = require('morgan') const app = express() // Log all requests using Apache combined format app.use(morgan('combined')) app.get('/', (req, res) => { res.send('Hello World') }) app.listen(3000) ``` -------------------------------- ### Timing Integration with onHeaders and onFinished Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Illustrates how Morgan uses the `on-headers` and `on-finished` npm modules to record request start times and log requests after they are fully completed, respectively. ```javascript onHeaders(res, recordStartTime) // Calls recordStartTime() which sets res._startAt onFinished(res, logRequest) // Calls logRequest() after response transmission complete ``` -------------------------------- ### Use Custom Format Function Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This example illustrates the most flexible way to extend Morgan by providing a custom format function. This gives complete control over the output formatting logic. ```javascript morgan((tokens, req, res) => { return JSON.stringify({...}) }) ``` -------------------------------- ### Custom Token and Format Chaining Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Register custom tokens and formats using chaining. This example defines 'id' and 'user' tokens and then uses them to create a 'custom' format for Morgan. ```javascript morgan .token('id', (req) => req.id) .token('user', (req) => req.user?.id) .format('custom', ':id :user :method :url') app.use(morgan('custom')) ``` -------------------------------- ### Deprecated Buffer Option Example Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Demonstrates the usage of the deprecated `buffer` option for buffering log output. This option is not recommended for new code. ```javascript // Deprecated - don't use app.use(morgan('combined', { buffer: 1000 // milliseconds })) ``` -------------------------------- ### Date Token Examples (CLF) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the current date and time in the Common Log Format (CLF) using the :date[clf] token. ```javascript morgan(':date[clf]') ``` -------------------------------- ### Log Request Method and URL Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Logs the HTTP method and URL of the request. This is a basic setup for request logging. ```javascript morgan(':method :url') // GET /api/users ``` -------------------------------- ### Date Token Examples (ISO) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the current date and time in ISO 8601 format using the :date[iso] token. This format is machine-readable and sortable. ```javascript morgan(':date[iso]') ``` -------------------------------- ### Deprecated morgan(options) Form Example Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Shows the deprecated way of calling Morgan with only an options object. The modern approach uses `morgan('format', { options })`. ```javascript // Deprecated form - don't use app.use(morgan({ format: 'combined', stream: accessLog })) // Modern form - use this instead app.use(morgan('combined', { stream: accessLog })) ``` -------------------------------- ### Common Log Format Date Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Example of the Common Log Format for date and time. ```text 10/Oct/2000:13:55:36 +0000 ``` -------------------------------- ### Vanilla HTTP Server with Combined Log Format Source: https://github.com/expressjs/morgan/blob/master/README.md This example shows how to use Morgan with the 'combined' format for logging requests in a vanilla Node.js HTTP server. It requires the 'finalhandler' package for error handling. The logger middleware is applied before the response is sent. ```javascript 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!') }) }) ``` -------------------------------- ### RFC 1123 Date Format (Default) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Example of the RFC 1123 date time format, which is the default for Morgan. ```text Tue, 10 Oct 2000 13:55:36 GMT ``` -------------------------------- ### ISO 8601 Date Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Example of the ISO 8601 date time format. ```text 2000-10-10T13:55:36.000Z ``` -------------------------------- ### Add Custom Token Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This example demonstrates how to add a custom token to Morgan for including application-specific data in logs. This custom token can then be used within existing Morgan formats. ```javascript morgan.token('user-id', (req, res) => req.user?.id) ``` -------------------------------- ### Express App with Combined Log Format Source: https://github.com/expressjs/morgan/blob/master/README.md This snippet demonstrates how to use Morgan with the 'combined' format for logging all requests to STDOUT in an Express application. Ensure 'morgan' is installed. ```javascript var express = require('express') var morgan = require('morgan') var app = express() app.use(morgan('combined')) app.get('/', function (req, res) { res.send('hello, world!') }) ``` -------------------------------- ### Response Time Calculation (Milliseconds) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md These code examples demonstrate how Morgan calculates the elapsed time in milliseconds for the ':response-time' and ':total-time' tokens, utilizing the high-resolution timing data stored on request and response objects. ```javascript // Calculate milliseconds between req start and res headers sent var ms = (res._startAt[0] - req._startAt[0]) * 1e3 + (res._startAt[1] - req._startAt[1]) * 1e-6 // Example: [2, 500000] - [1, 600000] // = 1 * 1000 + (500000 - 600000) * 1e-6 // = 1000 - 0.1 = 999.9 ms ``` ```javascript // Calculate milliseconds from req start to now var elapsed = process.hrtime(req._startAt) var ms = (elapsed[0] * 1e3) + (elapsed[1] * 1e-6) ``` -------------------------------- ### Custom CloudWatch Logs Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Configure Morgan to output logs in a format suitable for AWS CloudWatch. This example uses a simple string template and directs output to stdout. ```javascript morgan.format('cloudwatch', (tokens, req, res) => { return `[${new Date().toISOString()}] ${tokens.method(req, res)} ${tokens.url(req, res)} ${tokens.status(req, res)} ${tokens['response-time'](req, res)}ms` }) app.use(morgan('cloudwatch', { stream: process.stdout // CloudWatch reads from stdout })) ``` -------------------------------- ### Date Token Examples (Web/RFC 1123) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the current date and time in the web (RFC 1123) format using the :date[web] token. This is the default format if no argument is provided. ```javascript morgan(':date[web]') ``` ```javascript morgan(':date') ``` -------------------------------- ### Registering Predefined Named Formats Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Morgan allows for the registration of predefined named formats using the `morgan.format` function. This example shows how to register a format named 'combined'. ```javascript morgan.format('combined', ':remote-addr - :remote-user ...') ``` -------------------------------- ### Write Log Line to Stream Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Morgan writes log entries to a provided stream, typically buffered. This example shows the basic stream write operation. The write is asynchronous and does not wait for completion. ```javascript stream.write(line + '\n') ``` -------------------------------- ### Mocking Morgan Middleware in Tests Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Mock the Morgan middleware using Jest to verify that it is called with the correct arguments. This is useful for testing application setup. ```javascript jest.mock('morgan', () => { return jest.fn(() => (req, res, next) => next()) }) const morgan = require('morgan') test('app includes morgan middleware', () => { require('./app') expect(morgan).toHaveBeenCalledWith('combined') }) ``` -------------------------------- ### Import and Basic Usage of Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Demonstrates how to import Morgan and use it with predefined formats, custom format strings, custom format functions, and options for writing logs to a file. ```javascript const morgan = require('morgan') const app = require('express')() // Use with predefined format app.use(morgan('combined')) // Use with custom format string app.use(morgan(':method :url :status :response-time ms')) // Use with custom format function app.use(morgan((tokens, req, res) => { return `${tokens.method(req, res)} ${tokens.url(req, res)}` })) // Use with options app.use(morgan('combined', { stream: fs.createWriteStream('access.log') })) ``` -------------------------------- ### Morgan Options Configuration Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Illustrates common configuration options for Morgan middleware, including 'immediate', 'skip', and 'stream'. ```javascript morgan(format, { immediate: false, // Log on request vs. response skip: (req, res) => false, // Condition to skip logging stream: process.stdout // Output destination }) ``` -------------------------------- ### Morgan API: Create Middleware Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Shows how to create a Morgan middleware instance with a specified format and options, then apply it to an Express application. ```javascript const middleware = morgan('combined', { stream: logFile }) app.use(middleware) ``` -------------------------------- ### Basic Token Usage Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Demonstrates the basic usage of predefined tokens like ':method', ':url', and ':status' within a Morgan format string. ```javascript morgan(':method :url :status') // Uses method, url, status tokens ``` -------------------------------- ### Middleware Creation Flow Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This diagram outlines the steps involved when the morgan function is called to create a middleware function. It covers parsing the format and options, obtaining the format function, and setting up the stream. ```text morgan(format, options) ↓ Parse format argument (could be options object) ↓ Parse options object ↓ Get format function (lookup by name or compile string) ↓ Create stream (or use provided stream) ↓ Return middleware function ``` -------------------------------- ### Skipping Certain Requests Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Configure the logger to skip logging for specific requests based on a condition. This example logs only errors (status code 400 or higher). ```javascript const morgan = require('morgan') // Only log requests with status 400 or higher (errors) const logger = morgan('combined', { skip: (req, res) => res.statusCode < 400 }) app.use(logger) ``` -------------------------------- ### Common Pattern: Log to File Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Configures Morgan to write all access logs to a specified file, appending to the file if it already exists. ```javascript const fs = require('fs') const path = require('path') const logStream = fs.createWriteStream( path.join(__dirname, 'access.log'), { flags: 'a' } ) app.use(morgan('combined', { stream: logStream })) ``` -------------------------------- ### Multiple Loggers with Different Streams and Filters Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Set up multiple Morgan instances to log all requests to one file and only errors to the console, demonstrating flexible routing of log output. ```javascript // All requests to file app.use(morgan('combined', { stream: fs.createWriteStream('all-requests.log', { flags: 'a' }) })) // Only errors to console app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400 })) ``` -------------------------------- ### Morgan API: Compile Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Demonstrates compiling a format string into a function that can be used to generate log output. ```javascript const formatFn = morgan.compile(':method :url :status') const output = formatFn(morgan, req, res) ``` -------------------------------- ### Log to File Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Configure Morgan to write all access logs to a file named 'access.log'. The 'a' flag ensures logs are appended. ```javascript const fs = require('fs') app.use(morgan('combined', { stream: fs.createWriteStream('access.log', { flags: 'a' }) })) ``` -------------------------------- ### Define Custom Token for Request Method Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Create a custom token to log the HTTP request method (GET, POST, etc.). This is useful for detailed request logging. ```javascript morgan.token('custom-method', (req, res) => { return req.method // GET, POST, PUT, DELETE, etc. }) ``` -------------------------------- ### Request/Response Logging Flow Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This diagram illustrates the sequence of events when the middleware function returned by morgan() is invoked for a request. It details the timing initialization, address recording, and the conditional logging based on the 'immediate' option. ```text middleware(req, res, next) ↓ Initialize timing properties on req/res Record remote address ↓ Record request start time via recordStartTime() ↓ If immediate: true → Call formatLine() and write immediately Else (normal mode) → Wait for response headers via onHeaders() → Wait for response finish via onFinished() → Then call formatLine() and write ↓ Call next() ``` -------------------------------- ### Morgan Token with Argument Usage Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Shows how to use Morgan tokens that accept arguments, such as formatting the date or accessing request headers. ```javascript morgan(':date[iso] :req[authorization]') ``` -------------------------------- ### Immediate Mode Logging Logic Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Shows the conditional logic for Morgan's `immediate: true` option. When enabled, logging occurs before response headers are sent, allowing capture of request data even if the server crashes. ```javascript if (immediate) { // Log immediately logRequest() } else { // Wait for response and headers onHeaders(res, recordStartTime) onFinished(res, logRequest) } ``` -------------------------------- ### Dual logging to console and file Source: https://github.com/expressjs/morgan/blob/master/README.md Configures multiple morgan instances to log errors to the console and all requests to a file. ```js 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!') }) ``` -------------------------------- ### Log to Multiple Outputs Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Set up Morgan to log different types of requests to separate outputs, such as files and the console, based on status codes or other criteria. ```javascript const fs = require('fs') const morgan = require('morgan') // All requests to file app.use(morgan('combined', { stream: fs.createWriteStream('all-requests.log', { flags: 'a' }) })) // Only errors to console app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400 })) // Only successful requests to file app.use(morgan(':method :url :status', { stream: fs.createWriteStream('success-requests.log', { flags: 'a' }), skip: (req, res) => res.statusCode >= 400 })) ``` -------------------------------- ### Registering Custom Tokens Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Demonstrates how to register custom tokens by assigning a function to a property on the `morgan` object. This allows for overriding built-in tokens or creating new ones. ```javascript morgan.token('url', function getUrlToken(req, res) { ... }) morgan.token('method', function getMethodToken(req, res) { ... }) // Internally stored as: morgan.url = function getUrlToken(req, res) { ... } morgan.method = function getMethodToken(req, res) { ... } ``` -------------------------------- ### Morgan API: Register Token Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Shows how to register a custom token that can be included in log formats. ```javascript morgan.token('user-id', (req, res) => req.user?.id) app.use(morgan(':user-id :method :url')) ``` -------------------------------- ### Enable Debug Logging Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Enable Morgan's debug output by setting the DEBUG environment variable. This will show detailed logs about skipped requests, undefined formats, and logged requests. ```bash DEBUG=morgan node app.js ``` -------------------------------- ### morgan(format, options) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Creates and returns an Express/Connect middleware function that logs HTTP requests. The middleware adds timing properties to the request and response objects, then calls `next()`. Logging occurs either immediately or after the response is sent. ```APIDOC ## morgan(format, options) ### Description Creates and returns an Express/Connect middleware function that logs HTTP requests. The middleware adds timing properties to the request and response objects, then calls `next()`. Logging occurs either immediately (if `immediate: true`) or after the response is sent. ### Signature ```javascript function morgan(format, options) ``` ### Parameters #### format - **Type**: string | function - **Required**: No - **Default**: `'default'` - **Description**: Predefined format name ('combined', 'common', 'dev', 'short', 'tiny'), a format string with token references (e.g. `:method :url`), or a custom formatting function. #### options - **Type**: object - **Required**: No - **Default**: `{}` - **Description**: Configuration object for the logger. Supports `format`, `immediate`, `skip`, `stream`, and `buffer` (deprecated). ### Options Details - **format** (string | function): Format to use for log output. Only applies when morgan is called with an object as first argument (deprecated usage). - **immediate** (boolean): Log the request immediately on arrival, before response headers are sent. Response data (status, content-length) will not be available. Default: `false`. - **skip** (function): Function called as `skip(req, res)` that returns `true` to skip logging for that request. Must return a boolean. Default: `false`. - **stream** (writable stream): Stream to write log output to. Can be a file stream, process.stderr, or any writable stream. Default: `process.stdout`. - **buffer** (number | boolean): Deprecated. If true, uses 1000ms buffer duration. If a number, uses that value as milliseconds for buffering log output before writing. ### Return Type **Function** — Express middleware function with signature `function(req, res, next)` ### Examples **Basic usage with predefined format:** ```javascript const express = require('express') const morgan = require('morgan') const app = express() // Log all requests using Apache combined format app.use(morgan('combined')) app.get('/', (req, res) => { res.send('Hello World') }) app.listen(3000) ``` **Using a format string with tokens:** ```javascript const morgan = require('morgan') // Create logger with custom format string const logger = morgan(':method :url :status :response-time ms') app.use(logger) ``` **Using a custom format function:** ```javascript const morgan = require('morgan') const logger = morgan((tokens, req, res) => { return [ tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), tokens['response-time'](req, res) + 'ms' ].join(' ') }) app.use(logger) ``` **Skipping certain requests:** ```javascript const morgan = require('morgan') // Only log requests with status 400 or higher (errors) const logger = morgan('combined', { skip: (req, res) => res.statusCode < 400 }) app.use(logger) ``` **Logging to a file:** ```javascript const fs = require('fs') const morgan = require('morgan') const path = require('path') const accessLogStream = fs.createWriteStream( path.join(__dirname, 'access.log'), { flags: 'a' } ) app.use(morgan('combined', { stream: accessLogStream })) ``` **Immediate logging (request-time):** ```javascript const morgan = require('morgan') // Log immediately when request arrives, before response app.use(morgan('tiny', { immediate: true })) ``` **Vanilla Node.js HTTP server:** ```javascript const http = require('http') const morgan = require('morgan') const logger = morgan('combined') http.createServer((req, res) => { logger(req, res, () => { res.writeHead(200) res.end('Hello World') }) }).listen(3000) ``` ``` -------------------------------- ### Token with Argument Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Shows how to use a token with an argument, specifically ':response-time[5]' to log the response time with 5 decimal places. ```javascript morgan(':response-time[5]') // Response time with 5 decimal places ``` -------------------------------- ### Vanilla Node.js HTTP Server Integration Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Use Morgan with Node.js's built-in HTTP server by manually invoking the logger. ```javascript const http = require('http') const morgan = require('morgan') const finalhandler = require('finalhandler') const logger = morgan('combined') http.createServer((req, res) => { const done = finalhandler(req, res) logger(req, res, (err) => { if (err) return done(err) res.writeHead(200) res.end('Hello World') }) }).listen(3000) ``` -------------------------------- ### Timing Properties Initialization Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md When Morgan's middleware is invoked, it initializes several timing and address properties on the request and response objects for subsequent use in logging and token generation. ```javascript req._startAt = process.hrtime() // [seconds, nanoseconds] req._startTime = new Date() // Date object req._remoteAddress = getip(req) // Cached remote address ``` ```javascript res._startAt = process.hrtime() // [seconds, nanoseconds] res._startTime = new Date() // Date object ``` -------------------------------- ### Log to a File Stream Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Configure Morgan to write log output to a specific file using `fs.createWriteStream`. Ensure the file path is correct and the stream is properly managed. ```javascript const fs = require('fs') const accessLog = fs.createWriteStream('access.log', { flags: 'a' }) app.use(morgan('combined', { stream: accessLog })) ``` -------------------------------- ### Log to File Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Configure Morgan to write all incoming requests to a persistent log file using a write stream. ```javascript const fs = require('fs') const path = require('path') const morgan = require('morgan') const accessLog = fs.createWriteStream( path.join(__dirname, 'access.log'), { flags: 'a' } ) app.use(morgan('combined', { stream: accessLog })) ``` -------------------------------- ### Use Custom Format Function Source: https://github.com/expressjs/morgan/blob/master/README.md Create a custom logging format by providing a function to Morgan. This function receives tokens, request, and response objects to construct the log line. ```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(' ') }) ``` -------------------------------- ### Use 'short' log format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Use the 'short' format for concise logging, including response time in milliseconds, suitable for development. ```javascript const morgan = require('morgan') app.use(morgan('short')) ``` -------------------------------- ### morgan(format, options) Source: https://github.com/expressjs/morgan/blob/master/README.md Creates a new morgan logger middleware function using the specified format and configuration options. ```APIDOC ## morgan(format, options) ### Description Creates a new morgan logger middleware function. The format can be a predefined string, a custom format string, or a function. ### Parameters #### Arguments - **format** (string|function) - Required - The log format string or a function returning a log line. - **options** (object) - Optional - Configuration options for the logger. #### Options - **immediate** (boolean) - Optional - Write log line on request instead of response. - **skip** (function) - Optional - Function to determine if logging is skipped, called as skip(req, res). - **stream** (object) - Optional - Output stream for writing log lines, defaults to process.stdout. ### Request Example ```js morgan('combined', { skip: function (req, res) { return res.statusCode < 400 } }) ``` ``` -------------------------------- ### Common Pattern: Multiple Loggers Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Sets up two separate Morgan loggers: one for all requests to a file, and another for errors to the console. ```javascript // All requests to file app.use(morgan('combined', { stream: fs.createWriteStream('all.log', { flags: 'a' }) })) // Errors to console app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400 })) ``` -------------------------------- ### Format Lookup Order Logic Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This logic describes the order in which Morgan determines which format to use when a format is specified. It prioritizes functions, then registered formats, and finally compiles format strings. ```text 1. If format is a function → use directly 2. If format is a string a. Look for registered format with that name (morgan[name]) b. If found and is function → use it c. If found and is string → compile it d. If not found → compile the string as format string 3. If no format provided → use morgan.default ``` -------------------------------- ### Deprecated Buffering Option Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Demonstrates the deprecated `buffer` option for Morgan. This option is not recommended for production use. ```javascript // Don't use - deprecated app.use(morgan('combined', { buffer: 1000 })) ``` -------------------------------- ### Vanilla Node.js HTTP Server Integration Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Use Morgan with a vanilla Node.js HTTP server. The logger middleware needs to be manually invoked with req, res, and next. ```javascript const http = require('http') const morgan = require('morgan') const logger = morgan('combined') http.createServer((req, res) => { logger(req, res, () => { res.writeHead(200) res.end('Hello World') }) }).listen(3000) ``` -------------------------------- ### Logging HTTP Version with Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the HTTP protocol version used by the client. This token does not accept arguments. ```javascript morgan(':method :url HTTP/:http-version :status') ``` -------------------------------- ### Morgan API: Register Named Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Explains how to register a custom format with a name, allowing it to be used like a predefined format. ```javascript morgan.format('myformat', ':method :url :response-time ms') app.use(morgan('myformat')) ``` -------------------------------- ### Conditional Format Selection by Environment and Path Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Select different Morgan log formats based on the environment (production vs. others) or request path (e.g., '/api'). ```javascript const morgan = require('morgan') app.use((req, res, next) => { if (process.env.NODE_ENV === 'production') { return morgan('json')(req, res, next) } else if (req.path.startsWith('/api')) { return morgan(':method :url :status :response-time ms')(req, res, next) } else { return morgan('dev')(req, res, next) } }) ``` -------------------------------- ### Use 'tiny' log format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Use the 'tiny' format for minimal logging, including only essential information and response time, ideal when log volume is a concern. ```javascript const morgan = require('morgan') app.use(morgan('tiny')) ``` -------------------------------- ### morgan.compile(format) Source: https://github.com/expressjs/morgan/blob/master/README.md Compiles a format string into a function that generates log lines using defined tokens. ```APIDOC ## morgan.compile(format) ### Description Compiles a format string into a `format` function for use by `morgan`. A format string represents a single log line and can utilize token syntax (e.g., :token-name). ### Parameters #### Request Body - **format** (string) - Required - The format string containing token references. ### Response - **function** (function) - A function that takes (tokens, req, res) and returns a string log line or null/undefined to skip logging. ``` -------------------------------- ### Basic Express Usage Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Integrate Morgan middleware into an Express application to log all HTTP requests using the 'combined' format. Ensure Morgan is imported and used with app.use before defining routes. ```javascript const express = require('express') const morgan = require('morgan') const app = express() // Log all HTTP requests app.use(morgan('combined')) app.get('/', (req, res) => { res.send('Hello World') }) app.listen(3000) ``` -------------------------------- ### Logging User-Agent with Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the User-Agent header from the request, indicating the client's browser or application. ```javascript morgan(':method :url :status :user-agent') ``` -------------------------------- ### Logging HTTP Method with Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the HTTP method of the request. This token does not accept arguments. ```javascript morgan(':method :url') ``` -------------------------------- ### Available Log Tokens Source: https://github.com/expressjs/morgan/blob/master/README.md List of tokens available for use in Morgan log format strings. ```APIDOC ## Available Log Tokens ### Tokens - **:date[format]** - Current UTC date/time. Formats: clf, iso, web (default). - **:http-version** - HTTP version of the request. - **:method** - HTTP method of the request. - **:pid** - Process ID of the Node.js process. - **:referrer** - Referrer header of the request. - **:remote-addr** - Remote address of the request. - **:remote-user** - Authenticated user via Basic auth. - **:req[header]** - Value of the specified request header. - **:res[header]** - Value of the specified response header. - **:response-time[digits]** - Time in ms between request and response headers. - **:status** - HTTP status code of the response. - **:total-time[digits]** - Time in ms between request and full response write. - **:url** - URL of the request. - **:user-agent** - Contents of the User-Agent header. ``` -------------------------------- ### Immediate Mode for Development Debugging Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Enable immediate mode for logging in development environments. This logs requests as they are received, which can be helpful for debugging crashes. ```javascript if (process.env.NODE_ENV !== 'production') { app.use(morgan('dev', { immediate: true })) } ``` -------------------------------- ### Immediate Logging Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Log requests immediately when they arrive, before the response is sent. Note that response details like status code and content-length will not be available in the logs. ```javascript const morgan = require('morgan') // Log immediately when request arrives, before response app.use(morgan('tiny', { immediate: true })) ``` -------------------------------- ### morgan.compile(format) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Compiles a format string into a reusable format function. This is useful for advanced use cases where you want to pre-compile a format string without creating a full middleware. ```APIDOC ## morgan.compile(format) ### Description Compiles a format string into a reusable format function. Useful for advanced use cases where you want to pre-compile a format string without creating a full middleware. ### Signature ```javascript function compile(format) ``` ### Parameters #### format - **Type**: string - **Required**: Yes - **Description**: The format string to compile. Can include token references like `:method`, `:url`, etc. ``` -------------------------------- ### Morgan Module Exports Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Morgan exports the main morgan function along with functions for compiling formats, registering formats, and registering tokens. Format and token definitions are also stored as properties on the morgan function itself. ```javascript module.exports = morgan module.exports.compile = compile module.exports.format = format module.exports.token = token ``` -------------------------------- ### Chain Multiple Format Definitions Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Chains multiple calls to `morgan.format()` to define several named formats sequentially. This is a concise way to register multiple custom formats. ```javascript const morgan = require('morgan') morgan .format('format1', ':method :url :status') .format('format2', ':method :url :response-time ms') app.use(morgan('format1')) ``` -------------------------------- ### Log Request User-Agent and Method Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Logs the User-Agent header from the request and the HTTP method. ```javascript morgan(':req[user-agent] :method') // Mozilla/5.0 (X11; Linux x86_64) GET ``` -------------------------------- ### Logging to a File with Express Source: https://github.com/expressjs/morgan/blob/master/README.md This snippet configures Morgan to log all requests in the 'combined' format to a specific file named 'access.log'. It uses Node.js 'fs' module to create a write stream in append mode. Ensure 'morgan', 'fs', and 'path' are available. ```javascript 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 Environment and Region Information Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Create tokens to log the current Node.js environment (NODE_ENV) and AWS region (AWS_REGION). Defaults to 'development' and 'local' respectively. ```javascript morgan.token('env', (req, res) => { return process.env.NODE_ENV || 'development' }) morgan.token('region', (req, res) => { return process.env.AWS_REGION || 'local' }) app.use(morgan('[env=:env|region=:region] :method :url :status')) ``` -------------------------------- ### Create a Reusable JSON Formatter Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Compiles a format string into a JSON object. This formatter can then be used with the Morgan middleware. ```javascript const morgan = require('morgan') const jsonFormatter = morgan.compile( '{"method":":method","url":":url","status":":status"}' ) // Use in multiple places const middleware = morgan(jsonFormatter) ``` -------------------------------- ### Parsing Basic Authentication Credentials Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Demonstrates the implementation of the `remote-user` token, which uses the `basic-auth` module to parse and extract the username from the `Authorization` header. ```javascript morgan.token('remote-user', function(req) { var credentials = auth(req) // Parses Authorization header return credentials ? escapeLogField(credentials.name) // Only the username : undefined }) ``` -------------------------------- ### Common Pattern: Custom Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Defines and uses a custom log format named 'simple' for logging requests. ```javascript morgan.format('simple', ':method :url :status :response-time ms') app.use(morgan('simple')) ``` -------------------------------- ### Express Integration Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Integrate Morgan middleware into an Express application to log HTTP requests. ```javascript const express = require('express') const morgan = require('morgan') const app = express() // Add morgan middleware app.use(morgan('combined')) app.get('/', (req, res) => { res.send('Hello World') }) app.listen(3000) ``` -------------------------------- ### Colored Output for Development Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Create a custom format that enhances the 'dev' format with colored status codes for better readability in development environments. ```javascript morgan.format('dev-detailed', (tokens, req, res) => { const status = tokens.status(req, res) const color = status >= 500 ? 31 : status >= 400 ? 33 : 32 // red, yellow, green return `\x1b[${color}m${tokens.status(req, res)}\x1b[0m ${tokens.method(req, res)} ${tokens.url(req, res)} ${tokens['response-time'](req, res)}ms` }) app.use(morgan('dev-detailed')) ``` -------------------------------- ### Simple Custom Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Define a basic custom log format string for concise request logging. ```javascript app.use(morgan(':method :url :status - :response-time ms')) // GET /api/users 200 - 1.234 ms ``` -------------------------------- ### Logging Referrer with Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the Referrer header from the request, indicating which page linked to the current request. Returns '-' if the header is not present. ```javascript morgan(':method :url :referrer') ``` -------------------------------- ### morgan.format(name, fmt) Source: https://github.com/expressjs/morgan/blob/master/_autodocs/MANIFEST.md Registers a new format string or function with a given name. This allows you to define and reuse custom log formats. ```APIDOC ## morgan.format(name, fmt) ### Description Registers a new format string or function with a given name. This allows for the creation and reuse of custom log formats. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **name** (string) - Required - The name to register the format under. - **fmt** (string | function) - Required - The format string or function to register. ``` -------------------------------- ### Create Custom Morgan Token Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Defines and uses a custom token named 'my-token' to include application-specific data in logs. ```javascript const morgan = require('morgan') morgan.token('my-token', (req, res) => { // Return a string value return 'my-value' }) app.use(morgan(':my-token :method :url')) ``` -------------------------------- ### Define a Custom Format String by Name Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Defines a new named format string that can be used directly with the morgan middleware. This allows for easy reuse of custom log formats. ```javascript const morgan = require('morgan') // Define a simple format morgan.format('simple', ':method :url :status') // Now use it by name app.use(morgan('simple')) ``` -------------------------------- ### Common Pattern: Skip Certain Requests Source: https://github.com/expressjs/morgan/blob/master/_autodocs/quick-reference.md Sets up Morgan to skip logging for specific requests, such as health check endpoints or static file requests. ```javascript app.use(morgan('combined', { skip: (req, res) => { return req.path === '/health' || req.path.includes('static') } })) ``` -------------------------------- ### Capturing Log Output in Tests Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Capture Morgan's log output in tests by using a custom Writable stream. This allows assertions to be made against the logged content. ```javascript const morgan = require('morgan') const { Writable } = require('stream') let logOutput = '' const logStream = new Writable({ write(chunk, encoding, callback) { logOutput += chunk.toString() callback() } }) describe('API', () => { it('logs requests', (done) => { const logger = morgan(':method :url :status', { stream: logStream }) const req = { method: 'GET', url: '/test' } const res = { statusCode: 200, headersSent: true } logger(req, res, () => { expect(logOutput).toContain('GET /test 200') done() }) }) }) ``` -------------------------------- ### Replace Output Stream Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This code snippet shows how to substitute the default output stream for Morgan logs. This allows logs to be routed to various destinations like files or aggregation services. ```javascript morgan('combined', { stream: myCustomStream }) ``` -------------------------------- ### Time-Based Logging Skip Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Configure Morgan to skip logging requests during specific hours (e.g., between midnight and 6 AM) using the 'skip' option. ```javascript const morgan = require('morgan') app.use(morgan('combined', { skip: (req, res) => { const hour = new Date().getHours() // Don't log between midnight and 6am return hour >= 0 && hour < 6 } })) ``` -------------------------------- ### Generated JavaScript for Format String Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md Shows the JavaScript code generated from a sample format string `':method :url :status'`. This demonstrates how token references are transformed into function calls with fallback values. ```javascript "use strict" return "" + (tokens['method'](req, res) || "-") + " " + (tokens['url'](req, res) || "-") + " " + (tokens['status'](req, res) || "-") ``` -------------------------------- ### Logging to a File Stream Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Direct log output to a specific file stream instead of the default stdout. Ensure the file path and write stream are correctly configured. ```javascript const fs = require('fs') const morgan = require('morgan') const path = require('path') const accessLogStream = fs.createWriteStream( path.join(__dirname, 'access.log'), { flags: 'a' } ) app.use(morgan('combined', { stream: accessLogStream })) ``` -------------------------------- ### Custom Datadog Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Create a custom log format tailored for Datadog's log ingestion. This includes adding a timestamp token and mapping Morgan tokens to Datadog's expected fields. ```javascript morgan.token('timestamp', (req, res) => { return new Date().toISOString() }) morgan.format('datadog', (tokens, req, res) => { return JSON.stringify({ 'timestamp': tokens.timestamp(req, res), 'http.method': tokens.method(req, res), 'http.url': tokens.url(req, res), 'http.status_code': parseInt(tokens.status(req, res)), 'http.response_time': parseFloat(tokens['response-time'](req, res)), 'http.useragent': tokens['user-agent'](req, res), 'network.client.ip': tokens['remote-addr'](req, res), 'logger.name': 'morgan', 'logger.version': 'morgan/1.11.0' }) }) app.use(morgan('datadog')) ``` -------------------------------- ### Combined Date Token Usage Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Demonstrates integrating different :date formats with other tokens for comprehensive log entries. ```javascript morgan('[:date[clf]] :method :url :status') ``` ```javascript morgan(':date[iso] :method :url') ``` ```javascript morgan(':method :url - :date[web]') ``` -------------------------------- ### Add Custom Token with Argument Source: https://github.com/expressjs/morgan/blob/master/_autodocs/api-reference/morgan.md Create a custom token that accepts an argument, allowing for dynamic logging based on specific headers or parameters. The argument is passed to the token function. ```javascript const morgan = require('morgan') morgan.token('custom-header', (req, res, headerName) => { return req.headers[headerName] || '-' }) // Use with an argument app.use(morgan(':custom-header[x-request-id] :method :url :status')) ``` -------------------------------- ### Log URL and Response Headers Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Logs the request URL along with the response's content type and content length headers. ```javascript morgan(':url :res[content-type] :res[content-length]') // /api/users application/json 1234 ``` -------------------------------- ### Define Custom Format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md This snippet shows how to define a new named format for Morgan logs. This allows for reusable and composable log formats. ```javascript morgan.format('myformat', ':method :url :status') ``` -------------------------------- ### Using Format Function in Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md For more complex or dynamic log formatting, a function can be passed directly to the morgan function. This function receives tokens, request, and response objects to construct the log string. ```javascript morgan((tokens, req, res) => { return `${tokens.method(req, res)} ${tokens.url(req, res)}` }) ``` -------------------------------- ### Logging Remote User with Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/tokens-reference.md Logs the username from HTTP Basic Authentication. Returns '-' if no Basic auth credentials are present. ```javascript morgan(':remote-user :method :url :status') ``` -------------------------------- ### Skip Logging Based on Response Status Source: https://github.com/expressjs/morgan/blob/master/README.md Configure Morgan to skip logging requests where the response status code is less than 400. This is useful for logging only errors. ```js morgan('combined', { skip: function (req, res) { return res.statusCode < 400 } }) ``` -------------------------------- ### Combine Custom Token with Middleware Options Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Integrate a custom-defined token ('user') into the Morgan format string and use the `skip` option to exclude health check requests. ```javascript morgan.token('user', (req, res) => { return req.user?.id || 'anonymous' }) app.use(morgan(':user :method :url :status', { skip: (req, res) => req.path === '/health' })) ``` -------------------------------- ### Using Format String in Morgan Source: https://github.com/expressjs/morgan/blob/master/_autodocs/architecture.md A custom format can be directly provided as a string to the morgan function when creating the middleware. This is a concise way to define simple log formats. ```javascript morgan(':method :url :status') ``` -------------------------------- ### Use Custom Format String Source: https://github.com/expressjs/morgan/blob/master/README.md Define a custom log format string using predefined tokens. This allows for flexible logging of specific request and response details. ```js morgan(':method :url :status :res[content-length] - :response-time ms') ``` -------------------------------- ### Format Selection by Content Type Source: https://github.com/expressjs/morgan/blob/master/_autodocs/implementation-guide.md Dynamically choose the log format ('json' or 'dev') based on whether the request path indicates an API endpoint. ```javascript app.use((req, res, next) => { const isAPI = req.path.startsWith('/api') const format = isAPI ? 'json' : 'dev' return morgan(format)(req, res, next) }) ``` -------------------------------- ### Use 'dev' log format Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Use the 'dev' format for colored development logging, with status codes color-coded based on ranges (2xx, 3xx, 4xx, 5xx). ```javascript const morgan = require('morgan') app.use(morgan('dev')) ``` -------------------------------- ### Log Combined Request and Response Details Source: https://github.com/expressjs/morgan/blob/master/_autodocs/configuration.md Logs a comprehensive line including method, URL, status, content length, and response time. ```javascript morgan(':method :url :status :res[content-length] :response-time ms') // POST /api/users 201 42 0.456 ms ``` -------------------------------- ### Include Request ID in Logs Source: https://github.com/expressjs/morgan/blob/master/_autodocs/README.md Integrate request ID logging by generating a UUID for each request, defining a custom 'request-id' token, and including it in the Morgan format string. ```javascript const { v4: uuid } = require('uuid') morgan.token('request-id', (req, res) => req.id) app.use((req, res, next) => { req.id = uuid() next() }) app.use(morgan(':request-id :method :url :status')) ```