为所有控制台消息添加时间戳

Tra*_*Guy 79 console node.js express

我有一个完整的,部署的,基于Express的项目,其中包含许多console.log()和console.error()语句.该项目永远运行,将stdout和stderr指向2个单独的文件.

这一切都很好,但现在我错过了时间戳 - 确切地知道错误发生的时间.

我可以在我的代码中进行某种搜索/替换,或者在每个文件中使用一些覆盖控制台的npm模块,但我不想触及每个模型/路由文件,除非我绝对必须这样做.

有没有办法,也许是Express中间件,允许我为每次调用添加时间戳,还是我必须手动添加它?

Tra*_*Guy 103

事实证明,您可以覆盖app.js文件顶部的控制台功能,并使其在每个其他模块中生效.我得到了混合的结果,因为我的一个模块是分叉的child_process.一旦我将该行复制到该文件的顶部,一切正常.

为了记录,我安装了模块console-stamp(npm install console-stamp --save),并将此行添加到app.js和childProcess.js的顶部:

// add timestamps in front of log messages
require('console-stamp')(console, '[HH:MM:ss.l]');
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:date连接记录器的格式使用UTC格式,而不是我在其他控制台调用中使用的格式.这很容易通过注册我自己的时间格式来解决(作为副作用,需要附带的dateformat模块console stamp,而不是安装另一个模块):

// since logger only returns a UTC version of date, I'm defining my own date format - using an internal module from console-stamp
express.logger.format('mydate', function() {
    var df = require('console-stamp/node_modules/dateformat');
    return df(new Date(), 'HH:MM:ss.l');
});
app.use(express.logger('[:mydate] :method :url :status :res[content-length] - :remote-addr - :response-time ms'));
Run Code Online (Sandbox Code Playgroud)

现在我的日志文件看起来有条理(更好,可解析):

