我使用Express构建了一个Node JS REST服务。每项针对此服务的请求都有“X-org-ReqId”等标题。 'X-org-Tid'我需要登录在执行此请求期间写入的所有日志行。基本上我需要在每个日志行中记录一些上下文信息,以帮助我通过多种服务进行事务/请求跟踪。
我正在使用像这样初始化的winston logger:
var winston = require('winston');
var appLogger = new(winston.Logger)({
transports: [
new(winston.transports.Console)({
level: 'info', //TODO: Should be changed to Error in prod
colorize: true
}),
new(winston.transports.DailyRotateFile)({
filename: '/var/log/org/my-service.log',
datePattern: '.yyyy-MM-dd',
tailable: true,
// handleExceptions: true,
json: true,
logstash: true
})
],
exitOnError: false
});
appLogger.on('error', function(err) {
console.error("Logger in error", err);
});
module.exports.logger = function() {
return appLogger;
};
在个人课程中,无论我想使用它,我都喜欢这样:
var logger = require('../config/logger').logger();
myObject.on("error", function (err) {
logger.error("Error connecting bucket=" + bucketId , err);
});
这会产生这样的日志:
{"level":"info","message":"Error connecting bucket=2.....","timestamp":"2015-06-10T06:44:48.690Z"}
Winston默认情况下会为此日志语句添加时间戳,但我还想记录req.headers ['X-org-ReqId']& req.headers ['X-org-Tid']以便我知道哪个事务失败了,错误是什么。
我想要这样的日志:
{"level":"info","message":"Error connecting bucket=2....","timestamp":"2015-06-10T06:44:48.690Z", "tid":"a3e8b380-1caf-11e5-9a21-1697f925ec7b", "reqid":"aad28806-1caf-11e5-9a21-1697f925ec7b"}
在java世界中,我们曾经有NDC,在Node JS世界中是否存在等价物?
答案 0 :(得分:0)
我遇到了和你一样的问题。这可能不是最好的做事方式,因为你必须传播“请求”。对象,但它的工作原理。
我愿意得到任何改进:)
首先我在我的' log.js'中覆盖了winston日志记录方法。 :
// MyLogger definition
function MyLogger() {
this.__proto__.__proto__.constructor.apply(this, arguments);
}
// Inheritance
MyLogger.prototype.__proto__ = winston.Logger.prototype;
// Overwriting methods
MyLogger.prototype.log = function() {
var args = [];
// Copying arguments not to modify them
for (var i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
// Adding information in logs
var lastArg = args[arguments.length - 1];
if (typeof lastArg === 'object'
&& lastArg.headers) {
args[arguments.length - 1] = {
// Liste des infos ajoutées dans les logs
requestId: lastArg.headers['x-request-id'] ? lastArg.headers['x-request-id'] : arguments[arguments.length - 1].id,
host: arguments[arguments.length - 1].headers.host,
pId: process.pid
};
}
// Calling super
this.__proto__.__proto__.log.apply(this, args);
}
MyLogger.prototype.error = function() {
var args = ["error"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
MyLogger.prototype.warn = function() {
var args = ["warn"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
MyLogger.prototype.info = function() {
var args = ["info"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
MyLogger.prototype.verbose = function() {
var args = ["verbose"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
MyLogger.prototype.debug = function() {
var args = ["debug"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
MyLogger.prototype.silly = function() {
var args = ["silly"];
for (var i = 0; i < arguments.length; i++) {
args[i + 1] = arguments[i];
}
this.__proto__.log.apply(this, args);
}
var logger = new MyLogger({
transports: [
new winston.transports.File({
level: config.LOG_LEVEL,
filename: config.LOG_FILE,
handleExceptions: true,
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
}),
new winston.transports.Console({
level: config.LOG_LEVEL,
handleExceptions: true,
json: false,
colorize: true
})
],
exitOnError: false
});
module.exports = logger;
然后在每个需要记录的模块中:
var logger = require("../log.js");
...
logger.debug("My message", req);
在日志文件中生成登录控制台和JSON日志,每个信息都需要跟随流。
我的下一步不是要传播“请求”。并从上下文或会话中获取所需的信息。
希望有所帮助:)