Pythonプログラマが把握しなければならないログ記録


前に書く
私達の現実生活の中で、「日誌記録」は実はとても重要なことです。例えば銀行の振替記録、自動車のドライブレコーダーは走行中のすべてを記録しています。もし何か問題があったら、私達は「日誌記録」を通じて底に何が起こったのかを知ることができます。
日常のシステム開発やデバッグなどの過程で、ログを記録することも重要です。多くのプログラミング初心者は「ログを記録する」という習慣がないので、ログを記録することはあってもなくてもいいことだと思います。問題が発生した時はprint関数を使ってプログラムの中間結果を印刷すればいいです。本当にtoo young too naiveです。ただのprintなら簡単なスクリプトプログラムにとってはいいかもしれませんが、複雑なシステムに遭遇しても、printという方法だけを使うと、大量のニュースが見られます。吐きを見ても、その中で役に立つ情報が見つかるとは限りません。
「ログ」はシステムの重要な構成部分で、ユーザー操作、システム運行状態とエラー情報を記録します。その善し悪しはシステムに問題が発生した時の位置付けの速度に直接影響します。ログ記録があります。サービスが崩壊した時に素早くログを見て問題が発生したところを発見することができます。同様にログの観察と分析もできます。システムに存在する可能性のあるリスクを事前に発見する。
Pythonの標準ログモジュール
上記のように「日誌」は重要です。何でもできるPythonとしてはもちろん日誌関連の機能もあります。Python標準ライブラリにはlogingモジュールが提供されています。最も簡単な使用では、デフォルトではログをスクリーン端末に印刷して、直接にロゴモジュールを導入して、debug、info、warn、error、criticalなどの関数を呼び出してログを記録します。標準ログのレベルはwarningで、レベルがwarningより高いログが表示されます。「レベル」は論理的な概念で、ログの重要度を区別するために使われます。

import logging

logging.debug('debug message')
logging.info("info message")
logging.warn('warn message')
logging.error("error message")
logging.critical('critical message')
上記コードの実行結果は以下の通りです。
WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message
上記で述べましたが、printを使うと大量の情報が発生し、その中から本当に役に立つ情報を見つけるのは難しいです。logingでは、ログを異なるレベルに分けてから、ほとんどの時間でレベルの高いログ情報だけを保存して、ログの性能と分析速度を向上させました。そうすると、私たちは大きなログファイルから間違った情報を素早く見つけることができます。
ログの書式設定
ログを記録する前に簡単な設定を行います。

import logging

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

logging.debug('debug message')
logging.info("info message")
logging.warn('warn message')
logging.error("error message")
logging.critical('critical message')
上記の例では、BaicConfigでログを簡単に構成しましたが、実はもっと複雑な配置ができます。その前に、まずlogingのいくつかの概念を調べてみます。
  • ロギング:ログレコーダは、アプリケーションで直接使用できるインターフェースです。
  • Handler:ログプロセッサは、ログをどこに保存しますか?どれぐらい保存しますか?
  • Formater:ログの出力フォーマットを設定するためにフォーマットします。
  • 上記三者の関係は、ロギングは一つのハードラーを使い、一つのハードラーは一つのFormaterを使います。概念は分かりました。どうやってそれらを使うべきですか?私たちのロゴの中には多くの方法でファイルを配置しています。簡単には上記のBaicConfigを使って、ログの構成を一つの構成ファイルに保存して、メインプログラムでfileConfigを使ってプロファイルを読み取ります。
    基本的な知識は分かりました。以下は小さいテーマを作ります。ログファイルはすべてのdebugと以上のレベルのログを保存しています。各ログにはログを印刷する時間、ログのレベルとログの内容が必要です。まず自分で考えてみてください。もう考え終わったら、下を見てください。
    
    import logging
    
    logging.basicConfig(
      level= logging.DEBUG,
      format = '%(asctime)s : %(levelname)s : %(message)s',
      filename= "test.log"
    )
    
    logging.debug('debug message')
    logging.info("info message")
    logging.warn('warn message')
    logging.error("error message")
    logging.critical('critical message')
    上記コードの一回の運転結果は以下の通りです。
    2018-10-19 22:50:35,225:DEBUG:debug message
    2018-10-19 22:50:35,225:INFO:infoメッセージ
    2018-10-19 22:50:35,225:WARNING:warn message
    2018-10-19 22:50:35,225:ERROR:error message
    2018-10-19 22:50:35,225:CRITICAL:critical message
    先ほど上記で述べましたが、私たちはログの構成を一つのプロファイルに保存して、メインプログラムでfileConfigを使ってプロファイルを読み込むことができます。以下では典型的なログプロファイル(プロファイル名はloging.com nf)を見てみましょう。
    
    [loggers]
    keys = root
    
    [handlers]
    keys = logfile
    
    [formatters]
    keys = generic
    
    [logger_root]
    handlers = logfile
    
    [handler_logfile]
    class = handlers.TimedRotatingFileHandler
    args = ('test.log', 'midnight', 1, 10)
    level = DEBUG
    formatter = generic
    
    [formatter_generic]
    format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s] %(message)s
    上記のログ設定ファイルでは、まず「loggers」でrootというログレコーダ(logger)を宣言し、「handles」でlogfileというログプロセッサ(handler)を宣言し、「formaters」でgeneranicというフォーマットを宣言しました。その後[logger_]にいますrootでは、rootというログプロセッサ(logger)が使用するログプロセッサ(handler)を定義します。ログファイルにはログプロセッサの出力ログの方式、ログファイルの切り替え時間などが定義されています。最後は「formater_」です。ジェネリックではログの作成時間、レベル、ファイル名、行番号などの情報を含むログのフォーマットを定義しています。
    上記のプロファイルがあれば、メインコードでloging.com nfモジュールのfileConfig関数を使ってログの設定をロードすることができます。
    
    import logging
    import logging.config
    
    logging.config.fileConfig('logging.conf')
    
    logging.debug('debug message')
    logging.info("info message")
    logging.warn('warn message')
    logging.error("error message")
    logging.critical('critical message')
    上記のコードの実行一回の結果は以下の通りです。
    2018-10-19 23:00:02,809 WARNI[root:8]warn message
    2018-10-19 23:00:02,809 ERROR[root:9]error message
    2018-10-19 23:00:02,809 CRITI[root:10]critical message
    後に書く
    タイトルにもあるように、「ログ記録」は各Pythonプログラマーが知っておくべきものであり、習得するべきものであり、プログラマごとの意識でもあると思います。もしあなたが以前にログを使ったことがないなら、あるいはログをどうやって使えばいいか分かりません。この文章はあなたに助けを与えてくれると信じています。
    Pythonのログライブラリはデザインが良く、使い勝手がよく、Python標準ライブラリの中でもかなり優秀な存在と言えます。もちろん上に述べたのはPythonのログライブラリの中のほんの一部です。もっと多くの操作と内容は今後の学習と実践の中で自分で掘り起こして運用する必要があります。
    The end
    以上はPythonプログラマーが把握しなければならないログの詳細です。pythonログに関する資料は他の関連記事に注目してください。