What is morgan?
Morgan is a middleware for Node.js that enables HTTP request logging. It is commonly used with Express.js applications to log information about incoming requests, which can be helpful for debugging, monitoring, and analytics purposes.
What are morgan's main functionalities?
Logging HTTP requests
This code sets up an Express server and uses Morgan to log all incoming HTTP requests in the 'combined' Apache format.
const express = require('express');
const morgan = require('morgan');
const app = express();
app.use(morgan('combined'));
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Customizing log formats
This code demonstrates how to customize the log format to include specific details such as the HTTP method, URL, status code, content length, and response time.
const express = require('express');
const morgan = require('morgan');
const app = express();
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Creating custom tokens
This code shows how to create a custom token 'id' that can be used in the log format. The token function returns a value from the request object, which is then logged.
const express = require('express');
const morgan = require('morgan');
const app = express();
morgan.token('id', function getId(req) {
return req.id;
});
app.use(morgan(':id :method :url'));
app.get('/', (req, res) => {
req.id = 'abc123';
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Writing logs to a file
This code snippet demonstrates how to configure Morgan to write logs to a file named 'access.log' instead of outputting to the console.
const fs = require('fs');
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const app = express();
const accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
app.use(morgan('combined', { stream: accessLogStream }));
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Other packages similar to morgan
winston
Winston is a versatile logging library for Node.js. Unlike Morgan, which is specifically designed for HTTP request logging, Winston can be used for general-purpose application logging. It supports multiple transports (e.g., console, file, database) and is highly configurable.
pino
Pino is a very low-overhead Node.js logger. It is designed for speed and can be significantly faster than other logging solutions like Morgan, especially in high-throughput scenarios. Pino focuses on JSON logging and offers different log levels and custom serializers.
bunyan
Bunyan is a simple and fast JSON logging library for Node.js services. Like Pino, it focuses on JSON logging. Bunyan provides a set of standard log levels and includes a CLI tool for pretty-printing log files. It is more similar to Winston in terms of features but with a focus on JSON.
morgan
HTTP request logger middleware for node.js
Named after Dexter, a show you should not watch until completion.
API
var morgan = require('morgan')
morgan(format, options)
Create a new morgan logger middleware function using the given format
and options
.
The format
argument may be a string of a predefined name (see below for the names),
a string of a format string, or a function that will produce a log entry.
Options
Morgan accepts these properties in the options object.
buffer
Buffer duration before writing logs to the stream
, defaults to false
. When
set to true
, defaults to 1000 ms
.
immediate
Write log line on request instead of response. This means that a requests will
be logged even if the server crashes, but data from the response (like the
response code, content length, etc.) cannot be logged.
skip
Function to determine if logging is skipped, defaults to false
. This function
will be called as skip(req, res)
.
morgan('combined', {
skip: function (req, res) { return res.statusCode < 400 }
})
stream
Output stream for writing log lines, defaults to process.stdout
.
Predefined Formats
There are various pre-defined formats provided:
combined
Standard Apache combined log output.
:remote-addr - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
common
Standard Apache common log output.
:remote-addr - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length]
dev
Concise output colored by response status for development use. The :status
token will be colored red for server error codes, yellow for client error
codes, cyan for redirection codes, and uncolored for all other codes.
:method :url :status :response-time ms - :res[content-length]
short
Shorter than default, also including response time.
:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
tiny
The minimal output.
:method :url :status :res[content-length] - :response-time ms
Tokens
:req[header]
ex: :req[Accept]
:res[header]
ex: :res[Content-Length]
:http-version
:response-time
:remote-addr
:remote-user
:date
:method
:url
:referrer
:user-agent
:status
To define a token, simply invoke morgan.token()
with the name and a callback function. The value returned is then available as ":type" in this case:
morgan.token('type', function(req, res){ return req.headers['content-type']; })
Calling morgan.token()
using the same name as an existing token will overwrite that token definition.
Examples
express/connect
Simple app that will log all request in the Apache combined format to 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!')
})
vanilla http server
Simple app that will log all request in the Apache combined format to STDOUT
var finalhandler = require('finalhandler')
var http = require('http')
var morgan = require('morgan')
var logger = morgan('combined')
http.createServer(function (req, res) {
var done = finalhandler(req, res)
logger(req, res, function (err) {
if (err) return done(err)
res.setHeader('content-type', 'text/plain')
res.end('hello, world!')
})
})
write logs to a file
Simple app that will log all request in the Apache combined format to the file "access.log"
var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var app = express()
var accessLogStream = fs.createWriteStream(__dirname + '/access.log', {flags: 'a'})
app.use(morgan('combined', {stream: accessLogStream}))
app.get('/', function (req, res) {
res.send('hello, world!')
})
use custom token formats
Sample app that will use custom token formats like changing the ":date"
var express = require('express')
var morgan = require('morgan')
morgan.token('date', function () {
return new Date().toISOString()
})
var app = express()
app.use(morgan('combined'))
app.get('/', function (req, res) {
res.send('hello, world!')
})
License
MIT