はじめに
今回Azure Functions・ADF・PostgreSQL を組み合わせたバックエンドで、ログがリソースごとにバラバラのため、障害時に「どこで何が起きたか」を追うのが地味に大変。
そのためLog Analyticsで集約することにしました。
本記事では 相関 ID × KQL で、リソース横断ログを 1 画面で追跡する方法 を紹介します。
💡 相関 ID(Correlation ID) = 処理の起点で発行する一意の識別子。各リソースのログに同じ ID を埋め込むことで、散らばったログを串刺し検索できるようにする仕組みです。
前提:ログ収集はすべてリソース固有テーブル
今回の環境では、すべてのリソースで「リソース固有(Resource-Specific)」モード を選択しています。
| リソース | テーブル | メリット |
|---|---|---|
| Azure Functions |
AppTraces / AppRequests
|
Application Insights 経由で収集。リクエスト情報とトレースログを分けて追える |
| Azure Data Factory |
ADFPipelineRun / ADFActivityRun
|
CorrelationId がネイティブカラム。join 不要で串刺し可能 |
| PostgreSQL Flexible Server | PostgreSQLLogs |
リソース固有テーブルで収集。専用スキーマでカラムが明確 |
💡
AppTracesとAppRequestsの使い分け:
AppTraces…ILogger等で出力したトレースログ(処理の経過・デバッグ情報)AppRequests… HTTP リクエスト単位のログ(URL・ステータスコード・処理時間)障害調査では
AppRequestsで異常なリクエストを特定 →AppTracesで詳細を追う という流れが基本です。
処理フロー
【API】
エンドユーザ → Functions(API処理) → PostgreSQL(DB処理) → Functions(レスポンス整形) → エンドユーザ
【バッチ】 ADF(定時実行) → CSV読み取り(Blob) → PostgreSQL(DB処理) → メール通知(正常完了)
どちらも 処理の起点で相関 ID を発行し、各リソースのログに埋め込む のがポイントです。
KQL の設計方針
① 時系列 → ② 相関 ID の順でソート
order by TimeGenerated desc, correlationId
「いつ起きたか → どの処理の一連か」の順で並べると、ログの流れが直感的に追えます。
📝 公式ベストプラクティスでも
where TimeGenerated > ago(1h)をクエリ先頭に置くことが推奨されています。これだけで I/O が劇的に減ります。
まず全部出す → UI でフィルタ
KQL 側は 素材をドンと出す 役割に徹します。
- エラーの 前後の正常ログ も見たい(直前に何が起きたかが重要)
- Log Analytics の UI でカラムヘッダーをクリックするだけで
Level == "Error"等のフィルタが可能 - 最初からエラーだけに絞ると 見落としが発生する
KQLはAI(Copilot)に書かせる
KQL は Copilot(AI)に書かせるのが早い です。Log Analytics のクエリエディタにも Copilot が統合されているので、自然言語で指示すればたたき台を生成してくれます。
ここでは「こういうクエリが必要になる」というパターンだけ押さえておきます。
■ Functions ログ(AppTraces)
AppTraces
| where TimeGenerated > ago(24h)
| extend correlationId = tostring(customDimensions.correlationId)
| project TimeGenerated, correlationId, SeverityLevel, Message, OperationName
| order by TimeGenerated desc, correlationId
| ポイント | 説明 |
|---|---|
FunctionAppLogs |
Level・ExceptionDetails 等が専用カラム。customDimensions 展開不要 |
parse |
Message から [correlationId=xxx] を抽出。固定パターンなら extract より読みやすい |
■ ADF ログ(パイプライン + アクティビティ統合)
ADFPipelineRun
| where TimeGenerated > ago(24h)
| union (ADFActivityRun | where TimeGenerated > ago(24h))
| order by TimeGenerated desc, CorrelationId
🔧
CorrelationIdは ADF がパイプライン実行ごとに自動生成 します。同一パイプラインの全アクティビティに同じ値が入るので、joinなしで串刺し可能です。
■ PostgreSQL ログ
PostgreSQLLogs
| where TimeGenerated > ago(24h)
| order by TimeGenerated desc
■ 全体横断(3 リソース統合)
上記 3 つを union で結合すれば、1 画面で全リソースを横断できます。カラムの整形や case 文での Level 変換などは、Copilot に「3 テーブルを統合して correlationId で並べて」と指示すれば一発です。
💡 ただし、どのテーブルに何が入っているか(AppTraces / ADFPipelineRun / PostgreSQLLogs)と、並び順のポリシー(①時系列 → ②相関ID)だけは押さえておくと、AI への指示が的確になります。
相関 ID 設計 Tips
| 区間 | 伝播方法 |
|---|---|
| クライアント → Functions | HTTP ヘッダー x-correlation-id
|
| Functions → PostgreSQL | SQL コメント |
| ADF 内 | 組み込み CorrelationId が自動伝播 |
おわりに
リソース固有テーブル + 相関 ID + KQL のソート設計。この 3 つを押さえておけば、「あの処理どこでコケた?」が 1 画面で追えるようになります。KQL は最初に手間をかけて保存しておけば、運用保守担当者がワンクリックで呼び出せる資産 になるので、ぜひお試しを。

