Node.js:Winston:我可以将默认Meta数据添加到所有日志消息中吗

643ylb08  于 2023-10-17  发布在  Node.js
关注(0)|答案(8)|浏览(136)

我在Node.js中使用Winston进行日志记录。我知道我可以将元数据单独添加到每个日志消息中,但是有没有一种方法可以指定一组默认的元数据,这些元数据将被添加到每个日志消息中(例如应用程序名称),因为我不想每次需要发送日志消息时都指定它。

ktecyv1j

ktecyv1j1#

  • 对于温斯顿v2(见评论)*

现在有rewriters
例如,下面的代码将向通过此记录器的每个元数据添加属性app

logger.rewriters.push(function(level, msg, meta) {
      meta.app = 'myApp';
      return meta;
    });

您也可以在构建记录器时声明它:

new (winston.Logger)({
            level: config.log[file].level,
            rewriters: [
                (level, msg, meta) => {
                    meta.app = 'myApp';
                    return meta;
                }
            ],
            transports: [
                /*your transports*/
            ]
    });
pod7payv

pod7payv2#

对于Winston v3:

const addAppNameFormat = winston.format(info => {
  info.appName = "My Program";
  return info;
});

const logger = winston.createLogger({
  format: winston.format.combine(
    addAppNameFormat(),
    winston.format.json()
  ),
transports: [new winston.transports.Console()]
});

logger.warn('Danger Will Robinson!');
// {"message":"Danger Will Robinson!","level":"warn","appName":"My Program"}

参见:https://github.com/winstonjs/winston/blob/HEAD/UPGRADE-3.0.md#migrating-filters-and-rewriters-to-formats-in-winston3

r7xajy2e

r7xajy2e3#

现在(8/20/19)有一个属性defaultMeta被传递给createLogger,它会将您指定的Meta注入到每个日志中。

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'user-service' },
  transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log` 
    // - Write all logs error (and below) to `error.log`.
    //
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});
gk7wooem

gk7wooem4#

没有内置的方法来做到这一点,但你绝对可以自己添加它-这里是如何:
首先,像往常一样设置日志记录器。举例来说:

var logger = new (winston.Logger)({
            "exitOnError" : true,
            "transports" : [
                new (winston.transports.Console)({ "colorize" : true, "level" : "silly", "silent" : false, "handleExceptions" : false }),
            ]
        });

然后覆盖log()方法(这总是由级别方法调用--logger.foo()实际上调用logger.log('foo'))。

logger.log = function(){
  var args = arguments;
  if(args[2]) args[3] = args[2];
  args[2] = {
    "foo" : "bar"
  }
  winston.Logger.prototype.log.apply(this,args);
}

我在上面所做的一切都是为了在调用logger.log()时,它会调用上面的方法,该方法会添加元数据(在本例中,是包含foo键的对象)。然后,它从适当的上下文中调用wlog的Logger.log方法。
上面的代码将在您创建的模块中,在底部只需导出记录器:
module.exports = logger;
并在子类中导入logger模块而不是wlog模块。
var logger = require('./logger.js');
希望能帮上忙!

qlfbtfca

qlfbtfca5#

另一个输出更像log4j(s)的选项:
有一个文档化的label属性,它将向输出(json或line)添加一个标签:

var _ = require('lodash');
var winston = require('winston');
var path = require('path');
var baseDir = path.resolve(__dirname, '..');

// SETUP WINSTON LOGGER
var container = new winston.Container();
container.add("exception", {
    console: {
        handleExceptions: true,
        timestamp: true,
        label: "EXCEPTION",
        colorize: true
    }
});
container.get("exception").exitOnError = false;
var keys = [];
    
module.exports = function(filename) {
    var label = path.relative(baseDir, filename);
    if (!_.contains(keys, label)) {
        container.add(label, {
            console: {
                handleExceptions: false,
                level: 'debug',
                timestamp: true,
                label: label,
                colorize: true
            }
        });
        keys.push(label);
    }
    var logger = container.get(label);
    logger.exitOnError = false;
    return logger;
};

在其他模块中,需要这样做:

var logger = require('./logger')(__filename);

示例输出:

2014-07-23T07:05:27.770Z - info: [config/config.js] .......
jc3wubiy

jc3wubiy6#

我正在寻找一种方法来添加github交付ID到我所有的日志。
我使用wx3和defaultMeta getter,沿着使用express-http-context

// logger.js 
const logger = (filename) => winston.createLogger({
    ...
    defaultMeta: {
        get deliveryId () { return httpContext.get('deliveryId'); },
        get deliveryEvent () { return httpContext.get('deliveryEvent'); },
        module: filename,
    },
    ...
});

module.exports = (fileName) => {
    return logger(fileName);
}

在其他模块中:

// foo.js
const logger = require('./logger')(__filename)

module.exports = async(someInput) => {
    logger.debug('hello ' + someInput)
}

https://github.com/winstonjs/winston/issues/1626#issuecomment-531142958

kq0g1dla

kq0g1dla7#

根据我在这个博客上读到的内容,我发现了一个更好的使用util-extend的方法。它将在所有情况下附加数据,我发现这对捕获logger.info vs logger.log(“info”,message)很有用,并且不会覆盖其他参数。

logger.log = function(){
   var args = arguments;
   var level = args[0];

   var newArgs = {
        foo: "bar",
        baz: "abc"
   };
   var originalMeta = args[2] || {};
   args[2] = extend(originalMeta, newArgs);

   winston.Logger.prototype.log.apply(this,args);
};

将在控制台和日志中输出。

pu3pd22g

pu3pd22g8#

我使用winston@3x,有2个级别的metadatadefaultchild

// logger.ts

const logger = createLogger({
  level:"info",
  defaultMeta: { app: "MyApp" },
  handleExceptions: true,
  format: format.combine(
    format.errors({ stack: true }),
    format.timestamp(),
    format.json()
  ),
  transports: [new transports.Console()],
});

export default function getLogger(childName = ""): Logger {
  if (!childName) {
    return logger;
  }
  return logger.child({ childName });
}
// some-where.ts

const logger = getLogger("OnEarth")
logger.info("dog - bark bark")

--输出-

{
  ....
  level: "info",
  message: "dog - bark bark",
  app: "MyApp",
  childName: "OnEarth"
}

相关问题