[15:09:47.746] staging server listening on port 3000
[15:09:49.322] connected to database server xxxxx successfully
[15:09:52.743] GET /product 200 - - 127.0.0.1 - 214 ms
[15:09:52.929] GET /stylesheets/bootstrap-cerulean.min.css 304 - - 127.0.0.1 - 8 ms
[15:09:52.935] GET /javascripts/vendor/require.js 304 - - 127.0.0.1 - 3 ms
[15:09:53.085] GET /javascripts/product.js 304 - - 127.0.0.1 - 2 ms
...
Run Code Online (Sandbox Code Playgroud)

  • 我找不到它的文档,但似乎":mm"将引用月份,":MM"是您实际想要使用的格式 (2认同)
  • 你应该根据@ user603124的内容更改分钟部分.几分钟,字符串是**:MM**(https://github.com/starak/node-console-stamp) (2认同)
  • 好像你不再需要在括号中包裹HH:MM:ss.l - 它是自动执行的 (2认同)
  • FYI`logger`已由`morgan` https://github.com/senchalabs/connect#middleware取代 (2认同)

And*_*ren 23

使用以下内容创建文件:

var log = console.log;

console.log = function(){
  log.apply(console, [Date.now()].concat(arguments));
};
Run Code Online (Sandbox Code Playgroud)

在记录任何内容之前,请在您的应用中使用它 console.error如果需要,也可以这样做.

请注意,console.log("he%s", "y") // "hey"如果您正在使用此解决方案,则会破坏变量insertion().如果您需要,请先记录时间戳:

log.call(console, Date.now());
log.apply(console, arguments);
Run Code Online (Sandbox Code Playgroud)

  • 不是,如果它是相同的应用程序/过程.控制台是一个全局对象,所以如果你劫持它的一个功能,它将继续被共享该全局对象的所有文件劫持. (2认同)
  • 是的。<最少 15 个字符...> (2认同)

Sun*_*Wei 19

module:"log-timestamp"对我有用.

请参阅 https://www.npmjs.com/package/log-timestamp

npm install log-timestamp
Run Code Online (Sandbox Code Playgroud)

简单易用

console.log('Before log-timestamp');
require('log-timestamp');
console.log('After log-timestamp');
Run Code Online (Sandbox Code Playgroud)

结果

Before log-timestamp
[2012-08-23T20:08:32.000Z] After log-timestamp
Run Code Online (Sandbox Code Playgroud)


les*_*usz 10

如果您想要一个没有其他外部依赖关系的解决方案,但是您希望保留console.log(多个参数,变量插入)的完整功能,则可以使用以下代码:

var log = console.log;

console.log = function () {
    var first_parameter = arguments[0];
    var other_parameters = Array.prototype.slice.call(arguments, 1);

    function formatConsoleDate (date) {
        var hour = date.getHours();
        var minutes = date.getMinutes();
        var seconds = date.getSeconds();
        var milliseconds = date.getMilliseconds();

        return '[' +
               ((hour < 10) ? '0' + hour: hour) +
               ':' +
               ((minutes < 10) ? '0' + minutes: minutes) +
               ':' +
               ((seconds < 10) ? '0' + seconds: seconds) +
               '.' +
               ('00' + milliseconds).slice(-3) +
               '] ';
    }

    log.apply(console, [formatConsoleDate(new Date()) + first_parameter].concat(other_parameters));
};
Run Code Online (Sandbox Code Playgroud)

您可以修改formatConsoleDate函数以格式化日期的方式.

此代码只需在主JavaScript文件之上编写一次.

console.log("he%s", "y") 将打印这样的东西:

[12:22:55.053] hey
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这个“无依赖”的答案正是我所需要的。 (4认同)
  • 该解决方案无法输出对象。它将简单地输出“[Object object]”。不要连接时间戳和first_parameter,只需将它们视为两个参数:`log.apply(console, [formatConsoleDate(new Date()),first_parameter].concat(other_parameters));`(将'+'替换为',' ) (4认同)

Che*_*tan 9

您还可以使用log-timestamp包.它非常简单,也可以自定义.


Geo*_* Y. 7

此实现很简单,支持 console.log 的原始功能(传递单个对象和变量替换),不使用外部模块并在对 console.log 的单次调用中打印所有内容:

var origlog = console.log;

console.log = function( obj, ...placeholders ){
    if ( typeof obj === 'string' )
        placeholders.unshift( Date.now() + " " + obj );
    else
    {
        // This handles console.log( object )
        placeholders.unshift( obj );
        placeholders.unshift( Date.now() + " %j" );
    }

    origlog.apply( this, placeholders );
};
Run Code Online (Sandbox Code Playgroud)


小智 7

如果您愿意,您可以通过扩展“Console”类中的节点构建来为您的应用程序创建自定义记录器。请参考下面的实现

"use strict";

const moment = require('moment');
const util = require('util');
const Console = require('console').Console;

class Logger extends Console {
    constructor(stdout, stderr, ...otherArgs) {
        super(stdout, stderr, ...otherArgs);
    }

    log(...args) {
        super.log(moment().format('D MMM HH:mm:ss'), '-', util.format(...args));
    }

    error(...args) {
        super.error(moment().format('D MMM HH:mm:ss'), '-', util.format(...args));
    }
}

module.exports = (function() {
    return new Logger(process.stdout, process.stderr); 
}());
Run Code Online (Sandbox Code Playgroud)

之后,您可以在代码中使用它:

const logger = require('./logger');

logger.log('hello world', 123456);
logger.error('some error occurred', err);
Run Code Online (Sandbox Code Playgroud)


小智 5

为了避免安装外部模块,一种更基本的方法可以实现一个简单的功能,例如:

function timeStamp(message){
    console.log ( '[' + new Date().toISOString().substring(11,23) + '] -', message )
}
Run Code Online (Sandbox Code Playgroud)

然后我简单地这样称呼它:

timeStamp('this is my logline!!');
Run Code Online (Sandbox Code Playgroud)

结果将是:

 LOG  [15:22:30.682] - this is my logline!!
Run Code Online (Sandbox Code Playgroud)

当然,您可以将日期格式化为您需要的最佳格式,并将功能扩展到console.error、debug等。