Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Node.js库Winston向日志添加时间戳?_Node.js_Logging_Winston - Fatal编程技术网

如何使用Node.js库Winston向日志添加时间戳?

如何使用Node.js库Winston向日志添加时间戳?,node.js,logging,winston,Node.js,Logging,Winston,我想给日志添加时间戳。实现这一目标的最佳方法是什么?虽然我不知道温斯顿,但这是一个建议。我用于日志记录&默认情况下,我的日志如下所示 [2012-04-23 16:36:02.965] [INFO] Development - Node Application is running on port 8090 [2012-04-23 16:36:02.966] [FATAL] Development - Connection Terminated to '127.0.0.1' '6379' 开

我想给日志添加时间戳。实现这一目标的最佳方法是什么?

虽然我不知道温斯顿,但这是一个建议。我用于日志记录&默认情况下,我的日志如下所示

[2012-04-23 16:36:02.965] [INFO] Development - Node Application is running on port 8090
[2012-04-23 16:36:02.966] [FATAL] Development - Connection Terminated to  '127.0.0.1' '6379'
开发是我的节点进程的环境&[INFO | FATAL]是日志级别的

在log4js中可以维护不同的日志配置文件。我有开发和生产概况。还有一些记录器类型,如滚动文件appender、控制台appender等。作为一个插件,您的日志文件将根据日志级别[跟踪、信息、调试、错误、致命];)


log4js将覆盖您的console.log它现在是0.5+中的一个可配置参数

我自己也在处理同样的问题。我有两种方法可以做到这一点

