独自のロギングライブラリを開発しているときに、CPythonの標準 logging
モジュールのソースコードを研究しました。
その機能の1つは、ハンドラーがthread-safeであることです。行が破損するリスクなしに、複数のスレッドからファイルにログを書き込むことができます。
logging
モジュールのソースを詳しく調べて、スレッドの安全性を確保するために各ハンドラーが独自のLock
各ロギング呼び出しで取得および解放すること。あなたはこれを見ることができます ここ 。
ハンドラーの呼び出しをグローバルに囲む単一のロックを使用するのではなく、これを行う意味は何ですか?たとえば、 callHandlers()
関数でロックを取得しませんか?
主な利点は2つあります。
H1.handle(M1) -> H1.handle(M2) -> H2.handle(M2) -> H2.handle(M1)
が発生する可能性を回避できます)。私の個人用ロギングライブラリでは、ロガーごとに次のようなことを安全に実行できますか?
with self.lock:
for handler in self.handlers:
handler.handle(message) # No lock used in "handle()"
それとも何か他を見落としているのでしょうか?
特にSocketHandler/SMTPHandler/HTTPHandlerなどの別のマシンやサードパーティのサービスロギングハンドラーをリモートロギングする場合、ロギングハンドラーが遅くなる可能性があります。ロギングライブラリ全体が単一のロックを使用している場合、遅いハンドラー(例:例外時に管理者への電子メール)へのロギングは、速いハンドラー(例:ローカルファイルのログ)へのロギングをブロックします。
さらに、一部のロギングハンドラーはロックをまったく必要としない場合があります。たとえば、外部ロギングでは、処理をシリアル化して暗黙的にではなく、タイムスタンプを使用してログを並べ替えることがあります。