はじめに
logging
モジュールは、標準のPythonライブラリの一部であり、ソフトウェアが実行されている間に発生したイベントを追跡します。コードにログ呼び出しを追加して、どのイベントが発生したかを示すことができます。
logging
モジュールは、アプリケーションの動作に関連するイベントを記録する診断ログと、ユーザーのトランザクションのイベントを記録する監査ログの両方を可能にします。特に、イベントをファイルに記録するために使用されます。
前提条件
Python 3がインストールされており、コンピューターまたはサーバーにプログラミング環境が設定されている必要があります。プログラミング環境が設定されていない場合は、適切なオペレーティングシステム(Ubuntu、CentOS、Debianなど)用のローカルプログラミング環境またはサーバー上のプログラミング環境のインストールおよびセットアップガイドを参照できます。
なぜlogging
モジュールを使用するのですか
logging
モジュールは、プログラム内で発生するイベントの記録を保持し、ソフトウェアのランタイム全体で発生するイベントに関連する出力を見ることができるようにします。
おそらく、コード全体にprint()
ステートメントを使用してイベントが発生しているかどうかを確認することにより、より馴染みがあるかもしれません。 print()
ステートメントは、コード全体に埋め込まれた場合、実行フローとプログラムの現在の状態を追跡するための基本的な方法を提供しますが、このソリューションはlogging
モジュールを使用するよりも保守性に欠けることがいくつかあります:
- デバッグ出力と通常のプログラム出力を区別するのが難しくなります
- コード全体に分散して
print()
ステートメントを使用すると、デバッグ出力を提供するものを効率的に無効にする方法がありません - デバッグが完了した後にすべての
print()
ステートメントを削除するのが難しくなります - すぐに利用可能な診断情報を含むログレコードがありません
logging
モジュールをコードで使用する習慣を身につけるのは良い考えです。これは、小さなPythonスクリプトを超えて成長するアプリケーションに適しており、デバッグの持続可能なアプローチを提供します。
ログは時間の経過とともに動作とエラーを示すため、アプリケーション開発プロセス全体の状況をよりよく把握できます。
コンソールにデバッグメッセージを出力する
情報: このチュートリアルの例コードに従って進むには、ローカルシステムでPythonの対話型シェルを開いてpython3
コマンドを実行します。その後、>>>
プロンプトの後に例を追加、コピー、または編集できます。
プログラム内で何が起こっているかを確認するためにprint()
ステートメントを使用するのに慣れている場合、おそらく次のようなプログラムを見慣れているかもしれません:クラスを定義し、オブジェクトをインスタンス化するプログラムは次のようなものを生成します:
上記のコードには、Pizza
クラスのオブジェクトのname
とprice
を定義する__init__
メソッドがあります。それに続いて、ピザを作るためのmake()
メソッドと、ピザを食べるためのeat()
メソッドが2つあります。これらの2つのメソッドは、quantity
のパラメータを受け取り、これは1
で初期化されています。
さて、プログラムを実行してみましょう:
次の出力が得られます:
OutputPizza created: artichoke ($15)
Made 1 artichoke pizza(s)
Ate 1 pizza(s)
Pizza created: margherita ($12)
Made 2 margherita pizza(s)
Ate 1 pizza(s)
print()
ステートメントを使用してコードが機能していることを確認できますが、代わりにlogging
モジュールを使用して同じことができます。
コード全体からprint()
ステートメントを削除またはコメントアウトし、ファイルの先頭にimport logging
を追加しましょう:
logging
モジュールはDEBUG
よりも上のレベルであるWARNING
のデフォルトレベルを持っています。この例ではデバッグにlogging
モジュールを使用するため、logging.DEBUG
のレベルで情報をコンソールに返すように構成を変更する必要があります。それには、インポートステートメントの下に次の行を追加します:
このlogging.DEBUG
レベルは、閾値を設定するためにコードで参照する定数整数値を指します。DEBUGレベルは10です。
これで、すべてのprint()
ステートメントをlogging.debug()
ステートメントに置き換えます。定数であるlogging.DEBUG
とは異なり、logging.debug()
はlogging
モジュールのメソッドです。このメソッドを使用する際には、同じstring
をprint()
に渡したものを使用できます。次に示すように、:
この段階で、python pizza.py
コマンドでプログラムを実行すると、次の出力が得られます:
OutputDEBUG:root:Pizza created: artichoke ($15)
DEBUG:root:Made 1 artichoke pizza(s)
DEBUG:root:Ate 1 pizza(s)
DEBUG:root:Pizza created: margherita ($12)
DEBUG:root:Made 2 margherita pizza(s)
DEBUG:root:Ate 1 pizza(s)
ログメッセージには、Pythonモジュールのレベルを指すDEBUG
という深刻度レベルの他に、root
という単語が埋め込まれています。異なる名前を持つロガーの階層を持つlogging
モジュールを使用できるため、各モジュールに異なるロガーを使用できます。
例えば、異なる名前と異なる出力を持つ異なるロガーにロガーを設定できます:
OutputDEBUG:module_1:Module 1 debugger
DEBUG:module_2:Module 2 debugger
今、logging
モジュールを使用してメッセージをコンソールに表示する方法を理解したので、logging
モジュールを使用してメッセージをファイルに出力する方法に移りましょう。
logging
モジュールの主な目的は、メッセージをコンソールではなくファイルに記録することです。メッセージのファイルを保持することで、時間の経過とともにデータを参照し、コードに必要な変更を把握して量化できます。
ファイルにログを記録するには、logging.basicConfig()
メソッドを変更してfilename
パラメータを含めることができます。この場合、ファイル名をtest.log
と呼びましょう:
上記のコードは、前のセクションと同じですが、ログの出力先としてファイル名が追加されています。python pizza.py
コマンドでコードを実行すると、ディレクトリにtest.log
という新しいファイルが作成されるはずです。
test.log
ファイルをnano(またはお好みのテキストエディタ)で開きましょう:
ファイルが開くと、次のようなものが表示されます:
DEBUG:root:Pizza created: artichoke ($15)
DEBUG:root:Made 1 artichoke pizza(s)
DEBUG:root:Ate 1 pizza(s)
DEBUG:root:Pizza created: margherita ($12)
DEBUG:root:Made 2 margherita pizza(s)
DEBUG:root:Ate 1 pizza(s)
これは、前のセクションで遭遇したコンソール出力と似ていますが、今回はtest.log
ファイルにあります。
CTRL
+ x
を押してファイルを閉じ、コードを修正できるようにpizza.py
ファイルに戻りましょう。
コードの大部分は同じままにしておきますが、2つのピザインスタンス、pizza_01
とpizza_02
のパラメータを修正します:
これらの変更を加えたら、python pizza.py
コマンドでプログラムを再実行しましょう。
プログラムが実行されたら、再びnanoでtest.log
ファイルを開くことができます:
ファイルを確認すると、いくつかの新しい行が追加され、前回プログラムが実行された時の行が保持されていることがわかります:
DEBUG:root:Pizza created: artichoke ($15)
DEBUG:root:Made 1 artichoke pizza(s)
DEBUG:root:Ate 1 pizza(s)
DEBUG:root:Pizza created: margherita ($12)
DEBUG:root:Made 2 margherita pizza(s)
DEBUG:root:Ate 1 pizza(s)
DEBUG:root:Pizza created: Sicilian ($18)
DEBUG:root:Made 5 Sicilian pizza(s)
DEBUG:root:Ate 4 pizza(s)
DEBUG:root:Pizza created: quattro formaggi ($16)
DEBUG:root:Made 2 quattro formaggi pizza(s)
DEBUG:root:Ate 2 pizza(s)
この情報は確かに有用ですが、追加のLogRecord属性を追加してログをより情報豊かにすることができます。主に、LogRecordが作成された時刻を示す人間が読めるタイムスタンプを追加したいと考えています。
属性を追加して、format
というパラメータにその属性を追加できます。属性は、テーブルで示されているように文字列%(asctime)s
で参照します。さらに、DEBUG
レベル名を保持するには、文字列%(levelname)s
を含める必要があり、ロガーが出力するメッセージを保持するには%(message)s
を含めます。これらの属性は、追加されたコードに示されているように、colon
で区切られます。
上記のコードを追加した状態でpython pizza.py
コマンドを使用してコードを実行すると、test.log
ファイルに新しい行が追加され、人が読める時刻のタイムスタンプと、DEBUG
のレベル名、そしてロガーに渡されたメッセージが文字列として含まれます。
DEBUG:root:Pizza created: Sicilian ($18)
DEBUG:root:Made 5 Sicilian pizza(s)
DEBUG:root:Ate 4 pizza(s)
DEBUG:root:Pizza created: quattro formaggi ($16)
DEBUG:root:Made 2 quattro formaggi pizza(s)
DEBUG:root:Ate 2 pizza(s)
2021-08-19 23:31:34,484:DEBUG:Pizza created: Sicilian ($18)
2021-08-19 23:31:34,484:DEBUG:Made 5 Sicilian pizza(s)
2021-08-19 23:31:34,484:DEBUG:Ate 4 pizza(s)
2021-08-19 23:31:34,484:DEBUG:Pizza created: quattro formaggi ($16)
2021-08-19 23:31:34,484:DEBUG:Made 2 quattro formaggi pizza(s)
2021-08-19 23:31:34,484:DEBUG:Ate 2 pizza(s)
必要に応じて、コード内で追加のLogRecord属性を使用して、プログラムファイルのログを自分に関連付けることができます。
デバッグやその他のメッセージを別々のファイルに記録することで、Pythonプログラムの全体像を時間の経過とともに把握することができ、プログラムに取り組んできた歴史的な作業や発生したイベントやトランザクションによって情報を得て、コードをトラブルシューティングしたり修正したりする機会が得られます。
ログレベルの表
開発者として、ログにキャプチャされたイベントに重要度レベルを割り当てることができます。重要度レベルは以下の表に示されています。
ログレベルは技術的には整数(定数)であり、NOTSET
から始まり、数値0でロガーを初期化します。
また、定義済みのレベルに相対的な独自のレベルを定義することもできます。同じ数値を持つレベルを定義すると、その値に関連付けられた名前が上書きされます。
以下の表に、各レベル名、数値、そのレベルを呼び出すために使用できる関数、およびそのレベルの使用方法が示されています。
Level | Numeric Value | Function | Used to |
---|---|---|---|
CRITICAL |
50 | logging.critical() |
Show a serious error, the program may be unable to continue running |
ERROR |
40 | logging.error() |
Show a more serious problem |
WARNING |
30 | logging.warning() |
Indicate something unexpected happened, or could happen |
INFO |
20 | logging.info() |
Confirm that things are working as expected |
DEBUG |
10 | logging.debug() |
Diagnose problems, show detailed information |
logging
モジュールはデフォルトでレベルをWARNING
に設定しているため、WARNING
、ERROR
、CRITICAL
はすべてデフォルトでログに記録されます。上記の例では、次のコードを使用してDEBUG
レベルを含めた構成を変更しました。
デバッガーのコマンドや動作についての詳細は、公式のlogging
ドキュメントを参照してください。
結論
デバッグは、どんなソフトウェア開発プロジェクトにおいても重要なステップです。 logging
モジュールは、標準のPythonライブラリの一部であり、ソフトウェアが実行されている間に発生するイベントを追跡し、これらのイベントを別のログファイルに出力する機能を提供します。これにより、コードが実行される過程で発生するさまざまなイベントを理解することに基づいてコードをデバッグする機会が提供されます。
Source:
https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3