サーバーレスなイベント処理の監視

この記事では、サーバーレス イベント駆動型アーキテクチャの監視に関するガイダンスを提供します。

監視は、システムの動作と正常性に関する分析情報を提供します。 環境の全体像を構築し、履歴の傾向を取得し、さまざまな要因を関連付け、パフォーマンス、消費、またはエラー率の変化を測定するのに役立ちます。 監視を使用して、サービスの品質に影響を与える可能性のある条件が発生した場合、または特定の環境に特に関心のある条件が発生した場合のアラートを定義できます。

この記事では、Azure Monitor を使用して、Event HubsAzure Functions を使用してビルドされたサーバーレス アプリケーションを監視する方法を示します。 監視に役立つメトリックについて説明し、Application Insights と統合してカスタム メトリックをキャプチャする方法について説明し、コード サンプルを提供します。

前提条件

この記事では、「サーバーレスなイベント処理の参照アーキテクチャ」で説明されているアーキテクチャと同様のアーキテクチャを使用していると見なします。 基本構成:

  • イベントは Azure Event Hubs に到着します。
  • イベントを処理するために Function App がトリガーされます。
  • Azure Monitor は、アーキテクチャに使用できます。

Azure Monitor からのメトリック

まず、アーキテクチャに関する有用な分析情報の作成を開始する前に、必要なメトリックを決定する必要があります。 各リソースは異なるタスクを実行し、さらに異なるメトリックを生成します。

有用な分析情報を取得するには、Azure Event Hubs からの次のメトリックが重要です。

  • 受信要求
  • 送信要求
  • スロットルされた要求
  • 成功した要求
  • 受信メッセージ数
  • 送信メッセージ数
  • キャプチャされたメッセージ数
  • 着信バイト数
  • 発信バイト数
  • キャプチャされたバイト数
  • ユーザー エラー

同様に、有用な分析情報を取得するには、Azure Functions からの次のメトリックが重要です。

  • 関数の実行回数
  • 接続
  • データ:
  • 送信データ
  • HTTP サーバー エラー数
  • Requests
  • アプリケーション キュー内の要求数
  • 応答時間

診断ログを使用した分析情報のキャプチャ

上記のメトリックを一緒に分析すると、メトリックは次の分析情報を作成してキャプチャするために使用できます。

  • Azure Event Hubs によって処理された要求の割合
  • Azure Functions によって処理された要求の割合
  • Azure Event Hubs の合計スループット
  • ユーザー エラー
  • Azure Functions の期間
  • End-to-end の待機時間
  • 各ステージでの待機時間
  • 喪失したメッセージの数
  • 2 回以上処理されたメッセージの数

Azure Event Hubs が必要なメトリックをキャプチャすることを確実にするには、まず診断ログを有効にする必要があります (既定では無効)。 次に、必要なログを選択し、適切な Log Analytics ワークスペースを宛先として構成する必要があります。

重要なログとメトリックのカテゴリは次のとおりです。

  • OperationalLogs
  • AutoScaleLogs
  • KafkaCoordinatorLogs (Apache Kafka ワークロード用)
  • KafkaUserErrorLogs (Apache Kafka ワークロード用)
  • EventHubVNetConnectionEvent
  • AllMetrics

Azure のドキュメントでは、Azure イベント ハブの診断ログを設定する方法について説明します。 次のスクリーンショットは、正しいログとメトリック カテゴリが選択され、Log Analytics ワークスペースが宛先として設定されている診断設定構成パネルの例を示しています。 (外部システムを使用してログを分析している場合は、代わりに [イベント ハブへのストリーミング] オプションを使用できます)。

正しいログとメトリック カテゴリが選択され、Log Analytics ワークスペースが宛先として設定されていることを示す Azure Event Hubs 診断設定構成パネルのスクリーンショット。

注意

ログ診断を利用して分析情報をキャプチャするには、さまざまな名前空間にイベント ハブを作成する必要があります。 これは、Azure での制約が理由です。

特定の Azure Event Hubs 名前空間に設定された Azure Event Hubs は、EntityName というディメンションの Azure Monitor メトリックで表されます。 Azure portal では、特定のイベント ハブのデータは、通常、Azure Monitor のそのインスタンスで表示できます。 ただし、メトリック データがログ診断にルーティングされる場合、現在、EntityName ディメンションをフィルター処理してイベント ハブごとにデータを表示する方法はありません。

