web-dev-qa-db-ja.com

すべてのコンソールメッセージにタイムスタンプを追加する

完全なdeployed、Expressベースのプロジェクトがあり、多くのconsole.log()およびconsole.error()ステートメントがあります。プロジェクトは永久に実行され、stdoutとstderrを2つの別々のファイルに送ります。

すべてうまくいきますが、エラーがいつ発生したかを正確に知るために、タイムスタンプが欠落しています。

コード全体で何らかの種類の検索/置換を行うか、各ファイルのコンソールをオーバーライドするnpmモジュールを使用できますが、絶対に必要な場合を除き、すべてのモデル/ルートファイルに触れたくありません。

Expressミドルウェアのような方法で、行われたすべての呼び出しにタイムスタンプを追加できますか、それとも手動で追加する必要がありますか?

77

判明したのは、can app.jsファイルの上部にあるコンソール関数をオーバーライドし、他のすべてのモジュールで有効にすることです。モジュールの1つが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]');

私の問題は、接続ロガーの:date形式が、他のコンソール呼び出しで使用している形式ではなくUTC形式を使用していることです。これは、独自の時間形式を登録することで簡単に修正されました(副作用として、別のモジュールをインストールするのではなく、console stampに付属するdateformatモジュールが必要です)。

// 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'));

ログファイルが整理されたようになりました(さらに良いのは、解析可能):

[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
...
103

次のファイルを作成します。

var log = console.log;

console.log = function(){
  log.apply(console, [Date.now()].concat(arguments));
};

何かを記録する前に、アプリでそれを要求します。必要に応じて、console.errorに対して同じことを行います。

このソリューションを使用している場合、変数の挿入(console.log("he%s", "y") // "hey")が破棄されることに注意してください。必要な場合は、最初にタイムスタンプを記録するだけです。

log.call(console, Date.now());
log.apply(console, arguments);
23

モジュール:「log-timestamp」は私のために働きます。

https://www.npmjs.com/package/log-timestamp を参照してください

npm install log-timestamp

使いやすい

console.log('Before log-timestamp');
require('log-timestamp');
console.log('After log-timestamp');

結果

Before log-timestamp
[2012-08-23T20:08:32.000Z] After log-timestamp
14
Sunding Wei

log-timestamp パッケージを使用することもできます。それは非常に簡単で、同様にカスタマイズ可能です。

9
Chetan

別の外部依存関係のないソリューションが必要で、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));
};

FormatConsoleDate関数を変更して、希望する方法で日付をフォーマットできます。

このコードは、メインJavaScriptファイルの上に1回だけ記述する必要があります。

console.log("he%s", "y")は次のようなものを出力します:

[12:22:55.053] hey
8
leszek.hanusz
app.use(morgan('[:date[web]] :method :url :status :res[content-length] - :remote-addr - :response-time ms'))
3
thxmxx

https://nodejs.org/api/util.html の関数util.logを使用できます。

1
mlosev

この実装は単純で、console.logの元の機能(単一のオブジェクトの受け渡し、変数の置換)をサポートし、外部モジュールを使用せず、console.logの1回の呼び出しですべてを出力します。

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 );
};
1
George Y.

これは直接的な答えではありませんが、winston.jsを検討しましたか? jsonファイルまたはデータベースへのロギングを含む、さらに多くのロギングオプションがあります。これらは常にデフォルトでタイムスタンプを持っています。ちょっとした考え。

このようなイベントリスナーを使用して、

process.on('error', function() { 
   console.log('Error Occurred.');

   var d = Date(Date.now()).toString();
   console.log.call(console, d); // Wed Aug 07 2019 23:40:07 GMT+0100 (GMT+01:00)
});

ハッピーコーディング:)

0
JsWizard