Python入門【ロギングの基本(ログファイルの作成)】

Python logging

こんにちは、ミナトです。

「Pythonでログを出力するにはどうすればいいの?」

というあなたのために今回はPythonでのロギングの基本について解説します。

初心者にも分かりやすく解説していますので、ぜひご確認ください。

Pythonでログを出力するにはどうすればいいの?
アプリケーションでの障害や不具合がが発生した場合、ログがあると解決しやすくなるので、ログは重要やな!
今回はPythonでのロギングの基本について解説するな😆
以下のような方を対象としています
  • Pythonでのロギングについて知りたい
  • ログファイルの作成方法について知りたい
  • Pythonでプログラミングを学びたい初心者

ロギングの基本

ロギングの使い方

Pythonでログを扱うには、loggingモジュールを利用します。

まずは、loggingモジュールの基本的な使い方を確認します。

import logging

logging.critical('CRITICAL MESSAGE')
logging.error('INFO ERROR')
logging.warning('WARNING MESSAGE')
logging.info('INFO MESSAGE')
logging.debug('DEBUG MESSAGE')


## 出力
CRITICAL:root:CRITICAL MESSAGE
ERROR:root:INFO MESSAGE
WARNING:root:WARNING MESSAGE

上記を実行するとCRITICAL、ERROR、WARNINGの3つしか出力されていません。

Pythonには、ログレベルというログの重要度を示す値が存在し、設定したログレベル以上の重要度のログしか出力されません。

そして、デフォルトのログレベルがWARNINGとなっているため、初期状態ではCRITICAL、ERROR、WARNINGしか表示されません。

ログレベル用途
DEBUG開発時などのデバッグ用途で利用
INFO想定された通りの処理が実行されたことの確認
WARNING想定外の問題が発生した場合(処理を継続して実行できる)
ERROR想定外の問題が発生した場合(処理を継続して実行できない)
CRITICALログラム自体が実行を継続できない、重大なエラーが発生した場合
ログレベル

ログレベルの変更

ログレベルを変更するためには、basicConfig()を利用します。

ログレベルの変更
  • logging.basicConfig(level=ログレベル)

以下の例では、ログレベルをDEBUGに設定してます。デフォルトで出力されなかったINFOとDEBUGが出力されるようになります。

import logging

logging.basicConfig(level=logging.DEBUG)

logging.critical('CRITICAL MESSAGE')
logging.error('ERROR MESSAGE')
logging.warning('WARNING MESSAGE')
logging.info('INFO MESSAGE')
logging.debug('DEBUG MESSAGE')


## 出力
CRITICAL:root:CRITICAL MESSAGE
ERROR:root:ERROR MESSAGE
WARNING:root:WARNING MESSAGE
INFO:root:INFO MESSAGE
DEBUG:root:DEBUG MESSAGE

変数の出力

ログの中で変数を出力するには、以下のように「%s」を用いて記述します。

import logging

logging.basicConfig(level=logging.INFO)

v1 = 'test1'
v2 = 'test2'
v3 = 'test3'

logging.info('info message: %s %s %s', v1, v2, v3)

## 出力
INFO:root:info message: test1 test2 test3

ログファイルの出力

ログファイルを出力するためには、basicConfig()の引数filenameを指定します。

ログファイルの出力
  • logging.basicConfig(filename=ファイル名)

以下の例では、example.logという名前のファイルにログを書き込んでいます。

import logging

logging.basicConfig(filename='example.log', level=logging.INFO)

logging.info('ログをログファイルに出力します。')

フォーマッタの使い方

フォーマッタを利用することでログの出力形式を指定できます。

フォーマットの変更
  • logging.basicConfig(format=フォーマット文字列)

フォーマットの中では、様々なLogRecord 属性を利用できます。

以下の例では、asctime(ログが生成された時刻)とlevelname(ログレベル)を出力しています。

import logging

formatter = '%(asctime)s : %(levelname)s : %(message)s'
logging.basicConfig(format=formatter, level=logging.INFO)

