pythonでLoggingを使ってみる
実行環境
- OS : Windows10
- Python : v3.9.6
Loggingについて
Pythonを入れると標準で入ってくるモジュールです。
logging --- Python 用ロギング機能 — Python 3.9.4 ドキュメント
import logging
セットアップ
loggingインスタンスの生成
直接インスタンス化するのではなく、getLogger(name)
を介してインスタンス化する事が推奨されています。
logger = logging.getLogger("hogehoge")
logger = logging.getLogger(__name__)
インスタンスの親子
親インスタンスから子を作成。
# 親インスタンス parentLogger = logging.getLogger(__name__) # 子インスタンス childLogger = logging.getLogger(__name__).getChild("hogehoge")
ログレベルの設定
ログを出力する閾値を設定する。
閾値を設定することで、それ以上深刻なログのみ出力される。
ロガーインスタンス初期値 : NOTSET
ルートロガー初期値 : WARNING
レベル | 数値 |
---|---|
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
# レベル定数 CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 # Debugレベルに設定 logger.setLevel(logging.DEBUG) logger.setLevel(10) # ルートロガー初期値確認 logger = logging.getLogger() logger.getEffectiveLevel() # -> 30
ログ出力
レベルごとにメソッドを使い分けて出力する。
# 各レベルで出力 logger.debug("debug") logger.info("info") logger.warnig("warning") logger.error("error") logger.critical("critical") # 変数を出力文字内に入れる name = "hogehoge" logger.debug("Name:%s", name) # -> Name:hogehoge
NOTSETについて
初期値のNOTSET
レベルは、
ロガーがルートロガーであれば処理される、そうでなくてロガーが非ルートロガーの場合には親ロガーに委譲させる という設定で、NOTSET以外の設定を見つけるまで祖先をたどる。
ルートロガーの初期はWARNING
で設定されているため、レベル設定を行わない場合、WARNING以上しか出力されない。 引用元: Logging HOWTO — Python 3.9.4 ドキュメント
# warning以上しか出力されない logger = logging.getLogger(__name__) logger.info("info") -> logger.warning("warning") # -> warning # ルートロガーのレベル設定 logging.basicConfig(level=logging.DEBUG)
basicConfigでは、ほかにフォーマットや、ハンドラなどで基本的なロギングの設定を行える
Handler
ログの送り先をハンドラとして設定する
StreamHandler
標準出力(stdout)、標準エラー出力(stderror)へ送信する
# ロガーインスタンス作成 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # Handler作成 sh = logging.StreamHandler() sh.setLevel(logging.INFO) # loggerにHandler追加 logger.addHandler(ch) logger.info("hogehoge") # -> hogehoge
FileHandler
ログ出力をファイルに送信する
# ロガーインスタンス作成 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # # Handler作成 出力ファイル名_LOGFILE.log fh = logging.FileHandler("./LOGFILE.log") fh.setLevel(logging.INFO) logger.addHandler(fh) logger.info("hogehoge") # ==LOGFILE.log== hogehoge
Formatter
表示するメッセージの書式を設定する
フォーマット文字列内に特別な文字列を配置することで、日付やログレベルなどをメッセージに含められる。
フォーマッタの初期値は%(message)s
のみで、メッセージだけが出力される
出力される内容 | |
---|---|
%(asctime)s | 日時 |
%(name)s | ロガーインスタンス名 |
%(levelname)s | ログレベル |
%(message)s | メッセージ |
# ロガーインスタンス作成 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # Handler作成 ch = logging.StreamHandler() ch.setLevel(logging.INFO) # Formatter作成・追加 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) # loggerにHandler追加 logger.addHandler(ch) logger.info("hogehoge") # -> 2021-07-18 00:00:00,000 - __main__ - INFO - hogehoge logger.warning("hogehoge") # -> 2021-07-18 00:00:00,000 - __main__ - WARNING - hogehoge logger.error("hogehoge") # -> 2021-07-18 00:00:00,000 - __main__ - ERROR - hogehoge logger.critical("hogehoge") # -> 2021-07-18 00:00:00,000 - __main__ - CRITICAL - hogehoge
設定ファイルよりセットアップ
いままでの設定はコード内で行っていたが、
設定ファイル(.conf)を事前に定義して読み込みを行う事もできる。
# ==logging.conf== # logger keys "root" [loggers] keys=root # handler keys "streamHandler","fileHandler" [handlers] keys=streamHandler,fileHandler # formatter keys "formatter" [formatters] keys=formatter # "root" logger setup [logger_root] level=DEBUG handlers=streamHandler,fileHandler # "streamHandler" handler setup [handler_streamHandler] class=StreamHandler level=DEBUG formatter=formatter # "fileHandler" handler setup [handler_fileHandler] class=FileHandler level=DEBUG formatter=formatter args=('LOGFILE.log', 'w') # "formatter" formatter setup [formatter_formatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
# conf読み込み logging.config.fileConfig("./logging.conf") # loggerインスタンス生成 logger = logging.getLogger(__name__)
辞書型で定義してセットアップ
コード内で辞書型で定義することもできる。
設定内容は設定ファイルでの設定と同じ。
# 辞書型で設定内容を作成 logging_conf = { 'version': 1, 'formatters': { 'formatter': { 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s' }, }, 'handlers': { 'streamHandler': { 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'formatter' }, 'fileHandler':{ 'level':'DEBUG', 'class':'logging.FileHandler', 'formatter': 'formatter', 'filename': 'LOGFILE.log', 'mode': 'w' }, }, 'loggers': { 'root': { 'handlers': ['streamHandler', 'fileHandler'], 'level': 'DEBUG', } } } # 辞書型で読み込み logging.config.dictConfig(logging_conf) # インスタンス作成 logger = logging.getLogger(__name__)