メインコンテンツへスキップ
LogBrew は、開発者とコーディングエージェントのための Observability(可観測性)プラットフォームです。無料枠が充実していて、カードの登録は不要です。 このガイドでは、標準の logging モジュールを使った Python logging、Python の5つのログレベル、Python のエラー処理、よくある Python のエラーの種類を説明します。最後のセクションでは、logbrew-sdk 0.1.29 を使って同じログとクラッシュを LogBrew に送信します。どの例も Python 3.13 で実行しました。出力のブロックはすべて実際の出力です。 Flask アプリケーションの場合は、代わりに Flask のログを使ってください。同じログ設定にリクエストのトレースが加わります。

Python logging で最初のログを出力する

このファイルを app.py として保存します。logging.basicConfig() は、プログラムのエントリーポイントで1回だけ呼び出します。各モジュールでは名前付きのロガーを取得します。
python3 app.py を実行します。出力は標準エラー出力に送られます。
レベルが INFO なので、debug のレコードは表示されません。logger.exception() は ERROR レベルでログを記録し、トレースバックを追加します。このメソッドは except ブロックの中だけで呼び出してください。 値は "payment retry %d of %d", 2, 3 のように引数として渡します。Python は、ハンドラーがレコードを受け付けたときにだけメッセージを組み立てます。メッセージのテンプレートはどの再試行でも同じなので、そのテンプレートで検索できます。

Python のログレベル

ロガーがレコードを送るのは、レコードのレベルがロガーのレベル以上のときだけです。ハンドラーには、それより高い2つ目のレベルを設定できます。 ルートロガーの初期レベルは WARNING です。新しいロガーのレベルは NOTSET(0)で、親のレベルを使います。本番環境では INFO を設定します。DEBUG は開発中か、短時間の診断のときだけ使います。
1行目は、1つのモジュールのデバッグレコードを表示します。2行目は、ライブラリのノイズを抑えます。

ロガー、ハンドラー、フォーマッター

  • ロガーは呼び出しを受け取ります。ロガー名がモジュールのパスと一致するように、logging.getLogger(__name__) を使います。
  • ハンドラーは、コンソール、ファイル、LogBrew などの送信先にレコードを送ります。
  • フォーマッターは、レコードをテキストに変換します。
ライブラリではログを設定しないでください。ライブラリは自身のロガーに logging.NullHandler() だけを追加します。ハンドラーとレベルは、アプリケーションが1回だけ設定します。設定が大きい場合は logging.config.dictConfig() を使います。

Python のエラー処理

処理できる例外のうち、最も具体的なものをキャッチします。成功したときだけ実行するコードには else を、常に実行するコードには finally を使います。元の原因を残すには raise ... from error を使います。 このファイルを orders.py として保存します。
出力には、例外チェーンの2つの例外が両方とも表示されます。
例外ごとに、次のルールに従います。
  • 例外は、処理する場所で1回だけログに記録します。各レイヤーでログに記録してから再送出しないでください。レイヤーごとに重複したレコードが増えます。
  • except Exception: pass と書かないでください。エラーを無視する場合は、理由を添えて WARNING 以上のレベルでログに記録します。
  • BaseException ではなく Exception をキャッチします。BaseException は、意図的にプログラムを止める KeyboardInterrupt と SystemExit もキャッチします。
  • 呼び出し側で処理する必要があるエラーには、OrderError のように独自の例外クラスを定義します。

複数のエラーを報告する

Python 3.11 以降では ExceptionGroup を送出できます。1回のチェックで複数の問題が見つかったときに使います。種類ごとに except* で処理します。

よくある Python のエラーの種類

プログラムで処理できる組み込みのエラーは、すべて Exception を継承しています。次の表に、よく見る Python のエラーと、それぞれで最初に確認することをまとめます。 KeyboardInterrupt と SystemExit は、Exception ではなく BaseException を継承しています。これらはコードのエラーではありません。

Python のログを LogBrew に送信する

LogBrewLoggingHandler は標準のロギングハンドラーです。受け付けた各レコードを LogBrew に送信します。コンソールのハンドラーはそのまま変わりません。
1

プロジェクトのキーを作成する

CLI でサインインします。プロジェクトを作成し、その取り込みキーを所有者だけが読めるファイルに保存します。
CLI はキーを表示しません。本番環境では、利用しているプラットフォームのシークレット管理機能を使ってください。
2

SDK をインストールする

アプリケーションの仮想環境を有効化します。次に、パッケージをインストールします。このパッケージには Python 3.10 以降が必要です。
3

キーとデプロイの識別情報を設定する

クライアントは、各イベントにサービス、環境、リリースを追加します。
4

ハンドラーを追加する

このファイルを worker.py として保存します。クライアントを作成する前に logging.basicConfig() を呼び出します。クライアントはルートロガーにハンドラーを追加します。ルートロガーにハンドラーがすでにあると、basicConfig() は何もしません。
HttpTransport() は、最初のイベントから1秒後、またはイベントが50件たまった時点で、バックグラウンドでイベントを送信します。client.shutdown() は残りのイベントを送信し、クライアントを閉じます。
5

プログラムを実行する

コンソールの出力は変わりません。LogBrew は、レコードごとに1件のログイベントを受け取ります。次は最初のイベントです。共通のランタイムコンテキストは省いています。
extra={...} のプリミティブ値はメタデータになります。2件目のイベントでは、exceptionName が KeyError、exceptionMessage が 'seats' です。トレースバックの全文を送信するには、include_exception_text=True を指定してハンドラーを作成します。
6

ログを読み取って確認する

一致する結果が返れば、LogBrew がログを保存したことがわかります。CI やコーディングエージェントから読み取るには、プロジェクトの読み取りキーを使います。セットアップの確認を参照してください。

LogBrew に送るレコードを選ぶ

送るレコードを減らすには、ハンドラーに専用のレベルを設定します。コンソールには引き続き INFO 以上が出力されます。
Python のレベルは LogBrew のレベルに変換されます。元のレベル名と数値はメタデータに残ります。

Python のクラッシュを課題として報告する

install_process_error_capture(client) は、スクリプト、ワーカー、起動コード、スレッドで捕捉されなかった例外を報告します。各クラッシュは1件の課題になり、例外の型、メッセージ、スタックフレーム、例外チェーンの原因を含みます。Python は、これまでどおりトレースバックを出力して終了します。 このファイルを startup.py として保存し、実行します。
LogBrew は、タイトルが FileNotFoundError、レベルが critical、メカニズムが python.excepthook の課題を受け取ります。そのフレームには、ファイル名、行、関数が含まれます。フルパスは含まれません。スレッド内のクラッシュのレベルは error です。Python が終了する前に、SDK は配信を最大2秒待ちます。
課題には例外のメッセージが含まれます。例外のメッセージやログのメッセージに、認証情報や個人データを入れないでください。ログの秘匿を参照してください。

トラブルシューティング

Web アプリケーションについては Flask のログを参照してください。ログ形式を選ぶには構造化ログを参照してください。ほかのランタイムについては SDK 連携を参照してください。