Edited at

log4js-node で行番号の付いたログを出力したい!

More than 5 years have passed since last update.

Node.js でアプリケーションを開発している時、簡単なログは

var util = require("util");

console.log(util.inspect(val, {showHidden: true, colors: true, depth: null}));

このように書くか、単純に console.log(val) で出力すると思います。

util.log を使うとタイムスタンプを付けられます。

しかし、アプリケーションの開発が進むと console.log では不便な点が出てきます。


  1. ログレベルを指定したい

  2. 標準出力/標準エラー出力ではなくファイルに出力したい

  3. クリティカルなものはメールで通知したい

  4. ログローテーションしたい

  5. ログを出力している箇所 (ファイル名と行番号) が知りたい

実は、 1~4 までは log4js-node を導入することで可能です。

しかし、単体ではファイル名と行番号を出力することはできません。

そこで、 log4js-node-extend を導入します。

log4js-node を拡張して関数名、ファイル名、行番号、列番号をログに付加することができます。


仕組み

log4js-node-extend でファイル名や行数を取得しているのはこの部分です。

function prepareStackTrace(error, structuredStackTrace) {

var trace = structuredStackTrace[0];
return {
// method name
name: trace.getMethodName() || trace.getFunctionName() || "<anonymous>",
// file name
file: trace.getFileName(),
// line number
line: trace.getLineNumber(),
// column number
column: trace.getColumnNumber()
};
}

function getTrace(caller) {
var original = Error.prepareStackTrace,
error = {};
Error.captureStackTrace(error, caller || getTrace);
Error.prepareStackTrace = prepareStackTrace;
var stack = error.stack;
Error.prepareStackTrace = original;
return stack;
}

getTrace を呼ぶと、 getTrace を呼んだ箇所の関数名、ファイル名、行番号、列番号が得られます。

V8 の JavaScriptStackTraceApi を使うと、例外を throw することも、文字列をパースすることなく、任意の書式でスタックトレースの一部分を得る事ができるんですね。

あとは、 log4js-node のインスタンスメソッドを上書きして、指定された書式でログに付加しています。


参考