Pythonでログ取得のベストプラクティスは?サービスの品質を維持する監視の考え方

当サイトでは一部リンクに広告が含まれています

アプリケーションを作る時、ログ(記録)を取ることは大切な作業です。
ログを取るというのは、プログラムがどのように動いているのか、ユーザーはどのような操作を行ったのかといった情報を記録しておくことです。

そんな時、Pythonにはこの作業を行うためのloggingというモジュールがありますので、この記事では、Pythonでログを取る時の有効な方法について説明します。

目次

ログを取ることの大切さ

アプリケーションのログとは、エラー情報や警告、情報などのメッセージを記録する作業のことです。
これらのメッセージは、アプリケーションが動いている間に起こる色々な出来事を記録します。
後でこの情報を見れば、何が問題だったのか、何が原因で問題が起きたのかを解析したり、問題を特定して解決するための手がかりを得ることができます。

ログを適切に取ることは、アプリケーションの品質を高める上で大切です。
どのような情報をどのような形式でログに記録するかを決めておけば、アプリケーションのメンテナンスが楽になります。
また、問題が起きたときに、その原因を探しやすくなります。

ログを取る上での基本的な考え方

1. ログのレベルを適切に使う

ログには、DEBUG、INFO、WARNING、ERROR、CRITICALという5つのレベルがあります。

それぞれのレベルは、記録する情報の重要度によって使い分けます。
適切なレベルを使うと、どの情報が重要なのかがわかりやすくなり、また、必要な情報だけを選んで見ることができます。

例えば、アプリケーションを作っている時にはDEBUGレベルの情報が役に立ちますが、一方で、アプリケーションがユーザーに使われる本番環境では、そのような詳細な情報は必要ないかもしれません。

実際のログの例を見てみましょう。

2019-01-01 00:00:00,000 - DEBUG - main - データベースに接続しました。
2019-01-01 00:00:00,001 - WARNING - main - データベースからデータを取得できませんでした。
2019-01-01 00:00:00,002 - ERROR - main - データを処理できませんでした。
2019-01-01 00:00:00,003 - CRITICAL - main - データを保存できませんでした。

このログは、どのレベルの情報なのかがわかりやすくなっています。

上記の例では、以下のようなレベルの情報を記録しています。

  • DEBUG:デバッグ用の情報
  • WARNING:警告
  • ERROR:エラー
  • CRITICAL:重大なエラー

このように、適切なレベルを使うとどの情報が重要なのかがわかりやすくなり、また、必要な情報だけを選んで見ることができます。

2. ログの形式を統一する

ログの形式が統一されていると、ログの情報を見るのが楽になります。
ログには、何時に何が起きたのか、どのレベルの情報なのか、どの部分の情報なのかといった情報を含めます。
さらに、何が問題だったのか、問題が起きた時の詳細な状況といった情報も加えると、問題解決のための手がかりを得やすくなります。

実際のログの例を見てみましょう。

2019-01-01 00:00:00,000 - INFO - main - データベースに接続しました。
2019-01-01 00:00:00,001 - INFO - main - データベースからデータを取得しました。
2019-01-01 00:00:00,002 - INFO - main - データを処理しました。
2019-01-01 00:00:00,003 - INFO - main - データを保存しました。

このログは、何時に何が起きたのか、どのレベルの情報なのか、どの部分の情報なのかといった情報を含んでいます。
このように、ログの形式を統一しておくと、ログの情報を見るのが楽になります。

3. ログの回転を設定する

ログの情報が増えてくると、その量がとても大きくなることがあります。
その結果、ディスクの空き容量を無駄に使ってしまったり、ログの情報が探しにくくなったりすることがあります。
そこで、ログの回転という方法を使います。
ログの回転とは、古いログを消したり、アーカイブ(保管)したりすることです。
日ごと、週ごと、あるいはログのサイズに応じてログを回転させることで、ログの量を適切に保ち、ディスクの空き容量を有効に使うことができます。

Pythonでのログ取得の基本的な方法

Pythonのloggingモジュールを使えば、これまでに説明した方法を適用することができます。
以下に、具体的な手順を示します。

まずはloggingモジュールをインポートします。

import logging

次に、ログを取るためのオブジェクトを作ります。

logger = logging.getLogger(__name__)

続いてハンドラを作り、ログのレベルを設定します。
ハンドラとは、ログの情報をどこにどのように出力するかを決める部分です。

handler = logging.StreamHandler()
handler.setLevel(logging.INFO)

フォーマッタを作り、ハンドラに設定します。
フォーマッタとは、ログの情報をどのような形式で出力するかを決める部分です。

formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

ロガーにハンドラを追加します。

logger.addHandler(handler)

これでログの設定が完了しました。

ログを取るには、以下のようにします。

logger.info('データベースに接続しました。')
logger.warning('データベースからデータを取得できませんでした。')
logger.error('データを処理できませんでした。')
logger.critical('データを保存できませんでした。')

ログのレベルに応じて、以下のようにログが出力されます。

2019-01-01 00:00:00,000 - INFO - main - データベースに接続しました。
2019-01-01 00:00:00,001 - WARNING - main - データベースからデータを取得できませんでした。
2019-01-01 00:00:00,002 - ERROR - main - データを処理できませんでした。
2019-01-01 00:00:00,003 - CRITICAL - main - データを保存できませんでした。

まとめ

今回は、ログの基本的な考え方と、Pythonでのログ取得の基本的な方法を学びました。

ログは、プログラムの実行状況を記録するためのものであり、プログラムの実行状況を把握するために重要なものです。
特に、プログラムの実行状況を把握することは、プログラムのバグを見つけるために重要ですので、早めにログの取り方は覚えておきましょう!

目次