多くのアプリケーションにはログ モジュールがあり、システムの動作中にいくつかの重要な情報を記録し、システムの動作ステータスの追跡を容易にするために使用されます。この記事では、主にマルチプロセス環境での Python のロギング モジュールの使用方法を紹介します。必要な方は参考にしてください。
まえがき
すべてのプログラマーは、Python を使用してバックグラウンド タスクを作成する場合、多くの場合、出力ログを使用してプログラムの実行ステータスを記録し、エラーが発生したときにエラーの詳細情報を保存する必要があることを知っておく必要があると思います。デバッグと分析を避けるため。この状況では、Python のロギング モジュールが非常に役立ちます。
ログモジュールでは、DEBUG、INFO、WARNING、ERROR、CRITICAL のログレベルを指定できます。たとえば、開発およびデバッグ中は DEBUG 以上のレベルのログを出力できますが、運用環境では INFO レベルのログのみが出力されます。出力される。 (指定しない場合、デフォルトのレベルは警告です)
logging コマンドラインまたはファイルへの出力を指定することもでき、時間またはサイズでログ ファイルを分割することもできます。
ロギングの詳細な使用方法については、ここでは詳しく説明しません。公式ドキュメントまたはここの概要を参照してください。
ログ設定
通常、ログをファイルに保存する必要があり、ログ ファイルが大きくなりすぎないようにファイルが自動的に分割されることが期待されます。ロギング設定の例を以下に示します。
import logging.config logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'verbose': { 'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s", 'datefmt': "%Y-%m-%d %H:%M:%S" }, 'simple': { 'format': '%(levelname)s %(message)s' }, }, 'handlers': { 'null': { 'level': 'DEBUG', 'class': 'logging.NullHandler', }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'verbose' }, 'file': { 'level': 'DEBUG', 'class': 'logging.RotatingFileHandler', # 当达到10MB时分割日志 'maxBytes': 1024 * 1024 * 10, # 最多保留50份文件 'backupCount': 50, # If delay is true, # then file opening is deferred until the first call to emit(). 'delay': True, 'filename': 'logs/mysite.log', 'formatter': 'verbose' } }, 'loggers': { '': { 'handlers': ['file'], 'level': 'info', }, } })
これを使用してモジュールにログを記録できます
import logging logger = logging.getLogger(__name__) if __name__ == '__main__': logger.info('log info')
マルチプロセス環境で使用します
公式ドキュメントによると、ログはスレッドセーフです、つまり、プロセス内の複数のスレッドが同時に同じファイルにログを書き込んでも安全です。ただし (はい、それはありますが)、複数のプロセスが同じファイルにログを書き込むのは安全ではありません。公式ステートメントは次のとおりです:
Python には複数のプロセス間で 1 つのファイルへのアクセスをシリアル化する標準的な方法がないため、複数のプロセスから 1 つのファイルにログを記録する必要がある場合、これを行う 1 つの方法は、すべてのプロセスを実行することです。プロセスは SocketHandler にログを記録し、ソケットから読み取り、ファイルにログを記録するソケット サーバーを実装する別のプロセスを持ちます (必要に応じて、既存のプロセスの 1 つで 1 つのスレッドをこの機能の実行専用にすることができます)。
それなら複数のプロセスは必要ない、という人もいるでしょう。ただし、Python には大きな GIL ロックがあります (GIL に関する論争についてはここを参照してください)。マルチスレッドを使用してマルチコア CPU を活用することは不可能です。ほとんどの場合、マルチプロセスが使用されます。マルチコア CPU のせいで、複数のプロセスでログが開かないという問題はまだ回避できません。
この問題を解決するには、ConcurrentLogHandler を使用します。ConcurrentLogHandler は、マルチプロセス環境で同じファイルにログを安全に書き込み、ログ ファイルが特定のサイズに達したときにログ ファイルを分割できます。デフォルトのログ モジュールには、ログ ファイルを時間で分割できる TimedRotatingFileHandler クラスがありますが、残念ながら、ConcurrentLogHandler はログ ファイルを時間で分割するこの方法をサポートしていません。
ハンドラー内のクラスを変更します。
logging.config.dictConfig({ ... 'handlers': { 'file': { 'level': 'DEBUG', # 如果没有使用并发的日志处理类,在多实例的情况下日志会出现缺失 'class': 'cloghandler.ConcurrentRotatingFileHandler', # 当达到10MB时分割日志 'maxBytes': 1024 * 1024 * 10, # 最多保留50份文件 'backupCount': 50, # If delay is true, # then file opening is deferred until the first call to emit(). 'delay': True, 'filename': 'logs/mysite.log', 'formatter': 'verbose' } }, ... })
実行後、ロックを介してログ ファイルを安全に書き込むための .lock ファイルが自動的に作成されることがわかります。
マルチプロセス環境での Python のロギング モジュールの使用に関する詳細な記事については、PHP 中国語 Web サイトに注目してください。