情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsでwinstonを使ってログを出力する

ログを出力するには下のようなモジュールを利用する方法があります。

  • log
  • npmlog
  • bunyan
  • winston
  • log4js

この記事ではwinstonモジュールを利用する方法を取り上げます。

ログのレベル

一般的に、ログにはレベルという属性があり、ログの重要さを表します。

winstonモジュールの場合、重要さが最も高いものから順に下のようなレベルがあります。

  • error・・・問題が発生したことを示します。
  • warn・・・注意すべき事象が発生したことを示します。
  • info・・・情報であることを示します。
  • vervose・・・冗長な情報であることを示します。
  • debug・・・デバッグ用の情報であることを示します。
  • silly・・・些末な情報であることを示します。

レベルは内部的には下のような数値で表されています。

  • error・・・0
  • warn・・・1
  • info・・・2
  • vervose・・・3
  • debug・・・4
  • silly・・・5

winstonモジュールはsyslogのログのレベルにも標準で対応しています。

syslogのログのレベルの場合、重要さが最も高いものから順に下のようなレベルがあります。

  • emerg・・・アプリケーションが利用不可であることを示します。
  • alert・・・すぐに対処が必要であることを示します。
  • crit・・・重大な問題が発生したことを示します。
  • error・・・問題が発生したことを示します。
  • warning・・・注意すべき事象が発生したことを示します。
  • notice・・・重大な情報であることを示します。
  • info・・・情報であることを示します。
  • debug・・・デバッグ用の情報であることを示します。

レベルは内部的には下のような数値で表されています。

  • emerg・・・0
  • alert・・・1
  • crit・・・2
  • error・・・3
  • warning・・・4
  • notice・・・5
  • info・・・6
  • debug・・・7

winstonモジュールでは1つのレベルに1つの色を対応付けることができます。この色はログの出力の際に利用されることがあります。

レベルと色の対応付けを追加するにはwinston.addColors関数を使用します。

var winston = require('winston');

winston.addColors({
    foo: 'red', 
    bar: 'green'
});

第1引数にレベルと色の対応付けをオブジェクトとして指定します。オブジェクトのプロパティ名にレベルの名称を指定し、プロパティの値に色を指定します。

ログの出力先

winstonモジュールの場合、ログは1個以上の出力先に出力されます。

winstonモジュールでは出力先を表すオブジェクトのコンストラクタとして下のようなものが提供されています。

  • winston.transports.Console・・・標準出力や標準エラー出力にログを出力します。
  • winston.transports.File・・・ファイルや書き込みストリームにログを出力します。

これらのコンストラクタの第1引数にはオプションをオブジェクトとして指定します。

