14

ロギングを行う必要がある Ruby ライブラリに取り組んでいます。理想的には、複数のワーカー プロセスが同じファイルにログインできるようにしたいと考えています。Ruby の標準ライブラリのクラスのソースを見ると、複数のスレッドからログへの書き込みを同期するための努力がなされていることがわかります ( Is Ruby's stdlib Logger class thread-safe?Loggerへの回答で指摘されているように)。

複数のプロセスが同じログ ファイルに書き込みを行っている場合にも同様の問題があるようです。基盤となるレイヤーが書き込みをバッファリング/分割する方法によっては、各ログ メッセージの整合性が維持されない場合があります。

では、標準Loggerクラスを使用して、複数のプロセスが単一のファイルに安全にログを記録できるようにする方法はありますか? そうでない場合、これは通常、Ruby プロジェクトでどのように達成されますか?

「安全に」とは次のことを意味します。

  1. 各ログ行は「アトミック」であり、次のメッセージが始まる前に途切れることなく全体が表示されます。たとえば、何も好きではありません[1/1/2013 00:00:00] (PID N) LOGMESS[1/1/2013 00:00:01] (PID M) LOGMESSAGE2\nAGE1
  2. ログに表示されるタイムスタンプが正しい限り、ログメッセージはプロセス間で厳密に順序付けされる必要はありません。

更新

Tin Man のアドバイスを受けてテストを作成することにしました

短いバージョン: Winfield は正しいです。少なくともデフォルトの使用法でLoggerは、複数のプロセスから同時に安全に使用できます (上記の「安全」の定義について)。

重要な要素は、(既に開いている IO オブジェクトではなく) ファイル パスが指定された場合、Logger が modeWRONLY|APPENDでファイルを開き、それに設定sync=trueすることです。これら 2 つのことの組み合わせ (少なくとも Mac OS X での私のテストでは) により、複数のプロセスから同時にログを記録することが安全になるようです。すでに開いている IO オブジェクトを渡したい場合は、必ず同じ方法で作成してください。

4

1 に答える 1

10

はい、説明した方法で、インターリーブされたログデータを単一のログファイルに安全に書き込むことができます。

ただし、プロセスごとに個別のログを記録するか、syslog などの統合されたログ システムを使用することをお勧めします。いくつかの理由を次に示します。

  • ログのローテーション/管理: 複数のプロセスのシグナリングを調整する必要がある場合、ログファイルの切り捨て/ローリングは困難です
  • あいまいさを解消するために PID を注入している場合でも、インターリーブされたデータは混乱を招く可能性があります

現在、システムごとに 1 つのログファイルで多数の Resque ワーカーを管理していますが、ワーカーごとにログファイルを分けておけばよかったと思います。問題をデバッグし、ログを適切に管理することは困難でした。

于 2012-12-20T19:00:22.183 に答える