NODEJS | WINSTON ライブラリを使ったログ出力
I. 紹介
Winstonとは?
Winstonは、複数のトランスポートをサポートする一般的かつ簡潔なログ出力ライブラリーとして作られたものです。Winstonロガーごとに異なるレベルで構成されるトランスポートが複数あり得ます。全てのログはコンソール或いはローカルファイルへ出力されます。
Winstonは、ログ出力プロセスをフラグメント化して柔軟かつ拡張可能性のあるものになることを目的としています。
インストール
npm install winston または yarn add winston
プロジェクトへのWinston宣言
const winston = require(‘winston’) または import * as winston from ‘winston’.
Winston(ver 3.2.1)リリースノート
変更点
- トップレベルのwinston.* API
- トランスポート
- winston.Containerおよびwinston.loggers
- winston.loggers
- 例外および例外処理
- 他のマイナ変更点
winston.formatへのアップグレード
- winston.Logger形式オプション削除
- winston.transports.{File,Console,Http}形式オプション削除
- winston@3のformatsへのfiltersおよびrewritersの移植
- winston-transportやlogform等のモジュール化
詳細について以下のURLを参照のこと
https://github.com/winstonjs/winston/blob/HEAD/UPGRADE-3.0.md
Winston使用時、独自ロガーの実装が推薦されます。一番簡単な方法としてwinston.createLoggerを利用することです。
II. ロギング
Winstonのロギング・レベルはRFC5424で定義された重大性の順番に準拠しています。各レベルの重大性は昇順に並んでいる整数で定義されており、数値が小さいほど重大性が高いです。
パラメーター
パラメーター名 | デフォルト値 | 説明 |
level | ‘info’ | ログはinfo.levelがこのレベル以下の時のみ出力する |
levels | winston.config.npm.levels | レベル(色も)はログの優先度を示す |
format | winston.format.json | infoのメッセージの形式を指定する |
transports | [] (No transports) | infoのメッセージのロギング・ターゲットを設定する |
exitOnError | true | 偽(false)の場合、例外処理はprocess.exitを呼び出さない |
silent | false | 真(true)の場合、全てのログ出力を抑制する |
createLoggerに設定されたレベルは返却されるロガーにて便宜なメソッドとして定義されます。
winston.createLoggerから生成されたのち、ロガーからトランスポートを追加または削除することができます。
フォーマットの追加的な属性
属性 | 以下によるフォーマット追加 | 説明 |
splat | splat() | %d %sで文字列を挿入(メッセージスタイル) |
timestamp | timestamp() | メッセージ受取時のタイムスタンプ |
label | label() | 各メッセージに設けるカスタマイズラベル |
ms | ms() | 直前のメッセージよりミリ秒数 |
必要に応じて自由にいずれかの属性を追加することが可能です。内部状態はSymbol属性で維持します。
Symbol.for(‘level’) (読取専用): level属性と同等。全てのコードに変更しません。
Symbol.for(‘message’): “finalizing formats”で指定されたメッセージ
- json
- logstash
- printf
- prettyPrint
- simple
Symbol.for(‘splat’): 文字列挿入の引数。splat()で使われます。
注意: metaオブジェクトの 全て{message}属性は提供されたどのメッセージにも自動的に連結されます。以下の例に、’world’は’hello’と連結されます。
III. フォーマット
WinstonのフォーマットはWinstonからの別のモジュールであるlogformに実装され、winston.formatからアクセスできます。これにより独自トランスポートを作る時にフォーマットをデフォルトとして指定したい場合、柔軟に対応できます。
ログにフォーマットを指定したい場合、winston.format.printfがおすすめです。
フォーマット組合せ
format.combineを用いることで複数のフォーマットを単一フォーマットになるように組み合わせることができます。
文字列の挿入
logメソッドはformat.splat()を使った文字列の挿入をサポートしますが、format.splat()を用いることで有効化しなければなりません。
IV. ロギングレベル
レベルの一つずつは優先度としての整数を与えられます。優先度が高いほど、重大性が高いです。それに対して優先度が低いほど、重大性が低いです。以下のように、RFC5424で定義され、優先度としての整数が0~7、すなわち該当する重大性が一番高いものから一番低いものとなっています。
同様に、npmログレベルは0~5(一番高いから一番低い)で定義されます。
ロギングレベルの使用
カスタマイズしたロギングレベルの使用
V. トランスポート
トランスポートを作る時、winston.transports.Fileといった同じタイプのトランスポートを複数利用できます。
トランスポートの一つを削除したい場合、そのトランスポート自体を用いることで削除できます。
VI. 例外
Winstonによって処理されない例外の処理
Winstonでは、処理プロセスからuncaughtExceptionイベントを捕まえ、ログ出力することができます。作った独自ロガーでは、作成時または、アプリケーション・ライフサイクルでこの処理を有効にすることができます。
トランスポート・インスタンスで.exceptions.handle()を以下のようにコールすることでデフォルトロガーとしてこの機能を利用できます。
終了・非終了
WinstonはデフォルトとしてunsceptionExceptionのログが出力した後に終了します。終了したくない場合、exitOnError = falseで設定しなければなりません。
カストマイズ・ロガーでは、別々のexceptionHandlersの属性へトランスポートをセットし、または、handleExceptionsをトランスポートに設定することができます。
例1
例2
VII. QUERY LOGS.
WinstonはLogglyのようなオプションでログクエリをサポートしています。特に、File、Couchdb、Redis、Loggly、Nssocket、Httpです。
VIII. 案件への適用
Winstonインストール
winston.ts生成
ログ出力
検証
PostManを使ってAPIを実行します。http://localhost:8081/v1/user/1 (Idが存在している場合)
PostManを使ってAPIを実行します。http://localhost:8081/v1/user/2 (Idが存在しない場合)