オプションには下のようなものがあります。

  • name・・・名称を指定します。
  • level・・・レベルを指定します。このレベルより高いレベルのログはこの出力先には出力されなくなります。デフォルトはinfoです。
  • silent・・・全てのログを出力しないかを真偽値として指定します。デフォルトはfalseです。
  • colorize・・・ログを着色するかを真偽値として指定します。デフォルトはfalseです。
  • timestamp・・・ログの冒頭に日時を付加するかを真偽値として指定します。デフォルトはfalseです。あるいは、真偽値の代わりに関数を指定することもできます。関数を指定した場合には日時の代わりに関数の返り値が付加されます。
  • filename・・・出力先のファイル名を指定します。winston.transports.Fileコンストラクタのみのオプションです。
  • maxsize・・・出力先のファイルの最大サイズを指定します。ファイルがこのサイズを超過した場合には新しいファイルが作成されます(ファイル名の末尾に連番が付されます)。winston.transports.Fileコンストラクタのみのオプションです。
  • maxFiles・・・出力先のファイルの最大数を指定します。winston.transports.Fileコンストラクタのみのオプションです。
  • stream・・・出力先の書き込みストリームを指定します。winston.transports.Fileコンストラクタのみのオプションです。
  • json・・・ログをJSONとして出力するかを真偽値として指定します。デフォルトはwinston.transports.Consoleコンストラクタの場合にはfalseであり、winston.transports.Fileコンストラクタの場合にはtrueです。
  • stringify・・・ログをJSON文字列として出力するかを真偽値として指定します。ただし、jsonオプションがfalseである場合には無視されます。winston.transports.Consoleコンストラクタのみのオプションです。デフォルトはfalseです。
  • prettyPrint・・・メタデータをutil.inspect関数を使用して文字列化するかを真偽値として指定します。あるいは、メタデータを文字列化する処理を関数として指定することもできます。
  • depth・・・メタデータを文字列化する際に指定するutil.inspect関数のdepthオプションを指定します。ただし、prettyPrintオプションがtrueでない場合には無視されます。デフォルトはnullです。
  • showLevel・・・レベルを出力するかを真偽値として指定します。デフォルトはtrueです。
  • formatter・・・ログのフォーマット処理を関数として指定します。この関数の第1引数はログを表すオブジェクトです。timestampプロパティに日時が格納され、levelプロパティにレベルが格納され、messageプロパティにメッセージが格納され、metaプロパティにメタデータが格納されます。ただし、jsonオプションがtrueである場合には無視されます。
  • maxRetries・・・出力先のファイルに対する書き込みストリームの作成を最大で何回試行するかを指定します。winston.transports.Fileコンストラクタのみのオプションです。
  • zippedArchive・・・古い出力先のファイルをzip圧縮するかを真偽値として指定します。winston.transports.Fileコンストラクタのみのオプションです。
  • stderrLevels・・・標準エラー出力に出力するログのレベルを配列として指定します。これら以外のレベルのログは標準出力に出力されます。winston.transports.Consoleコンストラクタのみのオプションです。デフォルトは['error', 'debug']です。
  • options・・・出力先のファイルに対する書き込みストリームを作成する際に指定するfs.createWriteStream関数のオプションをオブジェクトとして指定します。winston.transports.Fileコンストラクタのみのオプションです。デフォルトは{ flags: 'a' }です。
  • handleExceptions・・・未処理の例外が発生した場合にログを出力するかを真偽値として指定します。デフォルトはfalseです。
  • humanReadableUnhandledException・・・未処理の例外が発生した場合に出力するログを人間に読みやすい形式で出力するかを真偽値として指定します。ただし、handleExceptionsオプションがfalseである場合には無視されます。デフォルトはfalseです。

ロガーの作成

winstonモジュールの場合、ログを出力するにはまずロガーを作成しなければなりません。

ロガーを作成するにはwinston.Loggerクラスのコンストラクタを使用します。

var logger = new winston.Logger({
    levels: {
        foo: 0, 
        bar: 1
    }, 
    level: 'info', 
    transports: [
        new winston.transports.Console({
            name: 'aaa', 
            level: 'bbb'
        }), 
        new winston.transports.File({
            name: 'ccc', 
            level: 'ddd', 
            filename: 'eee' 
        })
    ]
});

第1引数にオプションをオブジェクトとして指定します。

オプションには下のようなものがあります。

  • levels・・・レベルの定義をオブジェクトとして指定します。オブジェクトのプロパティ名にレベルの名称を指定し、プロパティの値にレベルの数値を指定します。syslogのログのレベルを使用する場合にはwinston.config.syslog.levelsを指定します。
  • level・・・レベルを指定します。このレベルより高いレベルのログはこのロガーでは出力されなくなります。デフォルトはinfoです。
  • transports・・・出力先を表すオブジェクトを配列として指定します。

返り値としてロガーが得られます。

以後ロガーをloggerと表記します。

ロガーの変更

ロガーのオプションを変更するにはlogger.configure関数を使用します。

logger.configure.({
    levels: {
        foo: 0, 
        bar: 1
    }, 
    level: 'info', 
    transports: [
        new winston.transports.Console({
            name: 'aaa', 
            level: 'bbb'
        }), 
        new winston.transports.File({
            name: 'ccc', 
            level: 'ddd', 
            filename: 'eee' 
        })
    ]
});

第1引数にオプションをオブジェクトとして指定します。

ロガーのlevelsオプションを変更するにはlogger.setLevels関数を使用することもできます。

logger.setLevels({
    foo: 0, 
    bar: 1
});

第1引数にレベルの定義をオブジェクトとして指定します。

ロガーのlevelオプションを変更するにはlogger.levelプロパティにレベルの名称を設定することもできます。

logger.level = 'xxx';

ロガーに出力先を追加するにはlogger.add関数を使用します。

logger.add(winston.transports.Console, {
    name: 'aaa', 
    level: 'bbb'
});
logger.add(winston.transports.File, {
    name: 'aaa', 
    level: 'bbb', 
    filename: 'ccc'
});

第1引数に出力先を表すオブジェクトのコンストラクタを指定します。

第2引数にオプションをオブジェクトとして指定します。

