Skip to main content
logbrew-flask 0.1.6 以降を使います。このパッケージは、リクエストのスパンと未処理の例外を取得します。任意のロギングハンドラーを使うと、Python のログをリクエストのトレースに結び付けられます。リクエストの所要時間のメトリクスも任意です。 このパッケージには、Python 3.10 以降と Flask 3.1 以降が必要です。
アプリケーションでは、プロジェクト単位のサーバー用取り込みキーを使ってください。CLI を認可するアカウントの認証情報は使わないでください。
<project_id>、<trace_id>、<issue_id> は、LogBrew の ID に置き換えます。テストのリクエストには開発用のプロジェクトを使います。シェルの例は Bash です。

最初のリクエストを送信する

1

プロジェクトのキーを作成または選択する

CLI でサインインします。次に、新しいプロジェクトか既存のプロジェクトを使います。両方の例を実行しないでください。新しいプロジェクトの場合は、取り込みキーを所有者だけが読める新しいファイルに保存します。
既存のプロジェクトの場合は、logbrew projects --json でプロジェクトの ID を確認します。次に、別のサーバー用キーを作成します。
CLI は、取り込みキーを所有者だけのアクセス権で保存します。キーやファイルのパスは表示しません。本番環境では、このローカルファイルではなく、デプロイ先のプラットフォームのシークレット管理機能を使ってください。作成リクエストの結果がはっきりしない場合は、同じコマンドをそのままもう一度実行します。
2

リリース済みの連携をインストールする

アプリケーションの仮想環境を作成または有効化し、フレームワークのパッケージをインストールします。互換性のあるコア SDK も依存関係としてインストールされます。
3

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

プロジェクトのキーを、表示せずにローカルで読み込みます。すべてのシグナルが役立つデプロイのコンテキストを持つように、変わらないサービス、環境、リリースを設定します。
init_logbrew() は、まず明示的な引数を確認し、次に Flask アプリケーションの設定、最後にこれらの環境変数を確認します。サービス名が設定されていない場合は、Flask のインポート名を使います。
4

Flask を1回だけ初期化する

新しいアプリの場合は、例を app.py として保存します。初期化処理は、Flask アプリケーションを作成した後に追加します。ロギングハンドラーは任意です。これを使うと、アプリケーションのログがアクティブなリクエストのトレースとスパンを共有します。
init_logbrew(app) を何度呼び出しても、同じ Flask 拡張が返ります。リクエストや例外のフックが重複してインストールされることはありません。初期化処理はロギングハンドラーを追加しません。ハンドラーは、アプリが所有するロガーに1回だけ追加します。
5

リクエストを1件実行する

アプリを起動し、別のターミナルからルートを呼び出します。アプリケーションのモジュール名が違う場合は、コマンドの app を置き換えます。
送信はバックグラウンドのワーカーで行われ、レスポンスを待たせません。
6

保存された証拠を確認する

正確なプロジェクトとデプロイの範囲で読み取ります。ヘルスチェックのリクエストのトレースと、例のロギングハンドラーが送った関連するログを探します。
返されたトレース ID を、範囲を限った調査コマンドにコピーします。
読み取りで一致すれば、LogBrew がシグナルを保存したことを確認できます。ローカルの 200 レスポンスが証明するのは、Flask がリクエストを処理したことだけです。

必要なシグナルを選ぶ

初期化処理では、最初からリクエストのトレースと未処理の例外の取得が有効です。リクエストのメトリクスと Python のログの転送は、別に選びます。 デフォルト値から始めます。レイテンシーを見る必要があるときに、リクエストのメトリクスを追加します。ロギングハンドラーは、調査に役立つロガーにだけ追加します。 デフォルトでは、初期化処理が HTTP トランスポートを持ちます。各イベントはキューに入り、キューにイベントが1件入るとすぐに、バックグラウンドのワーカーが送信を始めます。送信はレスポンスを待たせません。トランスポートが失敗しても、Flask のレスポンスは壊れません。 flush_on_response=True にすると、キュー内のイベントをレスポンスの経路で送信します。このオプションと合わせて raise_flush_errors=True を使うと、送信エラーが例外として発生します。どちらも、管理された診断にだけ使ってください。

ログの内容を管理する

必要なメッセージを出すロガーに、LogBrewLoggingHandler を1つ追加します。このハンドラーは、アプリのコンソールやファイルのハンドラーを置き換えません。Flask や Python の logging モジュールにパッチを当てることもありません。同じハンドラーを2回追加すると、ログが重複します。アプリがルートロガーも使っている場合は、2つ目のハンドラーを追加する前に伝搬を確認してください。 リクエスト内のログは、アクティブなトレースとスパンを引き継ぎます。リクエスト外のログには、リクエストのトレースがありません。 ハンドラーは、整形されたメッセージ、ロガー名、LogBrew のレベルを送信します。また、ソースのファイル名、モジュール、関数、行、スレッド名、プロセス名も送信しますが、ソースの完全なパスは送信しません。extra={...} のプリミティブな値はメタデータになります。ユーザー向けのリクエストからログを出す前に、それらの値を確認してください。 Python の DEBUG レコードは、LogBrew の info になります。WARNING は warning に、CRITICAL は critical になります。元の Python のレベル名と数値はメタデータに残ります。送信するレコードを減らすには、LogBrewLoggingHandler(logbrew.client, level=logging.WARNING) のように、ハンドラーに独自のレベルを設定します。 コンソールと LogBrew が同じレコードを受け取ることもできます。たとえば、Flask アプリを作成する前にコンソールを設定します。
コンソールには整形されたテキストが出力されます。LogBrew は、メッセージ、レベル、ロガー、メタデータを別々のフィールドとして保持します。 exc_info を持つログレコードには、例外の型とメッセージが含まれます。例外の全文が送信されるのは、ハンドラーに include_exception_text=True を設定した場合だけです。これは自動の例外取得とは別のもので、自動の例外取得は例外のメッセージを一切送信しません。ログや例外のメッセージに、認証情報、個人データ、リクエストのボディを入れないでください。

