HTTP request logger middleware for Node.js applications
npx @tessl/cli install tessl/npm-morgan@1.10.00
# Morgan
1
2
Morgan 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.
3
4
## Package Information
5
6
- **Package Name**: morgan
7
- **Package Type**: npm
8
- **Language**: JavaScript (CommonJS)
9
- **Installation**: `npm install morgan`
10
11
## Core Imports
12
13
```javascript
14
const morgan = require('morgan');
15
```
16
17
ES6 modules (if supported):
18
19
```javascript
20
import morgan from 'morgan';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const express = require('express');
27
const morgan = require('morgan');
28
29
const app = express();
30
31
// Use predefined format
32
app.use(morgan('combined'));
33
34
// Custom format string
35
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
36
37
// Custom format function
38
app.use(morgan((tokens, req, res) => {
39
return [
40
tokens.method(req, res),
41
tokens.url(req, res),
42
tokens.status(req, res),
43
tokens.res(req, res, 'content-length'), '-',
44
tokens['response-time'](req, res), 'ms'
45
].join(' ');
46
}));
47
48
app.get('/', (req, res) => {
49
res.send('Hello World!');
50
});
51
```
52
53
## Architecture
54
55
Morgan is built around several key components:
56
57
- **Middleware Factory**: Main `morgan()` function creates Express/Connect-compatible middleware
58
- **Format System**: Predefined formats (combined, common, dev, short, tiny) and custom format support
59
- **Token System**: Extensible token-based logging with built-in and custom tokens
60
- **Stream Interface**: Configurable output streams for flexible log destination management
61
- **Compilation Engine**: Format string compiler that transforms token-based formats into executable functions
62
63
## Capabilities
64
65
### Middleware Creation
66
67
Creates HTTP request logger middleware with flexible configuration options.
68
69
```javascript { .api }
70
/**
71
* Create a new morgan logger middleware function
72
* @param {string|Function} format - Format name, format string, or custom function
73
* @param {Object} [options] - Configuration options
74
* @param {boolean} [options.immediate] - Log on request instead of response
75
* @param {Function} [options.skip] - Function to determine if logging should be skipped
76
* @param {WritableStream} [options.stream] - Output stream (defaults to process.stdout)
77
* @param {number|boolean} [options.buffer] - Deprecated buffering support
78
* @returns {Function} Express/Connect middleware function
79
*/
80
function morgan(format, options);
81
```
82
83
### Format Compilation
84
85
Compiles format strings into executable logging functions.
86
87
```javascript { .api }
88
/**
89
* Compile a format string into a format function
90
* @param {string} format - Format string with token syntax
91
* @returns {Function} Format function that takes (tokens, req, res) and returns log line
92
* @throws {TypeError} When format is not a string
93
*/
94
function compile(format);
95
```
96
97
### Format Definition
98
99
Defines named formats for reuse across applications.
100
101
```javascript { .api }
102
/**
103
* Define a format with the given name
104
* @param {string} name - Format name for later reference
105
* @param {string|Function} fmt - Format string or function
106
* @returns {Object} Morgan instance (chainable)
107
*/
108
function format(name, fmt);
109
```
110
111
### Token Registration
112
113
Registers custom token functions for use in format strings.
114
115
```javascript { .api }
116
/**
117
* Define a token function with the given name
118
* @param {string} name - Token name for use in format strings
119
* @param {Function} fn - Token function that receives (req, res, ...args) and returns string
120
* @returns {Object} Morgan instance (chainable)
121
*/
122
function token(name, fn);
123
```
124
125
## Predefined Formats
126
127
### Apache Combined Format
128
129
Standard Apache combined log output with full request and response information.
130
131
```javascript { .api }
132
// Usage
133
morgan('combined');
134
135
// Equivalent format string
136
':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
137
138
// Example output
139
'::1 - - [27/Nov/2024:06:21:42 +0000] "GET /api/users HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0"'
140
```
141
142
### Apache Common Format
143
144
Standard Apache common log output without referrer and user agent.
145
146
```javascript { .api }
147
// Usage
148
morgan('common');
149
150
// Equivalent format string
151
':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]'
152
153
// Example output
154
'::1 - - [27/Nov/2024:06:21:46 +0000] "GET /api/users HTTP/1.1" 200 1234'
155
```
156
157
### Development Format
158
159
Colored output optimized for development with response time information.
160
161
```javascript { .api }
162
// Usage
163
morgan('dev');
164
165
// Equivalent format string with colors
166
':method :url :status :response-time ms - :res[content-length]'
167
168
// Example output (colored)
169
'GET /api/users 200 4.123 ms - 1234'
170
```
171
172
### Short Format
173
174
Compact format including response time and basic request information.
175
176
```javascript { .api }
177
// Usage
178
morgan('short');
179
180
// Equivalent format string
181
':remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
182
183
// Example output
184
'::1 - GET /api/users HTTP/1.1 200 1234 - 4.123 ms'
185
```
186
187
### Tiny Format
188
189
Minimal output with essential request information.
190
191
```javascript { .api }
192
// Usage
193
morgan('tiny');
194
195
// Equivalent format string
196
':method :url :status :res[content-length] - :response-time ms'
197
198
// Example output
199
'GET /api/users 200 1234 - 4.123 ms'
200
```
201
202
### Default Format (Deprecated)
203
204
Legacy default format, equivalent to combined format but with different date formatting. Deprecated in favor of combined format.
205
206
```javascript { .api }
207
// Usage (deprecated)
208
morgan('default');
209
210
// Equivalent format string
211
':remote-addr - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
212
213
// Example output
214
'::1 - - [Wed, 27 Nov 2024 06:21:42 GMT] "GET /api/users HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0"'
215
```
216
217
## Built-in Tokens
218
219
### Request Information Tokens
220
221
```javascript { .api }
222
/**
223
* HTTP method of the request
224
* Usage: :method
225
*/
226
function method(req);
227
228
/**
229
* Request URL (uses originalUrl if available, otherwise url)
230
* Usage: :url
231
*/
232
function url(req);
233
234
/**
235
* HTTP version of the request
236
* Usage: :http-version
237
*/
238
function httpVersion(req);
239
240
/**
241
* Remote IP address (uses req.ip, falls back to connection.remoteAddress)
242
* Usage: :remote-addr
243
*/
244
function remoteAddr(req);
245
246
/**
247
* Basic auth username
248
* Usage: :remote-user
249
*/
250
function remoteUser(req);
251
252
/**
253
* User-Agent header value
254
* Usage: :user-agent
255
*/
256
function userAgent(req);
257
258
/**
259
* Referrer header (handles both referer and referrer spellings)
260
* Usage: :referrer
261
*/
262
function referrer(req);
263
264
/**
265
* Request header value
266
* Usage: :req[header-name]
267
* @param {string} field - Header name
268
*/
269
function req(req, res, field);
270
```
271
272
### Response Information Tokens
273
274
```javascript { .api }
275
/**
276
* HTTP response status code
277
* Usage: :status
278
*/
279
function status(req, res);
280
281
/**
282
* Response header value
283
* Usage: :res[header-name]
284
* @param {string} field - Header name
285
*/
286
function res(req, res, field);
287
```
288
289
### Timing Tokens
290
291
```javascript { .api }
292
/**
293
* Response time in milliseconds (from request start to response headers written)
294
* Usage: :response-time[digits]
295
* @param {number} [digits=3] - Number of decimal places
296
*/
297
function responseTime(req, res, digits);
298
299
/**
300
* Total time in milliseconds (from request start to response complete)
301
* Usage: :total-time[digits]
302
* @param {number} [digits=3] - Number of decimal places
303
*/
304
function totalTime(req, res, digits);
305
306
/**
307
* Current date in various formats
308
* Usage: :date[format]
309
* @param {string} [format='web'] - Date format ('clf', 'iso', 'web')
310
*/
311
function date(req, res, format);
312
```
313
314
## Advanced Usage Examples
315
316
### Custom Tokens
317
318
```javascript
319
const express = require('express');
320
const morgan = require('morgan');
321
const uuid = require('uuid');
322
323
// Define custom token
324
morgan.token('id', (req) => req.id);
325
326
const app = express();
327
328
// Assign unique ID to each request
329
app.use((req, res, next) => {
330
req.id = uuid.v4();
331
next();
332
});
333
334
// Use custom token in format
335
app.use(morgan(':id :method :url :response-time'));
336
```
337
338
### Conditional Logging
339
340
```javascript
341
const fs = require('fs');
342
const path = require('path');
343
344
// Log only errors to console
345
app.use(morgan('dev', {
346
skip: (req, res) => res.statusCode < 400
347
}));
348
349
// Log all requests to file
350
app.use(morgan('combined', {
351
stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })
352
}));
353
```
354
355
### Custom Format Functions
356
357
```javascript
358
app.use(morgan((tokens, req, res) => {
359
const log = {
360
timestamp: new Date().toISOString(),
361
method: tokens.method(req, res),
362
url: tokens.url(req, res),
363
status: tokens.status(req, res),
364
responseTime: tokens['response-time'](req, res),
365
userAgent: tokens['user-agent'](req, res)
366
};
367
return JSON.stringify(log);
368
}));
369
```
370
371
## Types
372
373
```javascript { .api }
374
/**
375
* Morgan middleware function signature
376
* @callback MiddlewareFunction
377
* @param {IncomingMessage} req - HTTP request object
378
* @param {ServerResponse} res - HTTP response object
379
* @param {Function} next - Next middleware function
380
*/
381
382
/**
383
* Format function signature
384
* @callback FormatFunction
385
* @param {Object} tokens - Object containing all defined tokens
386
* @param {IncomingMessage} req - HTTP request object
387
* @param {ServerResponse} res - HTTP response object
388
* @returns {string|null|undefined} Log line or null/undefined to skip
389
*/
390
391
/**
392
* Token function signature
393
* @callback TokenFunction
394
* @param {IncomingMessage} req - HTTP request object
395
* @param {ServerResponse} res - HTTP response object
396
* @param {...any} args - Additional arguments from token usage
397
* @returns {string|undefined} Token value or undefined for default
398
*/
399
400
/**
401
* Skip function signature
402
* @callback SkipFunction
403
* @param {IncomingMessage} req - HTTP request object
404
* @param {ServerResponse} res - HTTP response object
405
* @returns {boolean} True to skip logging, false to log
406
*/
407
408
/**
409
* Morgan options interface
410
* @typedef {Object} MorganOptions
411
* @property {boolean} [immediate] - Log on request instead of response
412
* @property {SkipFunction} [skip] - Function to determine if logging should be skipped
413
* @property {WritableStream} [stream] - Output stream for log lines
414
* @property {number|boolean} [buffer] - Deprecated buffering support
415
*/
416
```