Udemy講座 Pythonista ロギングの使い所

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

庭に小さな畑があるのですが、ここ数年野菜を作っていませんでした。

今年は、久しぶりにトウモロコシや枝豆、ミニトマトなどを植えたのですが、どうにもトウモロコシの実が出てこないんですよね。

長いこと作物を作っていなかったので、特に土作りをする必要がないと思っていたのですが、やっぱり堆肥や石灰を混ぜ込んで、しっかりと土作りをしなかったのが良くなかったのかもしれません。

とりあえず、トマトと枝豆はできているのですが、一番楽しみにしていたトウモロコシができていないので、ちょっとがっくりしています。

それでは、今日もPython学習をすすめていきましょう!

昨日の復習

昨日は、ロギングコンフィグを使ってログの設定をする方法について学習しました。

ロギングの設定については、fileConfigを使って、ファイルに設定を記述するか、dictConfigを使ってPythonファイルに辞書スキーマで記述して読み込む方法がありました。

Webアプリなどの関係で、最近ではfilConfigを使うより、dictConfigを使って、設定モジュールをインポートするほうが主流になっているとのことでした。

ロギングコンフィグについては、昨日の記事で詳しく解説しています。

それでは、本日の学習にはいりましょう!

ロギングの基本

改めてロギングの基本について復習しておきましょう。

ロギングは、

なにかのログ(履歴など)をどこかに記録すること

です。

つまりPCやスマホ、タブレットでやったことを記録することです。

最近、ネット上で誹謗中傷された有名人が、訴訟を起こす流れが起こっていますが、あれはまさしくロギングのおかげで記録が残っているからできることです。

何も考えていない人は、ネット上は匿名だと思っているようですが、やっていることはすべてログに記録されているので、誰がいつどのようなことをしたのかすぐに分かってしまいます。

ネット上は匿名でなく、個人を特定することが可能なんです。

このことをわかっていない人が多すぎですよね。

そんな重要な役割を持っているのがロギングです。

サイトを運営している人なら必ず使っていると言っていい【Google Analytics】や【Search Console】などのアクセス解析サービスは、取得したログを分析して、サイト改善に役立てるためのサービスです。

つまり、何かを改善するために、ログを記録して分析するために必要不可欠なのがロギングだということです。

ロギングの使い方

最終的には記録したログを分析する必要があるので、ログは分析がしやすいようにkey-valueを使った辞書型のデータを使うことが主流となっています。

import logging


logger = logging.getLogger(__name__)

logger.error({
    'action': 'save',
    'status': 'fail',
    'message': 'csv_file save is fail'
})

出力結果

{'action': 'save', 'status': 'fail', 'message': 'csv_file save is fail'}

データを分析するにはkeyに対応したvalueが保存できる辞書型が最適だということです。

エラーが起こった時にログを調べるにしても、分析しやすい形で保存されていなければ、調査に時間がかかってしまいます。

なので、ログを取る場合は、ログ解析を前提として、辞書型のデータで記録するのが基本ということです。

Jarvisでロギング

これまでは、ロギングの使い方について、単純なログ出力やファイルへ記録する方法を学習してきましたが、少し前に作成した対話型アプリのJarvisでログを取る場所を考えてみましょう。

対話型アプリJarvisのMVCモデルの完成コードはこちらをごらんください。

このコードの中のCSVにデータを保存するranking.pyRankingModelクラスのsaveメソッドでログを取るコードを追加してみます。

import collections
import csv
import logging
import os
import pathlib


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

test_h = logging.FileHandler('logging.log')
logger.addHandler(test_h)

まずは3行目でloggingをインポートして、ロガーを作成します。

今回は、レベルをINFOlogging.logにログを書き込む設定でロガーに設定を渡しています。

本来なら、ロギングの設定ファイルを作って最初にインポートしたほうがいいのですが、あくまで一例としてこのようなコードにしています。

次に、73行目からのsaveメソッドにロガーを追加していきます。

    def save(self, test_arg='test'):
        """CSVファイルを保存する"""
        logger.info({
            'action': 'save',
            'csv_file': self.csv_file,
            'test_arg': test_arg,
            'status': 'run'
        })
        with open(self.csv_file, 'w+') as csv_file:
            writer = csv.DictWriter(csv_file, fieldnames=self.column)
            writer.writeheader()

            for name, count in self.data.items():
                writer.writerow({
                    RANKING_COLUMN_NAME: name,
                    RANKING_COLUMN_COUNT: count
                })
        logger.info({
            'action': 'save',
            'status': 'success'
        })

Jarvisとは全く関係のない引数test_argにデフォルトでtestを入れています。

Jarvisではこの引数は使われませんが、引数がエラーの原因になるかもしれないということで、ログに引数を出力しておけば、どんな値が入っているのかを確認することができるようになる例として追加しています。

81行目からのファイル操作の前に、ロガーを入れていますが、これは、ファイルを書き込む処理がスタートしたのかどうかを確認するためのものです。

save動作がrunしたのかと、ファイル名と引数の値を取得しています。

90行目から93行目までのロガーで、save動作がsuccessしたのかを記録します。

ログの出力結果

本来なら、ロギングの設定ファイルを作って細かい設定を決めておく必要がありますが、今回は最小限のロガー設定でログを記録してみました。

上記の設定で記録したログは、logging.logに保存されますが、ファイルが存在していなければ、作成され、すでにあれば、ファイルの最後に追記されます。

記録されるログは次のようになります。

{'action': 'save', 'csv_file': 'ranking.csv', 'test_arg': 'test', 'status': 'run'}
{'action': 'save', 'status': 'success'}

本来は、フォーマッタで日時も取得しておく必要がありますし、引数であるtest_argもデフォルト以外の値が入ることもあります。

そして、Jarvisを実行するたびに、このログが追記されていくので、もしエラーが起こった時に、どの時点でどこがおかしいのかがわかるということです。

やることがいっぱい

今回は、初めて作成した対話アプリJarvisのCSVファイルへの書き込みについてのログを記録してみました。

なんとなく、これまで学習してきた一つ一つのレクチャーの繋がりを感じていますが、ここまで学習してきて気づいたことは、

アプリ開発ってやることがいっぱい

ってことです。

実際にアプリを動かすコードだけでなく、問題が発生した時に原因を突き止めるためのロギングやアクセス解析のためのアクセスログなどが必要ですし、多分これらのこと以外にもやらなければならないことはたくさんあるので、ほんとやることが多すぎてため息が出てしまいます。

それに、きちんと動作していたとしても、無駄なコードがあったり、不安定な要素があったりするので、まじで頭がオーバーヒートしそうでおそろしい。。。

とはいえ、自分で作ったアプリがきちんと動くとそれまでの苦労も吹き飛んでしまうんでしょうね。

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

Udemy講師 酒井さん プログラミング Python

それでは、明日もGood Python!