Azure SDK documentation update: Include instrumentation scope は、Azure Monitor OpenTelemetry Exporter for Python のログテレメトリに、Python のロガー名を logger_name として追加する変更です。対応が必要なのは、Python アプリから Azure SDK/OpenTelemetry 経由で Application Insights や Azure Monitor にログ、例外、イベントを送っているチームです。
結論から言うと、アプリの業務ロジックを急いで書き換える変更ではありません。ただし、ログ分析、KQL クエリ、Application Insights のダッシュボード、アラート運用には影響します。特に「どの Python モジュールがこのログを出したのか」を Application Insights 上で追跡したい場合は、今回の logger_name 追加により調査しやすくなります。対象の PR は Azure SDK for Python の #46096 で、Message、Exception、Event テレメトリにロガー名を追加する内容として main ブランチにマージされています。(GitHub)
Azure SDK documentation update: Include instrumentation scopeで何が変わったのか
今回の変更は、Azure SDK for Python リポジトリ内の azure-monitor-opentelemetry-exporter に関するものです。具体的には、OpenTelemetry の InstrumentationScope.name に入っている Python のロガー名を、Azure Monitor に送信するログテレメトリの customDimensions に logger_name として追加します。
| 観点 | 変更前 | 変更後 |
|---|---|---|
| 対象 | Azure Monitor OpenTelemetry Exporter for Python のログ出力 | 同左 |
| 追加される情報 | ロガー名が Application Insights 側で失われる場合があった | customDimensions["logger_name"] として確認しやすくなる |
| 対象テレメトリ | Message、Exception、Event | Message、Exception、Event |
| 主な用途 | ログ本文や独自プロパティから発生元を推測 | KQL でモジュール名・ロガー名単位に絞り込みや集計が可能 |
| 注意点 | 既存クエリはロガー名を前提にできない | 過去データには logger_name が存在しないため、クエリで空値を考慮する |
背景にある Issue #45914 では、Python の logging.getLogger("myapp.services") のようなロガー名が OpenTelemetry 側では InstrumentationScope.name に保持される一方、Azure Monitor Log Exporter がそれを Application Insights の customDimensions にマッピングしていないため、KQL で発生元モジュール別にログを絞り込めない問題が報告されていました。(GitHub)
Instrumentation Scopeとは何か
Instrumentation Scope は、OpenTelemetry で「どの計装ライブラリ、どのロガー、どのモジュールがテレメトリを出したのか」を表すための情報です。Python の標準 logging を使う場合、たとえば次のように名前付きロガーを使います。
import logging
logger = logging.getLogger("myapp.services.order")
logger.info("注文処理を開始しました")
この "myapp.services.order" のようなロガー名が、OpenTelemetry のログ処理を通ると InstrumentationScope.name として扱われます。今回の変更では、その値が Azure Monitor 側のログプロパティに logger_name として反映されます。
実務上は、次のような調査がしやすくなります。
| やりたいこと | 変更後にやりやすくなること |
|---|---|
| エラーが多いモジュールを特定する | logger_name ごとに例外件数を集計する |
| 特定サービス層のログだけ確認する | logger_name startswith "myapp.services" で絞り込む |
| ノイズの多いログ発生元を探す | ロガー名別にログ件数を並べる |
| 障害時の調査時間を短縮する | メッセージ本文ではなく発生元で検索できる |
対応すべき人と、急がなくてよい人
この更新は Azure SDK 全体の大規模な仕様変更ではなく、主に Python の Azure Monitor OpenTelemetry Exporter を使ったログ出力に関する改善です。対応優先度は、現在の監視構成によって変わります。
| 対象者 | 対応優先度 | 理由 |
|---|---|---|
Python アプリで AzureMonitorLogExporter を使っている | 高 | ログ、例外、イベントの分析項目が増えるため、KQL やダッシュボード確認が必要 |
| Azure Monitor OpenTelemetry Distro 経由で Python ログを送っている | 中〜高 | Distro が内部で exporter を利用するため、依存パッケージ更新時に影響を受ける可能性がある |
| Application Insights の traces/exceptions/customEvents を日常的に見る運用担当者 | 高 | logger_name を使った調査・アラート改善ができる |
| メトリックや分散トレースだけを送っている | 低 | 今回の主対象はログ系テレメトリ |
| .NET、Java、JavaScript のみを使っている | 低 | この PR は Azure SDK for Python 側の変更 |
なお、Microsoft Learn の説明では、Azure Monitor OpenTelemetry Exporter は分散トレーシング、ログ、メトリックを含む高度な構成向けで、より簡単な設定には Azure Monitor OpenTelemetry Distro が推奨されています。現在どちらを使っているか分からない場合は、requirements.txt、pyproject.toml、コンテナイメージの依存関係を確認してください。(Microsoft Learn)
確認すべき変更点
customDimensions["logger_name"] が追加される
コード上では、ログレコードの instrumentation_scope.name が存在する場合、properties.setdefault("logger_name", str(instrumentation_scope.name)) によって logger_name が追加されます。(GitHub)
ここで重要なのは setdefault です。すでにアプリ側で logger_name というカスタムプロパティを明示的に設定している場合、その値が優先され、Instrumentation Scope 由来のロガー名では上書きされません。
つまり、既存運用で logger_name を独自の意味で使っている場合は注意が必要です。たとえば、これまで logger_name に「画面名」や「業務機能名」を入れていた場合、今後は OpenTelemetry 由来のロガー名と意味が衝突する可能性があります。
Message、Exception、Eventが対象
PR の説明では、Message、Exception、Events telemetry にロガー名を追加するとされています。(GitHub)
Application Insights で確認する場合は、主に次のテーブルを見ます。
| テレメトリ種別 | Application Insightsでよく見るテーブル | 確認内容 |
|---|---|---|
| Message | traces | 通常のログメッセージ |
| Exception | exceptions | 例外ログ |
| Event | customEvents | カスタムイベント |
ただし、環境や送信方法によって実際の見え方が異なる場合があります。まずはステージング環境でテストログを送信し、customDimensions に logger_name が入るか確認するのが安全です。
パッケージリリース状況は別途確認する
今回の変更は main ブランチの CHANGELOG では 1.0.0b52 (Unreleased) の Features Added に「Message、Exception、Event telemetry の custom dimensions に logger name を追加」として記載されています。一方、PyPI 上の azure-monitor-opentelemetry-exporter は、確認時点では 1.0.0b51 が最新として表示されていました。(GitHub)
つまり、PR がマージされたことと、手元の環境で pip install できるリリース版に含まれていることは同じではありません。対応時は、次の順番で確認してください。
| 確認項目 | コマンド・確認場所 |
|---|---|
| 現在の exporter バージョン | python -m pip show azure-monitor-opentelemetry-exporter |
| Distro を使っているか | python -m pip show azure-monitor-opentelemetry |
| ロックファイルの固定状況 | requirements.txt、poetry.lock、uv.lock、pip-tools の出力 |
| リリースノート | GitHub の CHANGELOG、PyPI の Release history |
| Python バージョン | python --version |
特に注意したいのは、同じ 1.0.0b52 の CHANGELOG に Python 3.9 サポート終了も含まれている点です。logger_name 追加だけを目的に更新する場合でも、実際のリリース単位では Python 3.10 以上が前提になる可能性があります。(GitHub)
KQLでlogger_nameを確認する方法
更新後にまず確認したいのは、customDimensions に logger_name が入っているかです。通常ログであれば、次のように traces テーブルを確認します。
traces
| where timestamp > ago(1h)
| extend logger_name = tostring(customDimensions["logger_name"])
| where isnotempty(logger_name)
| summarize count() by logger_name
| order by count_ desc
例外ログで確認する場合は、次のように exceptions テーブルを使います。
exceptions
| where timestamp > ago(1h)
| extend logger_name = tostring(customDimensions["logger_name"])
| where isnotempty(logger_name)
| project timestamp, logger_name, type, outerMessage
| order by timestamp desc
特定のアプリケーション層だけを見たい場合は、ロガー名の命名規則を使って絞り込めます。
traces
| where timestamp > ago(24h)
| extend logger_name = tostring(customDimensions["logger_name"])
| where logger_name startswith "myapp.services"
| project timestamp, logger_name, severityLevel, message
| order by timestamp desc
過去データと混在する期間を調査する場合は、logger_name が空の行も残るため、次のように coalesce で扱うと集計が崩れにくくなります。
traces
| where timestamp > ago(7d)
| extend logger_name = coalesce(tostring(customDimensions["logger_name"]), "(no logger_name)")
| summarize count() by logger_name
| order by count_ desc
設定確認で見るべきポイント
名前付きロガーを使っているか
Azure Monitor Log Exporter を使う場合は、root logger に無条件でハンドラーを付けるのではなく、アプリケーション用の名前付きロガーを使うのが安全です。Microsoft Learn でも、AzureMonitorLogExporter は azure-core に依存しており、root logger にハンドラーを付けると SDK 内部ログまで拾ってログの再帰や不要な増加につながる可能性があるため、名前付きロガーやフィルターの利用が推奨されています。(Microsoft Learn)
避けたい例は、アプリ全体の root logger にそのまま OpenTelemetry の LoggingHandler を付ける構成です。
logging.getLogger().addHandler(handler)
推奨されるのは、アプリの責務単位で名前付きロガーを使う構成です。
logger = logging.getLogger("myapp.services.order")
logger.addHandler(handler)
logger.setLevel(logging.INFO)
このようにしておくと、logger_name にも意味のある値が入り、KQL での調査がしやすくなります。
ロガー名を動的に作っていないか
logger_name は分析に役立つ一方、値が細かく増えすぎると調査しづらくなります。たとえば次のようなロガー名は避けるべきです。
logging.getLogger(f"myapp.user.{user_id}")
logging.getLogger(f"myapp.tenant.{tenant_id}")
ユーザー ID、テナント ID、リクエスト ID のように高頻度で変わる値は、ロガー名ではなく別のカスタムプロパティとして扱うべきです。ロガー名は、基本的にモジュール名や機能名に固定します。
良い例は次のような命名です。
logging.getLogger("myapp.api.orders")
logging.getLogger("myapp.worker.billing")
logging.getLogger("myapp.integrations.graph")
既存のlogger_nameプロパティと衝突しないか
アプリ側で extra={"logger_name": "..."} のように独自プロパティを設定している場合、今回追加される OpenTelemetry 由来の値よりも既存プロパティが優先される可能性があります。コード上では setdefault が使われているため、すでに logger_name が存在すれば上書きされません。(GitHub)
既存運用で logger_name を使っている場合は、意味を統一するか、別名に変更するかを決めてください。おすすめは、ロガー名は logger_name に統一し、業務機能名は feature、処理名は operation_name、テナントは tenant_id のように分けることです。
移行・検証の進め方
本番環境でいきなり依存パッケージを上げるのではなく、まずステージング環境で次の順番に確認してください。
| 手順 | 作業 | 判断基準 |
| -: | ——————————— | ——————————————- |
| 1 | 現在のパッケージバージョンを確認する | exporter または distro の利用有無が分かる |
| 2 | リリースノートを確認する | logger_name 追加が含まれるバージョンか分かる |
| 3 | Python バージョンを確認する | Python 3.9 利用中なら更新計画を分ける |
| 4 | 名前付きロガーでテストログを出す | logger_name に期待した値が入る |
| 5 | Message、Exception、Event をそれぞれ確認する | traces、exceptions、customEvents で確認できる |
| 6 | 既存 KQL を見直す | 空値、過去データ、既存 logger_name との衝突を考慮できている |
| 7 | ダッシュボードやアラートに反映する | モジュール別の障害検知や調査に使える |
検証用の最小コードは、次のような形です。実際には接続文字列や依存バージョンを自社環境に合わせてください。
import os
import logging
from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.instrumentation.logging.handler import LoggingHandler
from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter
logger_provider = LoggerProvider()
set_logger_provider(logger_provider)
exporter = AzureMonitorLogExporter(
connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
handler = LoggingHandler(logger_provider=logger_provider)
logger = logging.getLogger("myapp.services.order")
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info("注文処理のテストログです")
try:
1 / 0
except ZeroDivisionError:
logger.exception("例外テレメトリのテストです")
logger_provider.force_flush()
このログを送信したあと、Application Insights で customDimensions["logger_name"] が "myapp.services.order" になっていれば、今回の変更が反映された exporter を使えていると判断できます。
よくある失敗と対策
| 失敗しやすいポイント | 起きること | 対策 |
|---|---|---|
| PR マージだけを見て本番更新する | PyPI やロックファイルにはまだ入っていない場合がある | 実際のインストールバージョンを確認する |
| Python 3.9 環境でまとめて更新する | 同時に含まれる別変更で動かない可能性がある | Python 3.10 以上への移行計画を先に確認する |
| root logger にハンドラーを付ける | Azure SDK 内部ログまで拾い、ログ量が増える | 名前付きロガーまたはフィルターを使う |
logger_name を業務項目として既に使っている | OpenTelemetry 由来の意味と衝突する | プロパティ名を整理する |
過去データにも logger_name がある前提で KQL を書く | 集計結果に抜けや空値が出る | coalesce や isnotempty を使う |
| 動的なロガー名を使う | ロガー名が大量に増えて分析しづらくなる | モジュール名・機能名に固定する |
今回の更新をどう活用すべきか
この変更の価値は、単にプロパティが一つ増えることではありません。ログ分析の単位を「メッセージ本文」から「発生元モジュール」に引き上げられる点にあります。
たとえば障害対応では、次のような流れが取りやすくなります。
exceptions
| where timestamp > ago(6h)
| extend logger_name = tostring(customDimensions["logger_name"])
| summarize errors = count() by logger_name
| order by errors desc
この結果から、myapp.integrations.payment の例外が急増していると分かれば、決済連携まわりのリリース、外部 API、認証情報、リトライ設定に絞って調査できます。これまでは例外メッセージやスタックトレースから推測していた調査を、より短い時間で始められます。
また、運用ダッシュボードでは次のような観点を追加できます。
| ダッシュボード項目 | 目的 |
|---|---|
| ロガー名別のログ件数 | ノイズの多いモジュールを見つける |
| ロガー名別の例外件数 | 障害が集中している機能を見つける |
| ロガー名別の重大度分布 | warning や error が多い領域を把握する |
| 特定ロガー名の時系列推移 | リリース後の異常増加を検知する |
まず取るべき行動
今回の Azure SDK documentation update: Include instrumentation scope は、Python の Azure Monitor OpenTelemetry Exporter を使っているチームにとって、ログ調査の精度を上げる実用的な変更です。一方で、PR のマージと利用中パッケージへの反映には差があるため、まずは自社環境のバージョン確認から始めてください。
最初にやるべきことは、次の3つです。
azure-monitor-opentelemetry-exporterまたはazure-monitor-opentelemetryの利用有無とバージョンを確認する- ステージング環境で名前付きロガーのテストログを送り、
customDimensions["logger_name"]を KQL で確認する - 既存の KQL、ダッシュボード、アラートで
logger_nameを活用できる箇所を洗い出す
特に、Python 3.9 を使っている環境や、logger_name という独自プロパティをすでに運用している環境では、パッケージ更新前に影響範囲を整理しておくと安全です。ログの発生元を追いやすくするためにも、今後はアプリケーション内のロガー名を「固定されたモジュール名・機能名」として設計することをおすすめします。

コメント