ロガーから出力先を削除するにはlogger.remove関数を使用します。

logger.remove('xxx');

第1引数に出力先を表すオブジェクトそのものかオブジェクトの名称を指定します。

ログの出力

ログを出力するにはlogger.log関数を使用します。

logger.log('xxx', 'yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});

第1引数にレベルを指定します。

第2引数にメッセージを指定します。このメッセージには書式指定文字列(%s%d%jなど)を含めることもできます。

第3引数以降に第2引数のメッセージの書式指定文字列に順番に埋め込む値を指定します。この引数は指定しなくても構いません。

最後から2番目の引数にメタデータをオブジェクトとして指定します。この引数は指定しなくても構いません。

最後の引数にコールバック関数を指定します。この引数は指定しなくても構いません。この関数の第1引数はエラーオブジェクトであり、第2引数はレベルであり、第3引数はメッセージであり、第4引数はメタデータです。

あるいは、レベルに応じてレベルの名称と同じ名称のロガーの関数を使用することもできます。独自に追加したレベルに関してもレベルの名称と同じ名称の関数を使用することができます

logger.error('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});
logger.warn('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});
logger.info('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});
logger.verbose('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});
logger.debug('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});
logger.silly('yyy', 'aaa', 'bbb', { foo: 'ccc', bar: 'ddd' }, function (err, level, msg, meta) {
});

第1引数にメッセージを指定します。このメッセージには書式指定文字列(%s%d%jなど)を含めることもできます。

第2引数以降に第1引数のメッセージの書式指定文字列に順番に埋め込む値を指定します。この引数は指定しなくても構いません。

最後から2番目の引数にメタデータをオブジェクトとして指定します。この引数は指定しなくても構いません。

最後の引数にコールバック関数を指定します。この引数は指定しなくても構いません。この関数の第1引数はエラーオブジェクトであり、第2引数はレベルであり、第3引数はメッセージであり、第4引数はメタデータです。

なお、CLIに適した形式でログの出力を行うようにするにはlogger.cli関数を使用します。

logger.cli();

logger.cli関数の呼び出し以降に出力されるログはCLIに適した形式で出力されます。

イベント

winstonモジュールの場合、ログが出力された際にはロガーのloggingイベントが発生します。

このイベントのイベントハンドラの第1引数はログの出力先を表すオブジェクトであり、第2引数はレベルであり、第3引数はメッセージであり、第4引数はメタデータです。

なお、ロガーでエラーが発生した場合にはerrorイベントが発生します。

ただし、ロガーでerrorイベントが発生しないように設定することもできます。

ロガーでerrorイベントが発生しないように設定するにはlogger.emitErrsプロパティにfalseを指定します。

logger.emitErrs = false;

デフォルトロガー

winstonモジュールではデフォルトのロガーが提供されています。

デフォルトのロガーはwinstonプロパティに設定されています。

デフォルトのロガーは下のようなオプションのものとなっています。

  • level・・・infoが指定されています。
  • transports・・・winston.transports.Consoleコンストラクタのインスタンスが1つ指定されています。

サンプルコード1

winston.js

var winston = require('winston');

winston.log('info', 'yukari desu.');
winston.log('info', '%s desu.', 'pizyumi');
winston.log('info', '%s desu.', 'pizyumi', { foo: 100, bar: 200 });

winston.error('error.');
winston.warn('warn.');
winston.info('info.');
winston.verbose('verbose.');
winston.debug('debug.');
winston.silly('silly.');

winston.level = 'debug';

winston.error('error.');
winston.warn('warn.');
winston.info('info.');
winston.verbose('verbose.');
winston.debug('debug.');
winston.silly('silly.');

var logger = new winston.Logger({
    transports: [
        new winston.transports.Console({
            name: 'con1', 
            level: 'error'
        })
    ]
});

logger.error('ohayou.');

logger.remove('con1');

logger.error('ohayou.');

logger.add(winston.transports.Console, { name: 'con2' });
logger.add(winston.transports.Console, { name: 'con3' });

logger.error('ohayou.');

使用パッケージ

  • winston
    npm install winstonでインストールします。

実行結果

C:\work\node>node winston.js
info: yukari desu.
info: pizyumi desu.
info: pizyumi desu. foo=100, bar=200
error: error.
warn: warn.
info: info.
error: error.
warn: warn.
info: info.
verbose: verbose.
debug: debug.
error: ohayou.
error: ohayou.
error: ohayou.

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js