前書き

`+ logging +`モジュールは標準Pythonライブラリの一部であり、ソフトウェアの実行中に発生するイベントの追跡を提供します。 ロギングコールをコードに追加して、発生したイベントを示すことができます。

`+ logging +`モジュールは、アプリケーションの操作に関連するイベントを記録する診断ログと、分析のためにユーザーのトランザクションのイベントを記録する監査ログの両方を可能にします。 特に、イベントをファイルに記録するために使用されます。

`+ logging +`モジュールを使用する理由

`+ logging +`モジュールはプログラム内で発生するイベントの記録を保持し、ソフトウェアのランタイム全体で発生するイベントのいずれかに関連する出力を表示できるようにします。

コード全体で `+ print()`ステートメントを使用することで、イベントが発生していることを確認することに慣れているかもしれません。 ` print()`ステートメント_does_は、コードをデバッグして問題を解決する基本的な方法を提供します。 コード全体に ` print()`ステートメントを埋め込むと、実行フローとプログラムの現在の状態を追跡できますが、このソリューションは、いくつかの理由で ` logging +`モジュールを使用するよりも保守性が低いことがわかります。

  • 2つが混在しているため、デバッグ出力と通常のプログラム出力を区別することが難しくなります。

  • コード全体に分散した `+ print()+`ステートメントを使用する場合、デバッグ出力を提供するステートメントを無効にする簡単な方法はありません

  • デバッグが完了したら、すべての `+ print()+`ステートメントを削除することが難しくなります

  • すぐに利用できる診断情報を含むログレコードはありません

コード内で `+ logging +`モジュールを使用する習慣を身に付けるのは良い考えです。これは単純なPythonスクリプトを超えて成長し、デバッグへの持続可能なアプローチを提供するアプリケーションにより適しています。

ログは時間の経過とともに動作とエラーを表示できるため、アプリケーション開発プロセスで行われていることの全体像をよりよく把握できます。

コンソールへのデバッグメッセージの印刷

プログラムで発生していることを確認するために `+ print()+`ステートメントを使用することに慣れている場合、https://www.digitalocean.com/community/tutorials/how-toのプログラムを見ることに慣れているかもしれません-construct-classes-and-define-objects-in-python-3 [クラスを定義]し、次のようなオブジェクトをインスタンス化します。

pizza.py

class Pizza():
   def __init__(self, name, price):
       self.name = name
       self.price = price
       print("Pizza created: {} (${})".format(self.name, self.price))

   def make(self, quantity=1):
       print("Made {} {} pizza(s)".format(quantity, self.name))

   def eat(self, quantity=1):
       print("Ate {} pizza(s)".format(quantity, self.name))

pizza_01 = Pizza("artichoke", 15)
pizza_01.make()
pizza_01.eat()

pizza_02 = Pizza("margherita", 12)
pizza_02.make(2)
pizza_02.eat()

上記のコードには、 + Pizza`クラスのオブジェクトの + name`と + price`を定義するための + init + `メソッドがあります。 次に、2つのメソッドがあります。1つはピザを作るための `+ make()`と呼ばれ、もう1つはピザを食べるための ` eat()`と呼ばれます。 これらの2つのメソッドは、「 1+」で初期化される「+ quantity +」のパラメーターを受け取ります。

それではプログラムを実行しましょう:

python pizza.py

次の出力が表示されます。

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 +`を追加しましょう。

pizza.py

class Pizza():
   def __init__(self, name, value):
       self.name = name
       self.value = value
...

+ logging +`モジュールにはhttps://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3#table-of-logging-levels [デフォルトレベル]の `+がありますWARNING + `。これは + DEBUG + `より上のレベルです。 この例ではデバッグに `+ logging `モジュールを使用するので、 ` logging.DEBUG +`のレベルがコンソールに情報を返すように設定を変更する必要があります。 import statementの下に次の行を追加することでこれを行うことができます。

pizza.py

import logging




class Pizza():
...

このレベルの「+ logging.DEBUG 」は、しきい値を設定するために上記のコードで参照する定数整数値を指します。 ` DEBUG +`のレベルは10です。

