Track users’ logs with morgan

Morgan is a logging middleware used to handle the logging of your admin backend. It is called this way in your app.js file:

app.js
const morgan = require('morgan')
...
app.use(morgan('tiny'))
...

The logs are printed in this format:

Screenshot 2020-07-21 at 18.17.25.png

You can choose to have more verbose logs, add new information, and customize the log format using morgan.

You can take a look at the package documentation here.

This can be especially useful if you store your logs and use them to track user activities.

Add new information

You could add in your logging data like:

  • user IP (IP of the request),

  • user name & team from the Forest Admin token

You can adjust the code in your app.js file using the snippet below.

The logs printed will include information about the user IP, the user connected with Forest and his team.

app.js
const morgan = require('morgan')
...
morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
morgan.token('user', (req) => {
if (req.user) { return req.user.email; }
return 'no user info';
});
morgan.token('team', (req) => {
if (req.user) { return req.user.team; }
return '-';
});
app.use(morgan(':ip :user :team [:date[clf]] :method :url :response-time'));
...

This will give you the following log output:

Screenshot 2020-07-21 at 18.17.45.png

Customize the format of the logs

You can also use a custom format like a JSON to output your logs.

app.js
const morgan = require('morgan')
...
morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
morgan.token('user', (req) => {
if (req.user) { return req.user.email; }
return 'no user info';
});
morgan.token('team', (req) => {
if (req.user) { return req.user.team; }
return '-';
});
function jsonFormat(tokens, req, res) {
return JSON.stringify({
ip: tokens.ip(req, res),
user: tokens.user(req, res),
team: tokens.team(req, res),
time: tokens.date(req, res, 'iso'),
method: tokens.method(req, res),
url: tokens.url(req, res),
'http-version': tokens['http-version'](req, res),
'status-code': tokens.status(req, res),
'content-length': tokens.res(req, res, 'content-length'),
referrer: tokens.referrer(req, res),
'user-agent': tokens['user-agent'](req, res),
});
}
app.use(morgan(jsonFormat));
...

This will give you the following log output:

Screenshot 2020-07-21 at 17.58.38.png

Store logs via a stream

You can also choose to store your logs using a stream. The following example shows how you can store your logs into a CSV file.

app.js
const morgan = require('morgan')
...
morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
morgan.token('user', (req) => {
if (req.user) { return req.user.email; }
return 'no user info';
});
morgan.token('team', (req) => {
if (req.user) { return req.user.team; }
return '-';
});
let accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.csv'), { flags: 'a' });
app.use(morgan(':ip,:user,:team,[:date[clf]],:method,:url,:response-time', { stream: accessLogStream }));
...