如何将会话 ID 添加到 winston logger 中的每个日志

How to add session id to each log in winston logger

在我的节点应用程序中,我使用 winston 模块来存储我的应用程序日志。我得到的日志为:

2017-11-22T07:16:38.632Z - info: asset type is attached successfully

现在我想在时间戳之后添加sessionID。我希望我的日志为:

 2017-11-22T07:16:38.632Z -**sessionId here**- info: asset type is attached successfully.

我用于 winston 日志记录的代码是:

var winston = require('winston');
require('winston-daily-rotate-file');
const levels = {
  error: 0,
  warn: 1,
  info: 2,
  http: 3,
  verbose: 4,
  debug: 5,
  silly: 6,
  trace: 7
};

var transport = new (winston.transports.DailyRotateFile)({
  filename: 'logs/./log',
  datePattern: 'yyyy-MM-dd.',
  prepend: true,
  json: false,
  level: process.env.ENV === 'development' ? 'debug' : 'info'
});

var logger = new (winston.Logger)({
  levels: levels,
  transports: [
    transport
  ]
});

module.exports = logger;

您必须自定义日志格式https://github.com/winstonjs/winston/tree/2.x#custom-log-format

首先更新您的交通工具:

var transport = new (winston...
  ...
  level: process.env.ENV === 'development' ? 'debug' : 'info',
  timestamp: () => {
    let today = new Date();
    return today.toISOString();
  },
  formatter: options => `${options.timestamp()} -${options.meta.sessionId}- ${options.level}: ${options.message}`
});

然后,只需将会话 ID 传递给您的记录器 meta 功能:

logger.info('asset type is attached successfully', {sessionId: 'mySessionID'});

你会得到

2017-11-22T14:13:17.697Z -mySessionID- info: asset type is attached successfully

编辑: 我们不只导出 winston.logger 对象,而是导出一个需要 sessionId 作为参数并包含 winston.logger 的对象。我们还更新了传输,因此我们在新的 Logger 对象中自定义其 formatter 属性。在 formatter 属性 中,我们将 meta 声明替换为新的 this.sessionId 变量,所以我们不再使用 meta 属性。

logger.js :

var transport = new (winston...
  ...
  level: process.env.ENV === 'development' ? 'debug' : 'info',
  timestamp: () => {
    let today = new Date();
    return today.toISOString();
  }
});

class Logger {
  constructor(session) {
    this.sessionId = session;
    this.transport = transport;
    this.transport.formatter = options => `${options.timestamp()} -${this.sessionId}- ${options.level}: ${options.message}`;
    this.logger = new (winston.Logger)({
      levels: levels,
      transports: [this.transport]
    });
  }
}

module.exports = Logger;

server.js :

const Logger = require('./logger.js');
let logman = new Logger('my_session_id');
let logger = logman.logger;

logger.info('asset type is attached successfully');

2017-11-23T13:13:08.769Z -my_session_id- info: asset type is attached successfully

我有同样的要求,但对解决方案并不满意...我喜欢标准记录器格式化日志的方式,不想重新发明那个轮子。另外,我希望有更紧凑的东西,我想我找到了。我不是 javascript 程序员,所以这可能不是很好的编码习惯,但它似乎对我很有效...

server.js

//Initiate winston logging please
const logger = require('winston');
const common = require('winston/lib/winston/common');

function myFormat(options) {
  options.formatter = null
  options.label = helpers.getSessionId(logger.req)
  return common.log(options);
}

var consoleLoggingConfig = {
  timestamp: true,
  level: process.env.LOG_LEVEL ? process.env.LOG_LEVEL : "info",
  handleExceptions: true,
  humanReadableUnhandledException: true,
  formatter: myFormat
}

logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, consoleLoggingConfig)
logger.info('Winston logging initiated', consoleLoggingConfig)

//Helper to ensure that logger has access to the request object to obtain the session id
app.use(helpers.attachReqToLogger)
module.exports=logger

helpers.js

// Helper to ensure that the winston logger has the request object on it to obtain the sessionId
helpers.attachReqToLogger = function(req, res, next) {
  logger.req = req
  next();
}
import winston from "winston";
import { v4 as uuidv4 } from "uuid";

const { format } = winston;

const commonFormat = [format.timestamp(), format.json()];

const withId = [
    format.printf(({ message, id, ...rest }) => {

        return JSON.stringify(
            {
                // if frontend privide id, use it, else create one
                id: id ?? uuidv4(),
                message,
                ...rest,
            },
            null,
            // prettyPrint seems will overload printf's output
            // so i mannually do this
            4,
        );
    }),
];

export const logger = winston.createLogger({
    level: "debug",
    format: format.combine(...commonFormat, ...withId),
    // ...