標準モジュールのloggingについて紹介(上級編)
モノづくり部のokadaです。
前回はloggingの基本編を書きました。
今回は上級編を書きたいと思います。
内容としては上級ロギングチュートリアルの一部紹介です。
Python環境
以下の環境で動作確認しています。
Ubuntu 18.04 Python 3.6.5
loggerによるログ出力
まずは用語を簡単に説明します。
・ロガー(logger):ログ出力のためのオブジェクト
・フォーマッタ(formatter):ログ出力形式
・ハンドラー(handler):出力先
次にプログラムの流れを説明します。
- ロガー生成
- フォーマッタ生成
- ハンドラー生成
- ハンドラーにフォーマッタを設定
- ロガーにハンドラーを設定
ロガーの生成にはlogging.getLoggerメソッドを使用します。
一般的に__name__を引数に指定します。
フォーマッタの生成にはlogging.Formatterメソッドを使用します。
引数には基本編で説明したフォーマットを指定します。
ハンドラーの生成ではloggingdで準備されたhandlersを使用します。
ここではStreamHandlerとFileHandlerを使用します。
StreamHandlerはコンソールに出力します。
FileHandlerは引数で指定したファイルに出力します。
尚、ハンドラーは複数指定可能でそれぞれにログレベルを設定出来ます。
上記以外のハンドラーについては公式ドキュメントを参照ください。
https://docs.python.jp/3/library/logging.handlers.html
では、下記コードをlog.pyという名前で保存します。
import logging # ロガー生成 logger = logging.getLogger(__name__) # ログレベルを設定(loggerのログレベル以上のハンドラーしか出力されません) logger.setLevel(logging.DEBUG) # フォーマッタ生成 formatter = logging.Formatter("[%(asctime)s %(levelname)s] %(message)s") # ハンドラー生成 log_stream_handler = logging.StreamHandler() # StreamHandlerにフォーマッタを設定 log_stream_handler.setFormatter(formatter) # StreamHandlerのログレベルを設定 log_stream_handler.setLevel(logging.INFO) # ロガーにハンドラーを設定 logger.addHandler(log_stream_handler) # ログ出力 logger.critical("critical") logger.error("error") logger.warning("warning") logger.info("info") logger.debug("debug")
下記のコマンドで実行します。
> python log.py [2019-02-18 00:31:35,161 CRITICAL] critical [2019-02-18 00:31:35,161 ERROR] error [2019-02-18 00:31:35,161 WARNING] warning [2019-02-18 00:31:35,161 INFO] info
コンソールにINFO以上のレベルのログメッセージが出力されましたね。
次にFileHandlerを追加してみます。
ログレベルはERRORです。
import logging # ロガー生成 logger = logging.getLogger(__name__) # ログレベルを設定(loggerのログレベル以上のハンドラーしか出力されません) logger.setLevel(logging.DEBUG) # フォーマッタ生成 formatter = logging.Formatter("[%(asctime)s %(levelname)s] %(message)s") # ハンドラー生成 log_stream_handler = logging.StreamHandler() # StreamHandlerにフォーマッタを設定 log_stream_handler.setFormatter(formatter) # StreamHandlerのログレベルを設定 log_stream_handler.setLevel(logging.INFO) # ハンドラー生成 log_file_handler = logging.FileHandler("test.log") # FileHandlerにフォーマッタを設定 log_file_handler.setFormatter(formatter) # FileHandlerのログレベルを設定 log_file_handler.setLevel(logging.ERROR) # ロガーにハンドラーを設定 logger.addHandler(log_stream_handler) logger.addHandler(log_file_handler) # ログ出力を行う logger.critical("critical") logger.error("error") logger.warning("warning") logger.info("info") logger.debug("debug")
実行します。
> python log.py [2019-02-18 00:36:44,402 CRITICAL] critical [2019-02-18 00:36:44,402 ERROR] error [2019-02-18 00:36:44,402 WARNING] warning [2019-02-18 00:36:44,402 INFO] info
コンソールにINFO以上のレベルのログメッセージが出力され、log.pyにtest.logのファイルが作成されました。
test.logにはERROR以上のレベルのログメッセージが出力されています。
loggingの環境設定
loggingの環境設定は以下3種類で設定出来ます。
- 上記のようにPythonコードで明示的にロガー、フォーマッタ、ハンドラーを生成
- 設定ファイルを作成し、fileConfigメソッドで読み込み
- 設定辞書を作成し、dictConfigメソッドで読み込み
ここでは2のfileConfigを見てみたいと思います。
下記コードをlogging.confという名前で保存しましょう。
[loggers]
keys=root
[handlers]
keys=logStreamHandler, logFileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=logStreamHandler, logFileHandler
[handler_logStreamHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)
[handler_logFileHandler]
class=FileHandler
level=ERROR
formatter=simpleFormatter
args=('test.log',)
[formatter_simpleFormatter]
format=[%(asctime)s %(levelname)s] %(message)s
各セクションについて簡単にまとめます。
セクション | 説明 |
---|---|
loggers | 使用するロガーの名前をカンマ区切りで設定 |
handlers | 使用するハンドラーの名前をカンマ区切りで設定 |
formatters | 使用するフォーマッタの名前をカンマ区切りで設定 |
logger_ロガー名 | 使用するロガーの設定 |
handler_ハンドラー名 | 使用するハンドラーの設定 |
formatter_フォーマッタ名 | 使用するフォーマッタの設定 |
詳細については公式ドキュメントを参照ください。
https://docs.python.jp/3/library/logging.config.html#configuration-file-format
次にlog.pyを下記コードに修正して実行してみましょう。
fileConfigの引数には作成したlogging.confを設定します。
import logging.config logging.config.fileConfig('logging.conf') logger = logging.getLogger(__name__) logger.critical("critical") logger.error("error") logger.warning("warning") logger.info("info") logger.debug("debug")
実行します。
> python log.py [2019-02-18 11:05:33,087 CRITICAL] critical [2019-02-18 11:05:33,087 ERROR] error [2019-02-18 11:05:33,087 WARNING] warning [2019-02-18 11:05:33,087 INFO] info
コンソールにINFO以上のレベルのログメッセージが出力され、log.pyにtest.logのファイルが作成されました。
test.logにはERROR以上のレベルのログメッセージが出力されています。
設定ファイルにまとめているのでPythonコードがスッキリして見やすいですね。
本記事では紹介しませんでしたが、dictConfigを使用すると辞書形式の設定情報を読み込みます。
Pythonコードで辞書に設定情報を記載して読み込ませたり、jsonファイルで設定情報を持たせておき読み込ませたり、yamlファイルで設定情報を持たせておき読み込ませたり出来ます。
詳細は公式ドキュメントを参照ください。
https://docs.python.jp/3/library/logging.config.html#logging.config.dictConfig
もっとloggingについて勉強したいという方は、公式ドキュメントのLogging クックブックを見たり、OSSのlogging部分を見たり等して色々な使い方を学んで頂ければと思います。
以上、loggingの上級編でした。