LoginSignup
1
0

FastAPI のテレメトリデータを Azure Application Insights に送る

Last updated at Posted at 2024-02-29

タイトルの通り、FastAPI サーバのテレメトリデータを Azure Application Insights に送りたくて試行錯誤したのでそのメモ。

初期設定

azure-monitor-opentelemetryopentelemetry-instrumentation-fastapi を入れて、下記のように設定すれば動いた。

app.py
from os import getenv

from azure.monitor.opentelemetry import configure_azure_monitor
from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

app = FastAPI()

APPLICATIONINSIGHTS_CONNECTION_STRING = getenv("APPLICATIONINSIGHTS_CONNECTION_STRING")
if APPLICATIONINSIGHTS_CONNECTION_STRING:
    configure_azure_monitor(connection_string=APPLICATIONINSIGHTS_CONNECTION_STRING)
    FastAPIInstrumentor.instrument_app(app)

ただしハマったところとして、Application Insights リソースが配置されているリソースグループ名に日本語が含まれていた場合にデータを受け取ってくれなかった。リソースグループ名に非 ASCII 文字を使うのはやめよう...。

Exception を収集する

デフォルトで Exception は収集してくれているっぽい。

試しにこういうエンドポイントを作ってアクセスしてみると、Application Insights の画面でエラー情報を見ることができた。

@app.get("/")
async def get_root():
    1 / 0  # ERROR

image.png

アクセスしてきたユーザの ID を収集する

デフォルトでリクエストログは収集してくれているが、そのままだと「誰が」アクセスしてきたログなのかわからないので、ユーザ ID を追加で送信できるようにする。

app.py
from os import getenv

from azure.monitor.opentelemetry import configure_azure_monitor
from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor, Span

app = FastAPI()


APPLICATIONINSIGHTS_CONNECTION_STRING = getenv("APPLICATIONINSIGHTS_CONNECTION_STRING")
if APPLICATIONINSIGHTS_CONNECTION_STRING:

    def server_request_hook(span: Span, scope: dict):
        if span and span.is_recording():
            try:
                # Application Insights に送るデータにユーザ ID を追加する
                user_id = ...  # TODO: よしなにユーザ ID を取得する
                span.set_attribute("enduser.id", user_id)
            except KeyError:
                pass

    configure_azure_monitor(connection_string=APPLICATIONINSIGHTS_CONNECTION_STRING)
    FastAPIInstrumentor.instrument_app(app, server_request_hook=server_request_hook)

FastAPIInstrumentor の server_request_hook でカスタム属性を設定することができて1、Azure Application Insights の場合は enduser.id 属性を送信すると requests.user_Id として保存してくれるらしい。2

server_request_hook がいつ実行されるのかは詳しくわかっていないが、引数 scope から得られる情報を見る限りではレスポンスを返したあとっぽい。

  1. https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/fastapi/fastapi.html#request-response-hooks

  2. https://learn.microsoft.com/ja-jp/azure/azure-monitor/app/opentelemetry-add-modify?tabs=python#set-the-user-id-or-authenticated-user-id

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0