2
5

More than 3 years have passed since last update.

[python3] loggingとClickで簡易的にデバッグログ出力機能を実装する

Posted at

デバッグログを見ながらコードを書いていると、出力のON/OFFを変更するのが面倒になることが多々あります。そこで、コマンドラインからログレベルを変更する小技を紹介します。
※ 本記事は自分で趣味的にコーディングするような場合を想定しています。プロダクトには向かない可能性がありますので、その場合は開発チームの方法に従うことをお勧めします。

まずは普通のログ設定

コード例

まず普通にloggingモジュールを使用し、ログをコンソール出力する場合のコード例を添付します。以下、python3.7を使用しています。

logging_test.py
import logging

from logging import DEBUG, INFO


def set_logger():
    logger = logging.getLogger('logname')
    stream = logging.StreamHandler()
    logger.addHandler(stream)

    logger.setLevel(INFO)

    return logger


def main():
    logger = set_logger()

    logger.debug('debug')
    logger.info('info')


if __name__ == "__main__":
    main()

簡単に説明します。

  • set_loggerでログの設定をしています。返り値のloggerがプログラム内でログ出力に使うインスタンスです。
  • streamはログの出力先を決めるものです。今回はコンソール出力なのでlogging.StreamHandler()を使用しています。ファイルに出力する場合はlogging.FileHandler()を使用します。
  • streamで指定した出力先をlogger.addHandler(stream)でloggerインスタンスに追加します。
  • logger.setLevel(INFO)でログレベルを設定します。今回はINFO(information)レベルに設定しています。
  • そしてlogger.debug('debug')logger.info('info')でログを出力します。

実行結果

上記のコードを実行した結果がこちらです。

>python logging_test.py
info

>

INFOレベルのログは出力されていますが、DEBUGレベルのログは出力されていません。DEBUGレベルのログを出力するには、スクリプト中のログレベル設定のところをlogger.setLevel(DEBUG)とする必要があります。

本題:Clickを使用してログレベル変更

pythonのコマンドラインパーサにClickというものがあります。これを使用すれば、pythonファイルを実行するときにコマンドライン引数を渡す処理が簡単に実装できます。CLI作成用ライブラリといえばPython Fireがとても簡単で便利ですが、個人的にはCLIに渡すことができる変数を明示的に指定できるClickをお勧めしています。

コード例

Clickを使用して先ほどのコードを少しいじります。

logging_test.py
import click
import logging

from logging import DEBUG, INFO


def set_logger(debug_mode):
    logger = logging.getLogger('logname')
    stream = logging.StreamHandler()
    logger.addHandler(stream)

    if debug_mode is True:
        logger.setLevel(DEBUG)
    else:
        logger.setLevel(INFO)

    return logger


@click.command()
@click.option('--debug_mode', '-d', is_flag=True, 
              help='Show debug log')
def main(debug_mode):
    logger = set_logger(debug_mode)

    logger.debug('debug')
    logger.info('info')


if __name__ == "__main__":
    main()

大きな変更があったのはログレベルの設定部分とmain関数にデコレータ(@click.~の部分)が付与されているところです。これについて説明します。

  • まず、main関数に付与されているデコレータ@click.option('--debug_mode', '-d', is_flag=True, help='Show debug log') は、変数debug_modeをコマンドライン引数としてmain関数に渡す設定の部分です。引数は左から順に、ロングオプション、ショートオプション、フラグ(True/False)、ヘルプオプション指定時の説明文です。実行時に--debug_modeまたは-dを追加すると、debug_mode変数にTrueが入ります。
  • 次に、コマンドライン引数として受け取ったdebug_mode変数がset_logger関数に渡されます。この中で-dオプションが指定されている場合はログレベルがDEBUGになり、指定しなかった場合はINFOになります。

実行結果

-dを指定せず実行した場合と、指定して実行した場合の実行結果の比較がこちらになります。

>python logging_test.py
info

>python logging_test.py -d
debug
info

>

-dを指定した場合、DEBUGレベルのログまで出力されていますね。こうすることで、毎回ソースコードのログレベルを変更することなく、デバッグログの出力設定を行うことができます。

参考

最後に、loggingとClickに関して普段私が参考にしているサイトを載せておきます。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5