次に、すべての `+ print()`ステートメントを ` logging.debug()`ステートメントに置き換えます。 定数である ` logging.DEBUG `とは異なり、 ` logging.debug()`は ` logging `モジュールのメソッドです。 このメソッドを使用する場合、 ` print()+`に渡されるhttps://www.digitalocean.com/community/tutorial_series/working-with-strings-in-python-3[string]と同じものを使用できます。以下に示すように。

pizza.py

import logging

logging.basicConfig(level=logging.DEBUG)


class Pizza():
   def __init__(self, name, price):
       self.name = name
       self.price = price


   def make(self, quantity=1):


   def eat(self, quantity=1):


pizza_01 = Pizza("artichoke", 15)
pizza_01.make()
pizza_01.eat()

pizza_02 = Pizza("margherita", 12)
pizza_02.make(2)
pizza_02.eat()

この時点で、 `+ 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)

ログメッセージには重大度レベル「+ DEBUG 」と「 root 」という単語が埋め込まれています。これはPythonモジュールのレベルを指します。 ` logging +`モジュールは、異なる名前を持つロガーの階層で使用できるため、モジュールごとに異なるロガーを使用できます。

たとえば、異なる名前と異なる出力を持つ異なるロガーに等しいロガーを設定できます。

logger1 = logging.getLogger("module_1")
logger2 = logging.getLogger("module_2")

logger1.debug("Module 1 debugger")
logger2.debug("Module 2 debugger")
OutputDEBUG:module_1:Module 1 debugger
DEBUG:module_2:Module 2 debugger

`+ logging `モジュールを使用してコンソールにメッセージを出力する方法を理解できたので、次に ` logging +`モジュールを使用してメッセージをファイルに出力します。

メッセージをファイルに記録する

`+ logging +`モジュールの主な目的は、コンソールではなくファイルにメッセージを記録することです。 メッセージのファイルを保持することで、コードをどのように変更する必要があるかを確認できるように、時間をかけてデータを参照して定量化できます。

ファイルへのロギングを開始するには、 `+ logging.basicConfig()`メソッドを変更して ` filename `パラメーターを含めることができます。 この場合、ファイル名「 test.log +」を呼び出しましょう。

pizza.py

import logging

logging.basicConfig( level=logging.DEBUG)


class Pizza():
   def __init__(self, name, price):
       self.name = name
       self.price = price
       logging.debug("Pizza created: {} (${})".format(self.name, self.price))

   def make(self, quantity=1):
       logging.debug("Made {} {} pizza(s)".format(quantity, self.name))

   def eat(self, quantity=1):
       logging.debug("Ate {} pizza(s)".format(quantity, self.name))

pizza_01 = Pizza("artichoke", 15)
pizza_01.make()
pizza_01.eat()

pizza_02 = Pizza("margherita", 12)
pizza_02.make(2)
pizza_02.eat()

上記のコードは前のセクションと同じですが、印刷するログのファイル名を追加した点が異なります。 `+ python pizza.py `コマンドでコードを実行すると、ディレクトリに ` test.log +`という新しいファイルが作成されます。

nano(または選択したテキストエディター)で `+ test.log +`ファイルを開きましょう:

nano test.log

ファイルが開くと、次のように表示されます。

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)

これは、前のセクションで出会ったコンソール出力に似ていますが、現在は `+ test.log +`ファイルにあることを除いています。

+ CTRL + + `+ x `でファイルを閉じて、 ` pizza.py +`ファイルに戻り、コードを変更できるようにします。

コードの大部分は同じままにしますが、2つのピザインスタンス「+ pizza_01 」と「 pizza_02 +」のパラメータを変更します。

pizza.py

import logging

logging.basicConfig(filename="test.log", level=logging.DEBUG)


class Pizza():
   def __init__(self, name, price):
       self.name = name
       self.price = price
       logging.debug("Pizza created: {} (${})".format(self.name, self.price))

   def make(self, quantity=1):
       logging.debug("Made {} {} pizza(s)".format(quantity, self.name))

   def eat(self, quantity=1):
       logging.debug("Ate {} pizza(s)".format(quantity, self.name))

# Modify the parameters of the pizza_01 object
pizza_01 = Pizza()
pizza_01.make()
pizza_01.eat()

# Modify the parameters of the pizza_02 object
pizza_02 = Pizza()
pizza_02.make()
pizza_02.eat()

これらの変更により、 `+ python pizza.py +`コマンドを使用してプログラムを再度実行しましょう。

プログラムが実行されたら、nanoで `+ text.log`ファイルを再度開くことができます:

nano test.log

ファイルを見ると、いくつかの新しい行が追加され、プログラムが最後に実行された前の行が保持されていることがわかります。

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)

この情報は確かに役立ちますが、追加のhttps://docs.python.org/3/library/logging.html#logrecord-attributes[LogRecord attributes]を追加することでログをより有益なものにすることができます。 主に、LogRecordがいつ作成されたかを示す、人間が読み取れるタイムスタンプを追加します。

この属性を `+ format `というパラメーターに追加し、表に示すように文字列 `%(asctime)s `で参照することができます。 さらに、 ` DEBUG `レベル名を保持するには、文字列 `%(levelname)s `を含める必要があり、ロガーに印刷を要求する文字列メッセージを保持するには `%(メッセージ)s + `。 以下に追加するコードに示すように、これらの各属性は「コロン」で区切られます。

pizza.py

import logging

logging.basicConfig(
   filename="test.log",
   level=logging.DEBUG,

   )


class Pizza():
   def __init__(self, name, price):
       self.name = name
       self.price = price
       logging.debug("Pizza created: {} (${})".format(self.name, self.price))

   def make(self, quantity=1):
       logging.debug("Made {} {} pizza(s)".format(quantity, self.name))

   def eat(self, quantity=1):
       logging.debug("Ate {} pizza(s)".format(quantity, self.name))

pizza_01 = Pizza("Sicilian", 18)
pizza_01.make(5)
pizza_01.eat(4)

pizza_02 = Pizza("quattro formaggi", 16)
pizza_02.make(2)
pizza_02.eat(2)

`+ python pizza.py `コマンドで属性を追加して上記のコードを実行すると、レベルに加えて人間が読めるタイムスタンプを含む新しい行が ` test.log `ファイルに追加されます。 ` DEBUG +`の名前と、ロガーに文字列として渡される関連メッセージ。

OutputDEBUG: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)

必要に応じて、プログラムファイルのログを作成するために、コードで追加のhttps://docs.python.org/3/library/logging.html#logrecord-attributes[LogRecord attributes]を使用することができます。あなたに関連します。

デバッグとその他のメッセージを別々のファイルに記録すると、時間の経過とともにPythonプログラムの全体的な理解が得られ、プログラムに加えられた履歴作業によって通知される方法でコードのトラブルシューティングと修正を行うことができます。発生するイベントとトランザクション。

ロギングレベルの表

開発者は、重大度レベルを追加することにより、ロガーでキャプチャされるイベントの重要度を割り当てることができます。 重大度レベルを以下の表に示します。

ロギングレベルは技術的には整数(定数)であり、すべて0の数値でロガーを初期化する `+ NOTSET +`で始まる10ずつ増加します。

事前定義されたレベルに関連して独自のレベルを定義することもできます。 同じ数値でレベルを定義すると、その値に関連付けられた名前が上書きされます。

次の表は、さまざまなレベル名、それらの数値、レベルを呼び出すために使用できる関数、およびそのレベルの用途を示しています。

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.basicConfig(level=logging.DEBUG)

https://docs.python.org/3/library/logging.html [公式の `+ logging +`ドキュメント]からコマンドとデバッガーの操作についての詳細を読むことができます。

結論

デバッグは、ソフトウェア開発プロジェクトの重要なステップです。 `+ logging +`モジュールは標準Pythonライブラリの一部であり、ソフトウェアの実行中に発生するイベントの追跡を提供し、これらのイベントを別のログファイルに出力して、コードの実行中に発生することを追跡できるようにします。 これにより、時間の経過に伴うプログラムの実行から発生するさまざまなイベントの理解に基づいて、コードをデバッグできます。