Python logging ロギング

Python学習【365日チャレンジ!】123日目のマスターU(@Udemy11)です。

123というと、パチンコ店をイメージするのは私だけでしょうか?

やっぱり数字が並ぶと気持ちがウキウキしちゃいます。

Python学習365日チャレンジも1/3を超えて、最終目標がぼやっと見えてきましたが、まだまだ学習しないといけないことはたくさんあります。

しっかりと気を引き締めてPython学習を継続していきたいと思います。

昨日の復習

昨日は、Pythonの記述ルールについて、誰もが見やすいコードを書くために、改めて学習し直しました。

importの基本的な記述ルールからはじまり、空白行の挿入ルールやインデントが半角スペースを4つ入れること、変数や関数の名前の付け方は、キャメルケースやスネークケースなどがありました。

詳しいコードスタイルについては、こちらの記事を参考にしてください。

それでは本日の学習、ロギングに入っていきましょう!

ロギングとは

ロギングをネットで調べると次のような説明が見つかります。

ロギングとは

ロギングとは、起こった出来事についての情報などを一定の形式で時系列に記録・蓄積すること。そのように記録されたデータのことを「ログ」(log)という。

ようするに、あとから、何をしたのかわかるように、記録に残すことです。

いまだに匿名と思われているツイッターなどの発言は、実はロギングによって、記録された情報をたどることができるので、どこの誰なのかわかってしまうわけです。

犯罪に関係していない場合はその情報が開示されることはありませんが、誹謗中傷などで訴えられた場合、あなたの情報が開示されることは間違いないので、ネットでの発言にも責任が伴うということを理解しておきましょう。

ログの種類

ロギングで取得できるログはさまざまで、一例として次のようなものがあります。

  • ファイアーウォールの通信情報
  • DHCPサーバのIPアドレス割当情報
  • ファイルサーバへのアクセス情報
  • Webサーバへのアクセス情報
  • データベースサーバへのアクセス情報
  • 各種アプリケーションの処理情報
  • パソコンの操作ログ

ロギングは、ありとあらゆる情報を取得して、自動的に記録に残せるので、いってみればアプリケーションが書く日記のようなものですね。

記録に残していれば、なにか問題が生じたときに、ログを分析することで、原因を特定できるので、プログラミングにおいて、ロギングは必須ということです。

ログのレベル

Pythonでは、ロギングをするにあたって、取得するログの種類によって、5つのレベルに分けて記録をとることができます。

  • CRITICAL:危機的な状態
  • ERROR:実行時のエラー
  • WARNING:エラーではない例外処理
  • INFO:通常処理に関する情報
  • DEBUG:デバッグに関する情報

日本語の説明をみるとわかりますが、緊急性の高いものから順番に並んでいます。

この5つの内、loggingモジュールを使ってデフォルトの設定でログを記録できるのは、CRITICALERRORWARNINGの3つです。

INFODEBUGについては、別途デフォルト引数を指定しないとloggingのコードを書いたとしても記録することはできません。

こんな説明をしてもちょっとわかりづらいと思うので、実際に処理する際のコードを書いてみましょう。

loggingの処理方法

実際にログを出力するには、printをつかう必要はなく、次のように記述します。

import logging


logging.critical('危機的')
logging.error('エラー')
logging.warning('警告')
logging.info('情報')
logging.debug('デバッグ')

出力結果

CRITICAL:root:危機的
ERROR:root:エラー
WARNING:root:警告

4行目から8行目で、それぞれのレベルのログを出力するコードを書いているにもかかわらず、出力されているのは、警告までです。

このように、loggingのデフォルト設定では、警告レベルまでの出力しかできないということです。

ログのレベルをdebugまで出力するには、次のコードを出力コードより前の行に記述します。

logging.basicConfig(level=logging.DEBUG)

baxicConfigの引数levelにレベルを指定することで、出力できるレベルを変更することができます。

ロギングの出番

私自身勘違いしていたのですが、レベルに合わせたコードを書けば、勝手に警告とかのログを記録してくれるとおもっていました。

しかし、ログを出力させることができるだけで、実際にどんなログを出力させるのかは、プログラマーが決めてコードを書く必要があります。

つまり

こんなことが起これば、ちょっとやばいよね

ということが起こった場合、ログを記録するというコードを書く必要があるわけです。

以前学習したtry-except文は、エクセプションが起こった場合、エラーを起こさずに処理を続けるために使いました。

例えば、この時にエラーが起こっていることをログに出力すれば、普通に動いているけどエクセプションが発生していることがわかるわけですね。

ログの出力内容

ログを出力するには、loggingモジュールをインポートして、logging.critical()をはじめとする5つのメソッドに引数(例えば’警告’)を入れました。

出力メソッドの引数には、.format()を使って変数などを代入することもできます。

import logging


logging.warning('warning {} {}'.format('name', 'attention'))
logging.warning('warning %s %s' % ('name', 'attention'))
logging.warning('warning %s %s', 'name', 'attention')

これらの出力はすべてWARNING:root:warning name attentionとなりますが、5行目と6行目の%sを使った値の代入は、古いPythonのコードに出てくることがあるので、覚えておきましょう。

ログをファイルへ出力

これらのログは、Pythonファイルを実行すると、コンソールへ出力されますが、本来はログファイルへ出力する必要があります。

ファイルへ出力するための設定は、basicConfigのデフォルト引数filenameを使って指定します。

import logging


logging.basicConfig(filename='lessonlog.log')

logging.warning('これは困った!警告です')

このコードを書いているPythonファイルと同じ階層にlessonlog.logが作成され、中身はWARNING:root:これは困った!警告ですとなります。

今回は、日本語でログ文章を書いていますが、自分一人もしくは、日本人しか使うことが無いアプリなどで、グローバル展開をしないのなら、日本語のログでも問題はありません。

ただ、日本語だと文字コードによって文字化けするリスクがあるので、ログは英語で書いた方がいいでしょう。

ロギングは必須

自分だけしか使わないプログラムだとしても、ものすごく短いプログラムで無い限り、ロギングは必須です。

プログラムがうまく動かなくなったときに、どの時点でエラーが起こっているのかを特定する必要がありますので、ロギングしていない場合は、デバッグをして、一つ一つコードをチェックしていく必要があります。

しかし、ロギングできちんとログを残しておけば、どこでエラーが発生しているのかを特定することが容易になります。

話は飛びますが、先日Amazonプライムで観た『AI崩壊』でも、人工知能【のぞみ】のログを解析することで、どこでプログラムが書き換えられているのかを特定できていました。

いろいろと突っ込みどころ満載の内容でしたが、邦画としてはなかなか楽しむことができた部類に入るのではないでしょうか?

AI崩壊

ということで、今日はロギングの基本的なことについて学習しましたが、なんとなくロギングのことがわかってきたでしょうか?

ロギングに関してはまだまだ学習することがありますので、明日もさらにロギングについて学習します。

それでは明日も、Good Python!