rojanu rojanu - 1 year ago 187
Node.js Question

Logging with traceId in Express.js

I need to produce logs with a trace id. Currently we are using winston to do the logging

I am using winston containers as follows

var fs = require('fs');
var os = require('os');
var path = require('path');
var winston = require('winston');
var transports = [];

module.exports = function(setting) {

function formatter(options) {
return options.timestamp() +' '+ options.level.toUpperCase() +' '+ (undefined !== options.message ? options.message : '');

if (setting.log.file) {
fs.existsSync(setting.log.path) || fs.mkdirSync(setting.log.path);
transports.push(new winston.transports.DailyRotateFile({
handleExceptions: true,
json: true,
component: setting.customise.app_type,
datePattern: setting.log.datePattern,
filename: path.join(setting.log.path, setting.log.filename),
level: setting.log.level
if (setting.log.console || transports.length === 0) {
transports.push(new (winston.transports.Console)({
timestamp: function() {
return new Date().toISOString();
handleExceptions: true,
json: false,
formatter: formatter,
level: setting.log.level,
colorize: 'all'

winston.loggers.add('defaultLogger', {
transports: transports

var logger = winston.loggers.get('defaultLogger');
logger.exitOnError = false;
logger.addFilter(function(msg, meta, level) {
meta = {};
meta.component= setting.customise.app_type;
meta.component_version = setting.app_version;
meta.machine = os.hostname();
meta.context =;
return msg;

So in the files that need to do some logging, simply do

var sessionTool = require('sessionTool')(app);

var logger = require('winston').loggers.get('defaultLogger');

to get express to use winston

var winstonStream = {
write: function(message, encoding){, -1));
stream: winstonStream,
format: ':remote-addr - - :method :url HTTP/:http-version :status :res[content-length] :referrer :user-agent'

I added a capture all route to get/generate a trace id

app.all('*', function(req, res, next){
var traceId = req.params['trace_id'];
traceId = require('node-uuid').v4();
req.params['trace_id'] = traceId;

So the question is:
How can the unique trace id for each call made available thorough the application?

To make sure that the trace id is in used at all times, I am thinking of create an global variable for every request without passing the variable from request down to controllers and then down again, as that would mean that everytime a new controller or a service is introduced then we have to remember the trace id as well.

Answer Source

I have ended using continuation-local-storage to store trace_id and use it later when logging

Add the following to winston filter

logger.addFilter(function(msg, meta, level) {
   var nameSpace = require('continuation-local-storage').getNamespace('nameSpace');
   meta.trace_id = meta.trace_id || nameSpace.get('trace_id');
   return msg;

and change app.all() function to

server.all('*', function(req, res, next) {
  var nameSpace = require('continuation-local-storage').getNamespace('nameSpace');
  var traceId = req.get(;
  if (!traceId) {
    traceId = uuid.v4();
  res.header('trace_id', traceId); {
    nameSpace.set('trace_id', traceId);