回避策として、異なる名前空間にイベント ハブを作成すると、特定のハブのメトリックを見つけられるようになります。

Application Insights の使用

Application Insights を有効にして、メトリックとカスタム テレメトリを Azure Functions からキャプチャします。 これにより、独自の目的に合った分析を定義し、サーバーレス イベント処理シナリオに関する重要な分析情報を取得する別の方法を提供できます。

このスクリーンショットは、Application Insights 内のカスタム メトリックとテレメトリの例の一覧を示しています。

Application Insights 内のカスタム メトリックとテレメトリの例の一覧を示すスクリーンショット。

デフォルトのカスタム メトリック

Application Insights では、Azure Functions のカスタム メトリックは、customMetrics テーブルに格納されます。 これには、さまざまな関数インスタンスのタイムラインにまたがって、次の値が含まれます。

  • AvgDurationMs
  • MaxDurationMs
  • MinDurationMs
  • Successes
  • Failures
  • SuccessRate
  • Count

これらのメトリックを使用して、実行で呼び出される複数の関数インスタンス全体の集計平均を効率的に計算できます。

次のスクリーンショットは、Application Insights で表示された場合のデフォルトのカスタム メトリックの外観を示します。

Application Insights で表示された場合のデフォルトのカスタム メトリックの外観を示すスクリーンショット。

カスタム メッセージ

Azure 関数コード (ILogger を使用) に記録されたカスタム メッセージは、Application Insights の traces テーブルから取得されます。

この traces テーブルには、次の重要なプロパティ (他のプロパティも含む) があります。

  • timestamp
  • cloud_RoleInstance
  • operation_Id
  • operation_Name
  • message

Application Insights インターフェイスのカスタム メッセージの例を次に示します。

Application Insights の 'traces' データ テーブル内のカスタム メッセージの例を示すスクリーンショット。

Azure Event Hubs の受信メッセージまたは EventData[] が、このカスタム ILogger メッセージの一部としてログに記録されている場合は、Application Insights でも使用できるようになります。 これは非常に役立つ場合があります。

サーバーレス イベント処理シナリオでは、イベント ハブから受信した JSON シリアル化されたメッセージ本文をログに記録します。 これにより、生のバイト配列を、x-opt-sequence-numberx-opt-offsetx-opt-enqueued-time などの SystemProperties と共にキャプチャできます。 Azure Event Hubs によって各メッセージが受信された時間を確認するために、x-opt-enqueued-time プロパティが使用されます。

サンプル クエリ:

traces
| where timestamp between(min_t .. max_t)
| where message contains "Body"
| extend m = parse_json(message))
| project timestamp = todatetime(m.SystemProperties.["x-opt-enqueued-time"])

このサンプル クエリでは、次の例の結果のようなメッセージが返されます。この結果は、既定で Application Insights に記録されます。 Trigger Details のプロパティを使用すると、PartitionIdOffsetSequenceNumber ごとに受信したメッセージに関する追加の分析情報を検索してキャプチャできます。

サンプル クエリの結果の例:

"message": Trigger Details: PartitionId: 26, Offset: 17194119200, EnqueueTimeUtc: 2020-11-03T02:14:01.7740000Z, SequenceNumber: 843572, Count: 10,

警告

現在、Azure Java Functions のライブラリには、EventHubTrigger を使用するときに PartitionID および PartitionContext へのアクセスを妨げる問題があります。 詳細については、この GitHub 問題レポートを参照してください。

Application Insights でトランザクション ID を使用したメッセージ フローの追跡

Application Insights では、トランザクションの Operation Id 値に対してトランザクション検索クエリを実行することで、特定のトランザクションに関連するすべてのテレメトリを表示できます。 これは、トランザクションがイベント ストリーム パイプラインを移動するときのメッセージの平均時間のパーセント値をキャプチャする場合に特に役立ちます。

次のスクリーンショットは、Application Insights インターフェイスでのトランザクション検索の例を示しています。 目的の Operation ID がクエリ フィールドに入力され、虫眼鏡アイコンで識別されます (ここでは赤い枠線で囲まれて示されています)。 メイン ウィンドウの下部の Results タブに、一致するイベントが順番に表示されます。 各イベント エントリでは、検証を容易にするために、Operation ID 値が濃い青色で強調表示されます。

Application Insights インターフェイスでのトランザクション検索の例を示すスクリーンショット。

