2017-02-24 109 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

相關問題