Pythonで簡単にロギングを行うには
メインページ>コンピュータの部屋#Python>Python Tips
Python は最近山ほど書籍が出ていますが、プログラミングでは必須な ロギング に関する情報がなさすぎなので 簡単なまとめを書いてみることにしました。
目次
[非表示]最も簡単なやり方
とりあえず
- 出力先はコンソールだけ
- 適宜出力形式とレベルを変更できるだけでよい
の2条件を満たすだけなら恐ろしく簡単です。
まずメインモジュールの冒頭に以下の import 文を加えます。
import logging
そしてメインモジュールのモジュールレベルの先頭に
logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(module)-18s %(funcName)-10s %(lineno)4s: %(message)s' )
構成ファイルを使ったロギング
通常アプリケーションではもう少し凝ったロギングが必要です。こんな場合を考えてみましょう お置きます。これでお膳立てはおしまいです。
ログを出力するところには以下のように書きます。
logger.debug("デバッグ") logger.info("情報")
出力はコンソールに
2018-01-01 18:09:39,992 DEBUG main_module <module> 10: デバッグ 2018-01-01 18:09:39,992 INFO main_module <module> 11: 情報
と出力されます。
既にお察しとは思いますが、ログの第一コラムは日付、第2コラムは時刻、第3コラムはログレベル、第4コラムはモジュール名です。
第5コラムは関数名かメソッド名が表示されますが、モジュールレベルでログ出力を呼んだ場合 <module> と出力されます。 第6コラムはモジュール内の行番号、最後がログメッセージです。
メインモジュール以外でロギングを使うときは、先頭に import logging を書き、logger.debug 等でログ出力を書けばOKです。
これだけです。簡単ですよね。
より複雑なロギングを構成する
通常のアプリケーションでは、ロギングにもう少し凝った要件があります。とりあえずこんな条件を考えてみましょう。
- ログはコンソールとファイルに出力される。
- コンソールには全てのログを出力したい。
- ファイルには INFO(情報)以上のレベルのログだけを出力したい。
- ログファイルはサイズを 1MB までとし、バックアップファイル3個(つまり合計4個)でローテーションしたい。
これを実現するには3種類のやり方がありますが、その前に、python のロギングの仕組みを簡単に紹介しておきましょう。
Pythonのロギングの仕組み
Pythonのロギングの仕組みは log4net や log4j とあまり変わりません。
ロガー
Pythonのロギング では 「ロガー」 と呼ばれるオブジェクトの debug とか info 関数を呼ぶことでロギングを行います。 ロガーはそれに割りつけられた「ハンドラ」を使ってファイルやコンソールにログを送ります。
ルートロガー
logger には既定の「ルートロガー」と呼ばれるロガーがあり、ログ出力を行おうとするときに無いと自動的に作られます。 但し、自動的に作られる「ルートロガー」は、ハンドラはコンソールに出力するハンドラで、ログレベルがWARNING(警告) 以上のログ しか出力せず、書式も貧弱なので使いずらいです。
最初に紹介した
logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(module)-18s %(funcName)-10s %(lineno)4s: %(message)s' )
は強制的にルートロガーを作り、ログレベルがDEBUG以上のログを指定した書式でコンソールに出力するルートロガーを作ります。
ルートロガー以外のロガーの作り方
logger = logging.getLogger(<<ロガーの名前>>)
は新しい名前の付いたロガーを作ります。同じ名前を指定して2回呼ぶと、2回目は前と同じロガーの参照が返るので、同じ名前のロガーは1個しか作れません。
作られた直後のロガーはハンドラーを持たず、何も出力できませんが、既定でログをルートロガーに転送します。ここでの説明ではこの機能だけを利用します。