連携が取得するもの

スパン名には、HTTP メソッドと一致したルートテンプレートを使います。たとえば、/orders/100 と /orders/200 は、どちらも GET /orders/<int:order_id> になります。どのルートにも一致しないリクエストには、固定のラベル <unmatched> を使います。traceparent がないか無効な場合は、新しいトレースを開始します。 スパンのメタデータには、メソッド、ルートテンプレート、エンドポイント、ステータスコード、所要時間が含まれます。具体的なパスやクエリ文字列は含まれません。 0.1.6 以降では、リクエストのスパンが Flask のディスパッチ全体を対象にします。before-request フック、エラーハンドラー、teardown は、リクエストのトレースを共有します。ストリーミングのレスポンスでは、ボディが終わるか閉じられたときにスパンが終了します。

例外の取得をテストする

4xx や 5xx のステータスは、リクエストのスパンに表示されます。ステータスだけでは、例外が発生したことの証明にはなりません。障害を診断する前に、トレースと課題の両方を読んでください。LogBrew は、Flask のエラーハンドラーを置き換えたり、レスポンスのステータスを変えたりしません。 開発用のプロジェクトで、一時的なルートを追加します。1回だけ呼び出します。デプロイする前に削除してください。
リクエストはステータス 500 を返します。新しい課題とリクエストのメトリクスを探します。
課題のサービス、環境、リリース、例外の型、リクエストのトレースを確認します。課題に local capture check というテキストが含まれていてはいけません。

外部への処理をリクエストに結び付ける

Python SDK には、requests、urllib、httpx、aiohttp、データベース、キャッシュ、キューの処理のための、アプリ側で使うヘルパーがあります。各ヘルパーは、アクティブなリクエストのトレースの子スパンを作成します。SDK は、これらのライブラリにグローバルなパッチを当てません。例は logbrew-flask パッケージにあります。 各ヘルパーには、変わらない処理名と、ルートまたはステートメントのテンプレートを指定します。それらの名前に、レコード ID、顧客の値、SQL のバインド値、メッセージのペイロードを入れないでください。子スパンは、リクエストにとって重要な依存先にだけ追加します。小さな呼び出しのたびにスパンを作ると、トレースが読みにくくなります。外部への HTTP ヘルパーは、W3C traceparent ヘッダーを1つ追加します。完全な URL、クエリ文字列、ボディ、Cookie、任意のヘッダーは取得しません。データベース、キャッシュ、キューのヘルパーは、バインド値、結果、キャッシュの値、キューのペイロードを取得しません。

プライバシーとプロセスのライフサイクル

Flask の自動取得では、具体的なリクエストのパス、クエリ文字列、リクエストとレスポンスのボディ、Cookie、任意のヘッダー、traceparent の生の値、baggage、tracestate を除外します。 自動の例外取得は、str(error) を読み取ることも送信することもありません。固定の要約 Unhandled exception を使い、例外チェーンの各メッセージを秘匿済みとしてマークします。フレームには、ファイルのベース名と、範囲を限ったコードの識別情報が入ります。トレースバックの生のテキスト、ソースコード、ローカル変数、絶対パスは入りません。 アプリと LogBrew クライアントは、各ワーカープロセスの中で作成します。Gunicorn のデフォルトの、ワーカーごとにアプリを読み込む方式で動作します。親プロセスで作成したクライアントと一緒に Gunicorn の --preload を使わないでください。uWSGI では、--lazy-apps など、ワーカーごとにアプリを読み込む方式を使います。Python クライアントは、プロセスのフォーク後の再利用を拒否します。 プロセスマネージャーのワーカーごとの終了フックから、logbrew.client.shutdown() を呼び出します。これにより、キューに残ったイベントを送信し、クライアントを閉じます。リクエストのたびに呼び出さないでください。終了後、クライアントはそのワーカーからの新しいイベントを拒否します。 ワーカーがキューの最後のイベントを送信する前に、レスポンスが終わることがあります。デプロイやスケールダウンのときは、正常な終了処理によって、それらのイベントに最後の送信の機会が与えられます。

設定の問題を解決する

アカウントのアクセス権、キー、読み戻しのエラーについては、トラブルシューティングを参照してください。他のランタイムについては、SDK 連携を参照してください。