特定の操作 ID に対して生成されたクエリは次のようになります。 Operation ID GUID は 3 行目の where * has 句で指定されています。 この例では、2 つの異なる datetimes 間のクエリをさらに絞り込む方法を示します。

union isfuzzy=true availabilityResults, requests, exceptions, pageViews, traces, customEvents, dependencies
| where timestamp > datetime("2020-10-09T06:58:40.024Z") and timestamp < datetime("2020-11-11T06:58:40.024Z")
| where * has "1c8c9d7073a00e4bbdcc8f2e6570e46"
| order by timestamp desc
| take 100

Application Insights インターフェイスでのクエリとその一致する結果のスクリーンショットを次に示します。

特定の操作 ID に対して生成されたクエリの結果を含む Application Insights インターフェイスの一部を示すスクリーンショット。実際のクエリは上部の領域に表示され、一致する結果はその下に示されます。

Azure Functions からのカスタム メトリックのキャプチャ

.NET 関数

構造化ログは、Application Insights の traces テーブルでカスタム ディメンションをキャプチャするために、.NET Azure 関数内で使用されます。 これらのカスタム ディメンションは、データのクエリに使用できます。

例として、.NET TransformingFunction のログ ステートメントを次に示します。

log.LogInformation("TransformingFunction: Processed sensorDataJson={sensorDataJson}, " +
    "partitionId={partitionId}, offset={offset} at {enqueuedTimeUtc}, " +
    "inputEH_enqueuedTime={inputEH_enqueuedTime}, processedTime={processedTime}, " +
    "transformingLatencyInMs={transformingLatencyInMs}, processingLatencyInMs={processingLatencyInMs}",
    sensorDataJson,
    partitionId,
    offset,
    enqueuedTimeUtc,
    inputEH_enqueuedTime,
    processedTime,
    transformingLatency,
    processingLatency);

Application Insights に作成された結果のログには、次のスクリーンショットに示すように、上記のパラメーターがカスタム ディメンションとして含まれています。

前の C# コード サンプルによって Application Insights で作成されたログを示すスクリーンショット。

これらのログは、次のようにクエリで問い合わせられます。

traces
| where timestamp between(min_t .. max_t)
// Function name should be of the function consuming from the Event Hub of interest
| where operation_Name == "{Function_Name}"
| where message has "{Function_Name}: Processed"
| project timestamp = todatetime(customDimensions.prop__enqueuedTimeUtc)

注意

これらのテストのパフォーマンスに影響を確実に与えないようにするため、次に示すように、host.json ファイルを使用して Application Insights の Azure 関数ログのサンプリング設定を有効にしています。 つまり、ログ記録からキャプチャされた統計はすべて、実際のカウントではなく平均値と見なされます。

host.json の例:

"logging": {
    "applicationInsights": {
        "samplingExcludedTypes": "Request",
        "samplingSettings": {
            "isEnabled": true
        }
    }
}

Java 関数

現時点では、構造化ログは、Application Insights の traces テーブル内にカスタム ディメンションをキャプチャするためには、Java Azure 関数ではサポートされません。

例として、Java TransformingFunction のログ ステートメントを次に示します。

LoggingUtilities.logSuccessInfo(
    context.getLogger(), 
    "TransformingFunction", 
    "SuccessInfo", 
    offset, 
    processedTimeString, 
    dateformatter.format(enqueuedTime), 
    transformingLatency
);

Application Insights に作成された結果のログには、次に示すように、上記のパラメーターがメッセージに含まれています。

前の Java コード サンプルによって作成された、Application Insights に作成されたログを示すスクリーンショット。

これらのログは、次のようにクエリで問い合わせられます。

traces
| where timestamp between(min_t .. max_t)
// Function name should be of the function consuming from the Event Hub of interest
| where operation_Name in ("{Function name}") and message contains "SuccessInfo"
| project timestamp = todatetime(tostring(parse_json(message).enqueuedTime))

注意

これらのテストのパフォーマンスに影響を確実に与えないようにするため、次に示すように、host.json ファイルを使用して Application Insights の Azure 関数ログのサンプリング設定を有効にしています。 つまり、ログ記録からキャプチャされた統計はすべて、実際のカウントではなく平均値と見なされます。

host.json の例:

"logging": {
    "applicationInsights": {
        "samplingExcludedTypes": "Request",
        "samplingSettings": {
            "isEnabled": true
        }
    }
}

共同作成者

この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。

プリンシパル作成者:

パブリックでない LinkedIn プロファイルを表示するには、LinkedIn にサインインします。