Pythonのログメッセージをフォーマットせずに桁区切りのカンマを表示したい
69:ログメッセージをフォーマットしてロガーに渡さない — 自走プログラマー【抜粋版】 からの質問でした。
質問
python - ログメッセージをフォーマットせずに出力したいです。桁区切りのカンマを表示するには、どのように指定すればよいでしょうか? - スタック・オーバーフロー
shimizukawa.iconの回答
フォーマットせずに渡すけど、フォーマットしたい、という矛盾した要求に思えますが、ニーズは分かります。
フォーマットした値を渡す
ログメッセージをフォーマットしてロガーに渡さない のが良いのは、loggerの第一引数(メッセージ部分)をキーにログ出力を集約することがあるためです。言い換えると、第二引数以降にフォーマットした数値(の文字列)を渡してしまえば良いと思います。
code:python
>> import logging
>> logger = logging.getLogger()
>> value = 12345678
>> logger.error('size %s mb', value)
size 12345678 mb
>> logger.error('size %s mb', f'{value:,}')
size 12,345,678 mb
これで、メッセージ部分は 'size %s mb' で一意なキーには変わりないので、目的は達成できると思います。
フォーマットした値とは別に生データも渡す
もし、ログ表示とは別に裏で生データも扱えるようにしておきたいのであれば、extraで元データも渡しておく方法があります。
code:python
>> logger.error('size %s mb', f'{value:,}', extra={'value': value})
size 12,345,678 mb
カンマ区切りにフォーマットされる整数値wrapperクラスを実装する
値を2つ渡すのが面倒、表示は3桁区切りにしたいが生データを維持したい、ということであれば、ロギング用の3桁区切りラッパークラスを実装してしまう方法もあります。
code:python
>> class ThreeDigit(int):
... def __str__(self):
... return f'{self:,}'
...
>> ThreeDigit(value)
12345678
>> print(ThreeDigit(value))
12,345,678
>> logger.error('size %s mb', ThreeDigit(value))
size 12,345,678 mb
いずれの方法でも実現はできますが、JSONの構造化ログでログデータを扱い始めると、Python loggerのレイヤーで3桁区切りのフォーマットをする必要がなくなる(構造化ログのビューワーを別途用意すると思われる)ため、将来どうしていきたいか次第で選べば良さそうです。
気にせずフォーマットする
ログ出力はコンソールに表示するだけで収集しない、ということであれば、(良いプラクティスではありませんが)気にせずフォーマットしてしまうという割り切りもありだと思います。
#ロギング
#ログ出力
#Python_Logging_入門
#自走プログラマー