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~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 のインスタンスメソッドを上書きして、指定された書式でログに付加しています。