在 Express.js 中使用 traceId 记录
Logging with traceId in Express.js
我需要生成带有跟踪 ID 的日志。目前我们正在使用 winston 进行日志记录
我正在使用 winston 容器如下
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) {
if(!meta){
meta = {};
}
meta.component= setting.customise.app_type;
meta.component_version = setting.app_version;
meta.machine = os.hostname();
meta.context = process.pid;
return msg;
});
};
所以在需要做一些记录的文件中,只需做
var sessionTool = require('sessionTool')(app);
var logger = require('winston').loggers.get('defaultLogger');
获取 express 使用 winston
var winstonStream = {
write: function(message, encoding){
logger.info(message.slice(0, -1));
}
};
app.use(express.logger({
stream: winstonStream,
format: ':remote-addr - - :method :url HTTP/:http-version :status :res[content-length] :referrer :user-agent'
}));
我添加了一个捕获所有路由到 get/generate 跟踪 ID
app.all('*', function(req, res, next){
var traceId = req.params['trace_id'];
if(!traceId){
traceId = require('node-uuid').v4();
}
req.params['trace_id'] = traceId;
});
所以问题是:
如何使每个调用的唯一跟踪 ID 在整个应用程序中可用?
更新:
为了确保始终使用跟踪 ID,我正在考虑为每个请求创建一个全局变量,而不是将变量从请求传递到控制器然后再向下传递,因为这意味着每次一个新的控制器或一个引入了服务,那么我们还要记住trace id。
我已经结束使用 continuation-local-storage
来存储 trace_id 并在以后记录时使用它
将以下内容添加到 winston 过滤器
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;
}
并将 app.all() 函数更改为
server.all('*', function(req, res, next) {
var nameSpace = require('continuation-local-storage').getNamespace('nameSpace');
var traceId = req.get(GLOBAL.com.mdsol.csa.traceIdKey);
if (!traceId) {
traceId = uuid.v4();
}
res.header('trace_id', traceId);
nameSpace.run(function() {
nameSpace.set('trace_id', traceId);
});
});
我需要生成带有跟踪 ID 的日志。目前我们正在使用 winston 进行日志记录
我正在使用 winston 容器如下
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) {
if(!meta){
meta = {};
}
meta.component= setting.customise.app_type;
meta.component_version = setting.app_version;
meta.machine = os.hostname();
meta.context = process.pid;
return msg;
});
};
所以在需要做一些记录的文件中,只需做
var sessionTool = require('sessionTool')(app);
var logger = require('winston').loggers.get('defaultLogger');
获取 express 使用 winston
var winstonStream = {
write: function(message, encoding){
logger.info(message.slice(0, -1));
}
};
app.use(express.logger({
stream: winstonStream,
format: ':remote-addr - - :method :url HTTP/:http-version :status :res[content-length] :referrer :user-agent'
}));
我添加了一个捕获所有路由到 get/generate 跟踪 ID
app.all('*', function(req, res, next){
var traceId = req.params['trace_id'];
if(!traceId){
traceId = require('node-uuid').v4();
}
req.params['trace_id'] = traceId;
});
所以问题是: 如何使每个调用的唯一跟踪 ID 在整个应用程序中可用?
更新: 为了确保始终使用跟踪 ID,我正在考虑为每个请求创建一个全局变量,而不是将变量从请求传递到控制器然后再向下传递,因为这意味着每次一个新的控制器或一个引入了服务,那么我们还要记住trace id。
我已经结束使用 continuation-local-storage
来存储 trace_id 并在以后记录时使用它
将以下内容添加到 winston 过滤器
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;
}
并将 app.all() 函数更改为
server.all('*', function(req, res, next) {
var nameSpace = require('continuation-local-storage').getNamespace('nameSpace');
var traceId = req.get(GLOBAL.com.mdsol.csa.traceIdKey);
if (!traceId) {
traceId = uuid.v4();
}
res.header('trace_id', traceId);
nameSpace.run(function() {
nameSpace.set('trace_id', traceId);
});
});