logging.info('ログをログファイルに出力します。')

## 出力
2021-07-11 11:56:17,524 : INFO : ログをログファイルに出力します。

ロガーの使い方

Loggerオブジェクトを利用して、ログを出力することができます。Loggerを利用することでより柔軟にログの設定が行えるため、開発の中でもLoggerを利用してログを出力するケースが多いです。

以下の例では、main.pyからlogtest.pyをインポートしてlogtest.pyのlog_test()メソッドを実行しています。

mian.pyでは、ログレベルがINFOに設定されているため、debug()の値が出力されていません。

一方、logtest.pyでは、logger.setLevel()メソッドを利用してログレベルをDEBUGに変更しているため、debug()の値もコンソールに出力できています。

このようにLoggerオブジェクトを用いることで、処理ごとにログレベルを変更して利用するといったことができます。

また、getLogger(__name__)のように引数に__main__を渡すことで、どのモジュールで実行されたかが記されるため、ログの発生箇所が分かりやすくなります。

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


def log_test():
    logger.info('logtest info')
    logger.debug('logtest debug')
import logging
import logtest

logging.basicConfig(level=logging.INFO)

logger = logging.getLogger(__name__)

logger.info('main log info')
logger.debug('main log debug')

logtest.log_test()


## 出力
INFO:__main__:main log info
INFO:logtest:logtest info
DEBUG:logtest:logtest debug

ハンドラーの使い方

ログの出力先を設定するためにはHandler(ハンドラー)を利用します。

Handlerを利用することでログをコンソールに出力したり、ファイルに出力したりメールで通知するなど様々な出力先を設定できます。

ハンドラーを追加するにはHadlerオブジェクトを作成し、loggerのaddHandler()メソッドの引数に渡します。

ハンドラーの追加
  • logger.addHandler(ハンドラーオブジェクト)

以下の例ではFileHandlerを追加して、標準出力とファイルにログを出力しています。

import logging

logging.basicConfig(level=logging.INFO)

logger = logging.getLogger(__name__)
h = logging.FileHandler('example.log')
logger.addHandler(h)


logger.info('ログをファイルに出力します。')

Pythonには様々なハンドラーが用意されているので、興味がある方は公式ドキュメントを確認してください。

公式ドキュメント

フィルタの使い方

フィルタを利用することで特定のログのみを出力するようにフィルタリングできます。

フィルタを定義するためには、logging.Filterクラスを継承したクラスを定義し、filter()メソッドをオーバーライドします。

filter()メソッドはログに出力する場合Trueを、出力しない場合はFalseを返すように実装します。

フィルタの定義

class フィルタクラス名(logging.Filter):
 def filter(self, record):
  処理

また、loggerにフィルタを使いするにはaddFilter()メソッドを利用します。

フィルタの追加

logger.addFilter(フィルタオブジェクト)

アプリケーションの実行時に誤ってユーザーが入力したパスワードがログに出力されないように以下の例では、出力内容にpasswordという文字列が含まれている場合はログを出力しないようにフィルタリングしています。

import logging

logging.basicConfig(level=logging.INFO)


class ProtectPasswordFilter(logging.Filter):
    def filter(self, record):
        log_message = record.getMessage()
        return 'password' not in log_message


logger = logging.getLogger(__name__)
logger.addFilter(ProtectPasswordFilter())

logger.info('password = "xxxxxxxxx"')
logger.info('user_id = "xxxxxxxxx"')


## 出力
INFO:__main__:user_id = "xxxxxxxxx"

まとめ

loggingモジュールを利用することで、簡単にログを扱うことができます。

ログは障害や不具合を解決するために非常に重要な材料となります。

loggingモジュールには、非常に便利な機能が多く用意されているので、その都度ドキュメントを読みロギングについて慣れるようにしましょう。

最後まで読んでいただき、ありがとうございます。

この記事が、「面白いな」、「勉強になったな」という方は、SNSでシェアしていただけると嬉しいです。