当您包括Winston时,它通常默认为添加控制台传输。为了使时间戳在这种默认情况下工作,我需要:

  • 卸下控制台传输并使用时间戳选项再次添加
  • 创建自己的记录器对象,将timestamp选项设置为true
  • 第一:

    var winston = require('winston');
    winston.remove(winston.transports.Console);
    winston.add(winston.transports.Console, {'timestamp':true});
    
    第二,更干净的选择:

    var winston = require('winston');
    var logger = new (winston.Logger)({
        transports: [
          new (winston.transports.Console)({'timestamp':true})
        ]
    });
    
    控制台传输的其他一些选项可以找到:

    • 级别:此传输应记录的消息级别(默认为“调试”)
    • 静默:指示是否抑制输出的布尔标志(默认为false)
    • colorize:指示是否应该为输出着色的布尔标志(默认为false)
    • timestamp:布尔标志,指示是否应在输出前加上时间戳(默认为false)。如果指定了函数,则将使用其返回值而不是时间戳
    您可以使用内置的和,通过timestap为您的nodejs服务器实现日志记录。 启动服务器时,将日志输出添加为参数的一部分:

    forever start -ao log/out.log server.js
    
    然后可以在server.js中编写util

    server.js

    var util = require('util');
    util.log("something with timestamp");
    
    out.log文件的输出如下所示:

    {"t":"2020-08-06 08:02:05","l":"info","m":"app is running on port 3001","s":""},
    
    out.log

    15 Mar 15:09:28 - something with timestamp
    

    我们可以使用控制台戳向现有控制台添加时间戳和日志级别:
    require('console-stamp')(控制台,[yyyy-mm-dd HH:mm:ss.l])


    有关详细信息,请参见

    有时默认的时间戳格式可能对您不方便。 您可以用您的实现覆盖它

    而不是

    var winston = require('winston');
    var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({'timestamp':true})
    ]
    });
    
    你可以写

    var winston = require('winston');
    var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({
         'timestamp': function() {
            return <write your custom formatted date here>;
         }
      })
    ]
    });
    
    var winston=require('winston');
    var记录器=新(winston.logger)({
    运输:[
    新建(winston.transports.Console)({
    “时间戳”:函数(){
    返回;
    }
    })
    ]
    });
    

    有关详细信息,请参见

    以上答案对我不适用。如果您试图使用最新版本的Winston-3.0.0-rc1将时间戳添加到日志中,这就像:

        const {transports, createLogger, format} = require('winston');
    
        const logger = createLogger({
            format: format.combine(
                format.timestamp(),
                format.json()
            ),
            transports: [
                new transports.Console(),
                new transports.File({filename: 'logs/error/error.log', level: 'error'}),
                new transports.File({filename: 'logs/activity/activity.log', level:'info'})
            ]
        });
    
    我使用了“format.combine()”。因为我在所有传输上都需要时间戳,所以我在createLogger中添加了格式化选项,而不是在每个传输中。我在控制台和文件(activity.log)上的输出如下:

    {"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}
    {"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}
    
    我们可以像往常一样使用“format.combine()”将格式添加到此时间戳,方法是:

    format.timestamp({format:'MM-YY-DD'})
    

    我们也可以这样做

    var winston=require('winston');
    const{createLogger,format,transports}=require('winston');
    var config=require('../configurations/envconfig.js');
    var loggerLevel=process.env.loggerLevel | | config.get('loggerLevel');
    var logger=winston.createLogger({
    格式:format.combine(
    格式.时间戳({
    格式:“YYYY-MM-DD HH:MM:ss”
    }),
    format.printf(info=>`${info.timestamp}${info.level}:${info.message}`+(info.splat!==未定义?`${info.splat}`:“”)
    ),
    运输:[
    新的(winston.transports.Console)({level:loggerLevel}),
    ]
    });
    module.exports=记录器;
    
    另一种解决方案是将记录器包装到一个文件中,该文件导出一些函数,如logger.info()、logger.error()等。然后您只需在每个消息日志上传递一个额外的密钥即可

    loggerService.js

    const logger = winston.createLogger({ ... })
    
    function handleLog(message, level) {
      const logData = {
        timestamp: Date.now(),
        message,
      }
    
      return logger[level](logData)
    }
    
    function info(message) {
      handleLog(message, 'info')
    }
    
    function error(message) {
      handleLog(message, 'error')
    }
    
    function warn(message) {
      handleLog(message, 'warn')
    }
    
    module.exports = {
      info,
      error,
      warn
    }
    
    不管是什么-file.js

    const logger = require('./services/loggerService')
    
    logger.info('Hello World!')
    
    你的-log.log

    {"timestamp":"2019-08-21 06:42:27","message":"Hello World!","level":"info"}
    

    我接受了Biswadev的答案,创建了一个字符串化的JSON对象。这样,如果我以后需要处理日志,它将采用结构良好的格式

    const winston = require('winston');
    const { createLogger, format, transports } = require('winston');
    
    const dotenv = require('dotenv');
    dotenv.config();
    
    var logger = createLogger({
        level: 'info',
        format: format.combine(
            format.timestamp({
                format: 'YYYY-MM-DD HH:mm:ss',
            }),
            format.printf((info) =>
                JSON.stringify({
                    t: info.timestamp,
                    l: info.level,
                    m: info.message,
                    s: info.splat !== undefined ? `${info.splat}` : '',
                }) + ','
            )
        ),
    });
    
    if (process.env.NODE_ENV !== 'PRODUCTION') {
        logger.add(new transports.Console({ format: winston.format.cli() }));
    
        // Turn these on to create logs as if it were production
        // logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
        // logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
        // logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
    } else {
        logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
        logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
        logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
    }
    
    module.exports = {
        logger,
    };
    
    用法:

    app.listen(port, () => logger.info(`app is running on port ${port}`));
    
    输出:

    app.listen(port, () => logger.info(`app is running on port ${port}`));
    
    info.log文件:

    {"t":"2020-08-06 08:02:05","l":"info","m":"app is running on port 3001","s":""},
    
    控制台:

    info:    app is running on port 3001
    

    令人惊奇的同时也很简单。非常感谢。这太棒了。我通常将其包装在一个专用文件中,以便可以轻松地从任何文件获取配置的记录器,即,我将上述代码(选项2)放入一个新文件logger.js中,然后是module.exports=logger;然后从任何文件中,我执行var logger=require('./logger.js'),然后可以从任何文件中执行logger.info('hello'),并获得与Winston.TypeError相同的配置:(中间值)不是一个函数这在当前版本的Winston中似乎不起作用。请尝试其他答案。仅供参考:log4js node(0.5+)的较新版本不会自动覆盖console.log。@jeffhiltz Ya您是对的:)现在它是一个可配置的参数不幸的是,
    util.error()
    跳过输出的时间戳。这仍然太宽,因为无法从客户端计算机执行。这是否也适用于
    logger.info('Message',someObject)
    ?我使用combine设置了一个自定义格式,但似乎无法获取日志消息中包含的
    someObject
    。我能够通过使用以下printf语句
    ${info.timestamp}[${info.level.toUpperCase()}]:${info.message}${JSON.stringify(info)}
    获取包含的
    someObject
    。它包括级别、时间戳和消息,我想我可以删除它们。。。复制粘贴解决方案!!但它不向文件传输添加时间戳。