Node.js-日志记录/使用Morgan和Winston


99

我们用于morgan记录快速转换:

var morgan  = require('morgan');
morgan('combined');
// a format string
morgan(':remote-addr :method :url :uuid');
// a custom function
morgan(function (req, res) {
  return req.method + ' ' + req.url + ' ' + req.uuid;
})

另外,我们winston为了记录其他日志记录而使用:

var winston = require('winston');
var logger = new (winston.Logger)({
  transports: [
         new (winston.transports.Console)({ level: 'info' }),
          new (winston.transports.File)({ filename: '/var/log/log-file.log' })
  ]
});

有什么办法可以将两个记录器组合在一起?现在的情况morgan是写入时winston写入我的标准输出/var/log/log-file.log

我希望记录器文件将结合明确的转换信息和我想要的其他信息(logger.info())。


我的意思是,这样做的目的是什么,为什么您在开始时需要摩根大通,为什么不只是写一个winston Middlewrare做快递呢?
Dimitri Kopriwa

Answers:


141

本文对您想做的事情做得很好。

http://tostring.it/2014/06/23/advanced-logging-with-nodejs/

对于您的特定代码,您可能需要这样的东西:

var logger = new winston.Logger({
    transports: [
        new winston.transports.File({
            level: 'info',
            filename: './logs/all-logs.log',
            handleExceptions: true,
            json: true,
            maxsize: 5242880, //5MB
            maxFiles: 5,
            colorize: false
        }),
        new winston.transports.Console({
            level: 'debug',
            handleExceptions: true,
            json: false,
            colorize: true
        })
    ],
    exitOnError: false
});

logger.stream = {
    write: function(message, encoding){
        logger.info(message);
    }
};

app.use(require("morgan")("combined", { "stream": logger.stream }));

这将设置Winston将日志和文件写入日志。然后,您可以使用最后一个表达式将来自摩根中间件的输出传递给Winston。


我们可以在此过程中使用时间戳吗?
bombayquant

23
似乎没有必要重写logger.stream。.就我而言,我能够做到app.use(morgan("combined", { stream: { write: message => logger.info(message) }}));
Devon Sams

17
如果使用@DevonSams的方法,则记录的行之间将出现空行,因为morgan和winston都在记录的消息末尾添加了换行符。你可以简单地从消息修剪断行了logger.info(message.trim())
蒂莫

2
如果服务器响应500,我想使用logger.error而不是logger.info怎么办?
阿伦多夫

3
对于winston: ^3.0.0使用winston.createLogger代替new winston.Logger
streof

21

在打字稿中:

let logger = new (winston.Logger)({
    exitOnError: false,
    level: 'info',
    transports: [
        new (winston.transports.Console)(),
        new (winston.transports.File)({ filename: 'app.log'})
    ]
})

class MyStream {
    write(text: string) {
        logger.info(text)
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));

为什么很小而不合并?
An-droid

我再也无法使用它了。看来输入不正确。stackoverflow.com/questions/50048193/…–
jpetitte

7

更新最后一行以删除警告

app.use(require("morgan")("combined", { stream: logger.stream }));

3

对于Typescript,无需创建类的另一种方法是

let logger = new (winston.Logger)({
    exitOnError: false,
    level: 'info',
    transports: [
        new (winston.transports.Console)(),
        new (winston.transports.File)({ filename: 'app.log'})
    ]
})

const myStream = {
    write: (text: string) => {
        logger.info(text)
    }
}

app.use(morgan('combined', { stream: myStream }));

该解决方案是从Github页面https://github.com/winstonjs/winston/issues/1385中拆分的。但是,请务必注意,我们的代码之间存在细微差别。代替:

app.use(morgan('combined', { myStream }));

我用:

app.use(morgan('combined', { stream: myStream }));

这对我的帮助不大,因为我在创建类上不是很大。


1

摩根(Morgan)有个坏习惯,即以一个结尾来结束消息,\n以便使事情井井有条,您可能需要在将其写入Winston之前将其删除。

这可以通过许多不同的方式来完成,例如在winston的格式方面,或者通过更新流以不编写 \n

class MyStream {
    write(text: string) {
        logger.info(text.replace(/\n$/, ''));
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.