ロガーメッセージ文字列の遅延評価
2023-10-19 01:46:37
質問
Pythonアプリケーションで標準のPythonロギングモジュールを使用しています。
インポートロギング logging.basicConfig(レベル=logging.INFO) logger = logging.getLogger("log") while True: logger.debug('Stupid log message " + ' '.join([str(i) for i in range(20)]) ) # 何かをする
問題は、デバッグレベルを有効にしていないにもかかわらず、ループの繰り返しごとにその愚かなログメッセージが評価され、パフォーマンスがひどく損なわれていることです。
これに対する解決策はあるのでしょうか?
C++では
log4cxx
パッケージがあり、このようなマクロが提供されています。
LOG4CXX_DEBUG(logger, messasage)
これは事実上、次のように評価されます。
if (log4cxx::debugEnabled(logger)) { log4cxx.log(logger,log4cxx::LOG4CXX_DEBUG, message)
しかし、Pythonにはマクロがないので(AFAIK)、ロギングを行うための効率的な方法はないでしょうか?
どのように解決するのですか?
loggingモジュールは、あなたがやりたいことをすでに部分的にサポートしています。 これを実行します。
log.debug("Some message: a=%s b=%s", a, b)
...の代わりに、こんな感じ。
log.debug("Some message: a=%s b=%s" % (a, b))
ロギングモジュールは、メッセージが実際にどこかに記録されない限り、完全なログメッセージを生成しないように十分に賢明です。
この機能を特定のリクエストに適用するために、lazyjoin クラスを作成することができます。
class lazyjoin:
def __init__(self, s, items):
self.s = s
self.items = items
def __str__(self):
return self.s.join(self.items)
このように使います(ジェネレータ式を使っていることに注意してください、手抜き感が増します)。
logger.info('Stupid log message %s', lazyjoin(' ', (str(i) for i in range(20))))
以下は、この動作を示すデモです。
>>> import logging
>>> logging.basicConfig(level=logging.INFO)
>>> logger = logging.getLogger("log")
>>> class DoNotStr:
... def __str__(self):
... raise AssertionError("the code should not have called this")
...
>>> logger.info('Message %s', DoNotStr())
Traceback (most recent call last):
...
AssertionError: the code should not have called this
>>> logger.debug('Message %s', DoNotStr())
>>>
デモでは、logger.info()の呼び出しはアサーションエラーにヒットしましたが、logger.debug()はそこまで至りませんでした。
関連
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み] 文字列をfloatやintにパースするにはどうしたらいいですか?
-
[解決済み] Pythonで文字列の部分文字列を取得するにはどうすればよいですか?
-
[解決済み] Pythonで文字列を小文字にするには?
-
[解決済み] モジュールの関数名(文字列)を使って、モジュールの関数を呼び出す。
-
[解決済み] なぜlist.join(string)ではなくstring.join(list)なのでしょうか?
-
[解決済み] 文字列フォーマット:% vs. .format vs. f-stringリテラル
-
[解決済み】文字列をdatetimeに変換する
-
[解決済み】Pythonでマルチプロセシングを使用しているとき、どのようにログを取るべきですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] スロットの使い方__?
-
[解決済み] f-stringの評価を遅らせるには?
-
[解決済み] DataFrameの文字列、dtypeがobjectの場合
-
[解決済み] Pythonのマルチプロセッシングプールimap_unorderedの呼び出しの進捗を表示しますか?
-
[解決済み] PILからopenCVフォーマットへの変換
-
[解決済み] タプルのリストを複数のリストに変換するには?
-
[解決済み] Pythonのインスタンス変数とクラス変数
-
[解決済み] 範囲指定された浮動小数点数のランダムな配列を生成します。
-
[解決済み] subprocess.run()の出力を抑制またはキャプチャするには?
-
[解決済み] virtualenv の `--no-site-packages` オプションを元に戻す。