2017-02-24 98 views
4

我正在使用winston记录器。我想在每个请求中具有相同uuid的日志中添加uuid如何在每个请求的每个winston日志节点js中添加uuid?

在app.js

var distributorapp = require('./routes/distributorapp'); 
app.use('/dstapp',distributorapp); 

在路由/ distributorapp.js(中间件)

var qs = require('querystring'); 
var request = require('request'); 
var logger = require('../locallibs/logger'); 
var uuid = require('uuid/v1'); 
module.exports = { 
    mddlw: function (req, res, next) { 
     req.bodyData = qs.parse(req.body); // parsing body and added to request object 
     req.uuid = uuid(); // Adding uuid to request to available every where throught request 
     callHsmRest(req, res); // function to do some logic and handle middleware functionality 
    } 
}; 

在logger.js

var winston = require('winston'); 
var fs = require('fs'); 
var moment = require('moment'); 
var today = moment().format('YYYY-MM-DD'); 

if (!fs.existsSync(today)) { 
    fs.mkdirSync(today); 
} 


function customFileFormatter(options) { 
    console.log(options); 
    return options.timestamp() + ' [' + options.level.toUpperCase() + '] ' + (undefined !== options.message ? options.message : '') + 
      (options.meta && Object.keys(options.meta).length ? JSON.stringify(options.meta) : ''); 
} 

var logger = new (winston.Logger)({ 
    transports: [ 
     new (winston.transports.File)({ 
      timestamp: function() { 
       return moment().format(); 
      }, 
      json: false, 
      filename: today + '/test.log', 
      formatter: customFileFormatter 
     }) 
    ] 
}); 

现在我要生成UUID,并将其添加到请求body.So我Middleware.But添加怎么会提供给customFileFormatter格式化功能logger.js每个请求?

当有人使用此记录器记录任何数据时,我希望通过请求将每个日志中的uuid预先记录在记录器格式化程序中。

如果有人需要logger.js

logger.info("Hello"); 
logger.info("Hi"); 

目前以下我有以下日志

2017-02-24T12:36:23 + 05:30 [INFO] “你好”
2017-02-24T12:36:23 + 05:30 [信息] “嗨”

但我想

2017-02-24T12:36:23 + 05:30 [INFO] c00d6800-fa5f-11e6-83c2-f531bfc95472 “你好”
2017-02-24T12:36:23 + 05:30 [INFO ] c00d6800-fa5f-11e6-83c2-f531bfc95472 “嗨”


而且我想根据路线中间件更改记录文件的路径。

目前,当要求从/dstapp来到它使用distributorapp中间件和以后每日志从这个请求转到路径dstapp/2017-02-24/test.log
但是,当请求来自可以说/anotherapp它使用anotherapp中间件和随后的日志从这个请求转到路径anotherapp/2017-02-24/test.log

我走过的每一个地方,但无法找到任何解决方案提前

+0

它在文档中https://github.com/bithavoc/express-winston/blob/master/Readme。 md#request-logging而不是格式化程序你可以添加一个模板字符串 - >'transport:{...},msg:'{{req.uuid}}'' – Molda

+0

@Molda我没有使用express-winston包。我只用了温斯顿。我可以在Winston中添加'{{req.uuid}}',因为我使用格式化程序的回调函数 –

回答

2

感谢我做了ES6 Proxy类似搜索。在中间件中,我生成唯一的requestId并将其添加到app.locals。然后在logger.js我添加的代理处理程序日志功能:

let logProxyHandler = { 
    apply (target, thisArg, args) { 
     var app = getApp(), 
      id = ''; 
     // Some requests do not have unique ID 
     if (app && app.locals && app.locals.requestId) { 
      id = `[${app.locals.requestId}]`; 
     } 
     args[0] = `${id} ${args[0]}`; 
     return Reflect.apply(target, thisArg, args); 
    } 
} 

再补充一点:

logger.info = new Proxy(logger.info, logProxyHandler) 
2

我已经找到办法解决这一点。

在app.js

var logger = require('./locallibs/logger'); 
app.use(logger) 
app.use('/dstapp',distributorapp); 

我logger.js

var winston = require('winston'); 
var fs = require('fs'); 
var moment = require('moment'); 
var today = moment().format('YYYY-MM-DD'); 
var uuid = require('uuid/v1'); 
if (!fs.existsSync(today)) { 
    fs.mkdirSync(today); 
} 


function customFileFormatter(options) { 
    return options.timestamp() + ' [' + options.level.toUpperCase() + '] ' + uuid() + ' ' + (undefined !== options.message ? options.message : '') + 
      (options.meta && Object.keys(options.meta).length ? JSON.stringify(options.meta) : ''); 
} 

winston.remove(winston.transports.Console); 
winston.add(winston.transports.File, 
     { 
      timestamp: function() { 
       return moment().format(); 
      }, 
      json: false, 
      filename: today + '/test.log', 
      formatter: customFileFormatter 
     } 
); 

module.exports = function (req, res, next) { 
    next() 
}; 

在任何文件

var logger = require('winston'); 
logger.info("First Log"); 
logger.info("Second Log"); 

输出是

2017-02-24T18:51:39+05:30 [INFO] 2cf92c90-fa94-11e6-83ba-ebaf5a4e7acd First Log 
2017-02-24T18:51:39+05:30 [INFO] 2cf9c8d0-fa94-11e6-83ba-ebaf5a4e7acd Second Log 
+0

但是这会为相同的请求写入不同的ID,对不对? – MartinGian

1

我不得不面对同样的问题。 我找到了一个解决方案,使用node-uuid库为每个请求生成唯一的uuid,并使用continuation-local-storage库在模块之间共享信息。

1º。我添加了一个中间件的功能,以创建每个请求的UUID并将其添加到我创建的命名空间:

var uuid = require('node-uuid'); 
var createNamespace = require('continuation-local-storage').createNamespace; 
var myRequest = createNamespace('my request'); 

// Run the context for each request. Assign a unique identifier to each request 
app.use(function(req, res, next) { 
    myRequest.run(function() { 
     myRequest.set('reqId', uuid.v1()); 
     next(); 
    }); 
}); 

2º。我裹着温斯顿库打印获得请求的ID,并把它添加到每个日志,是这样的:

var winston = require('winston'); 
var getNamespace = require('continuation-local-storage').getNamespace; 

// Wrap Winston logger to print reqId in each log 
var formatMessage = function(message) { 
    var myRequest = getNamespace('my request'); 
    message = myRequest && myRequest.get('reqId') ? message + " reqId: " + myRequest.get('reqId') : message; 
    return message; 
}; 

var logger = { 
    log: function(level, message) { 
     winstonLogger.log(level, formatMessage(message)); 
    }, 
    error: function(message) { 
     winstonLogger.error(formatMessage(message)); 
    }, 
    warn: function(message) { 
     winstonLogger.warn(formatMessage(message)); 
    }, 
    verbose: function(message) { 
     winstonLogger.verbose(formatMessage(message)); 
    }, 
    info: function(message) { 
     winstonLogger.info(formatMessage(message)); 
    }, 
    debug: function(message) { 
     winstonLogger.debug(formatMessage(message)); 
    }, 
    silly: function(message) { 
     winstonLogger.silly(formatMessage(message)); 
    } 
}; 
module.exports = logger; 

有了这个2个的代码片段,你得到它。 如果你想进一步了解一下,你可以看看这篇文章:https://solidgeargroup.com/express-logging-global-unique-request-identificator-nodejs