@logbrew/sdk 0.1.40、@logbrew/node 0.1.24、@logbrew/express 0.1.10 で実行しました。出力のブロックはすべて実際の出力です。
Winston と Pino のどちらを選ぶか
どちらのライブラリも構造化された JSON ログを出力します。アプリケーションですでに使っているライブラリをそのまま使います。LogBrew の設定はライブラリごとに異なります。LogBrew のプロジェクトを準備する
1
プロジェクトのキーを作成する
CLI でサインインします。プロジェクトを作成し、その取り込みキーを所有者だけが読めるファイルに保存します。CLI はキーを表示しません。本番環境では、利用しているプラットフォームのシークレット管理機能を使ってください。
2
パッケージをインストールする
パッケージには Node.js 18.19 以降が必要です。Winston と Pino のどちらか、または両方をインストールします。
3
キーとデプロイの識別情報を設定する
createLogBrewNodeClient() は LOGBREW_SERVER_API_KEY からキーを読み取ります。サービス名は package.json の name です。別の名前を使うには LOGBREW_SERVICE_NAME を設定します。例では ES モジュールを使うので、package.json に "type": "module" を設定します。Node.js のログレベル
ライブラリごとにレベル名と数値が異なります。LogBrew は4つのレベルを保存し、元のレベルをメタデータに残します。
Winston では、数値が小さいほど重大度が高くなります。Pino では、数値が大きいほど重大度が高くなります。本番環境では
info を設定します。debug は短時間の診断のときだけ使います。
Winston のロガー
このファイルをwinston-app.js として保存します。最初のフォーマットは、ロガーのレベルより低いレコードを、トランスポートに渡る前に除外します。LogBrew のトランスポートはロガーが書き込むすべてのレコードを受け取るので、このフィルターが必要です。
node winston-app.js を実行します。コンソールには、info 以上の各レコードが1行の JSON として出力されます。ここではスタックを短くしています。
context.* のメタデータになります。
トランスポートはエラーの名前とメッセージを送信しますが、スタックは送信しません。スタックを送信するには、
createLogBrewWinstonTransport() で includeErrorStack: true を設定します。各メッセージは、次の課題の直前の手順にもなります。これを止めるには breadcrumbs: false を設定します。
Pino のロガー
このファイルをpino-app.js として保存します。最初のログの前に、installLogBrewPinoInstrumentation() を1回呼び出します。この関数は、書き込みが終わった Pino の各レコードを読み取ります。Pino は引き続き独自の出力先に書き込みます。
node pino-app.js を実行します。ここではホスト名とスタックを短くしています。
debug のレコードは、LogBrew に届く前に Pino が除外します。
token フィールドは LogBrew に保存されません。LogBrew は認証情報、Cookie、本文、クエリ、URL、スタックのフィールドを除外します。Pino の redact のパスも、2つ目の対策として有効なままです。pid、hostname、time は Pino のデフォルトなので、LogBrew はこれらをコピーしません。
自動取得には、9.x 系なら Pino 9.11 以降、それ以外は Pino 10.1 以降が必要です。それより古い Pino では、@logbrew/sdk の createLogBrewPinoDestination() を Pino の出力先として使います。
開発中に Pino の出力を読みやすくするには、pino-pretty に渡します。
Express のロガー
logbrewMiddleware() は、リクエストごとに1つのリクエストスパンを作成します。logbrewErrorHandler() はエラーを課題として報告します。リクエスト内の Pino のログには、そのリクエストのトレース ID とスパン ID が付きます。このファイルを express-app.js として保存します。
スパン名には、実際のパスではなくルートのテンプレートが使われます。
listening on 3000 のログはリクエストの外で出力されるので、トレースを持ちません。
リクエスト用のクライアントは、ミドルウェアに作成させます。プロセス全体で使う client を、logbrewMiddleware() や logbrewErrorHandler() に渡さないでください。ミドルウェアは、各レスポンスの後でリクエスト用のクライアントをシャットダウンします。
Winston のログにトレースを追加する
Winston では、アクティブなトレースをトランスポートに渡します。logbrewTransport をロガーの transports リストに追加します。これで、Express のリクエスト内の Winston のログに、そのリクエストのトレース ID とスパン ID が付きます。
ログを読み取って確認する
<trace_id> はトレースか課題からコピーします。CI やコーディングエージェントから読み取るには、プロジェクトの読み取りキーを使います。セットアップの確認を参照してください。
ログを失わずにシャットダウンする
クライアントは、キューにたまったイベントを、最初のイベントから1秒後、またはイベントが50件たまった時点で送信します。イベントループが空になると、クライアントは残りのイベントを最大2秒かけて送信します。process.exit() とシグナルでは、この処理が実行されません。Express の例の SIGTERM ハンドラーのように、終了する前に await client.shutdown() を呼び出します。
トラブルシューティング
ログのフィールドを選ぶには構造化ログを参照してください。ほかのフレームワークについては SDK 連携を参照してください。
