分散トレース (プレビュー) を使用して Azure IoT の cloud-to-device メッセージをトレースする

IoT Hub で分散トレース (プレビュー) を使って、Azure サービスを通過する IoT メッセージを監視します。 IoT Hub は、分散トレースをサポートする最初の Azure サービスの 1 つです。 多くの Azure サービスが分散トレースをサポートしているため、ソリューションに関連する Azure サービス全体でモノのインターネット (IoT) メッセージをトレースできます。 この機能の詳細については、分散トレースの概要に関する記事を参照してください。

IoT Hub の分散トレースを有効にすると、次の操作を行えるようになります。

  • トレース コンテキストを使って、IoT Hub を介した各メッセージの流れを監視できます。 トレース コンテキストには、あるコンポーネントからのイベントを別のコンポーネントからのイベントに関連付けることができる関連付け ID が含まれています。 デバイス ツインを使用して、サブセットまたはすべての IoT デバイス メッセージに適用できます。
  • トレース コンテキストを自動的に Azure Monitor ログに記録できます。
  • デバイスから IoT Hub およびルーティング エンドポイントまでのメッセージ フローと待ち時間を測定および把握できます。

重要

Azure IoT ハブの分散トレースは現在プレビュー段階です。 ベータ版、プレビュー版、または一般提供としてまだリリースされていない Azure の機能に適用される法律条項については、「Microsoft Azure プレビューの追加使用条件」を参照してください。

前提条件

  • 次のいずれかのリージョンで作成された Azure IoT ハブ。

    • 北ヨーロッパ
    • 東南アジア
    • 米国西部 2
  • IoT ハブに登録されているデバイス。 お持ちでない場合は、「IoT ハブに新しいデバイスを登録する」の手順に従い、この記事で使うデバイス接続文字列を保存します。

  • この記事は、読者が IoT Hub へのテレメトリ メッセージの送信について理解していることを前提としています。

  • 最新バージョンの Git

パブリック プレビューの制限と考慮事項

このプレビュー機能が実際のシナリオに適しているかどうかを判断するには、次の制限事項を考慮してください。

  • W3C トレース コンテキスト標準の提案は、現在、草案の段階です。

  • クライアント SDK が現在サポートしている開発言語は C のみです (Azure IoT device SDK for C のパブリック プレビュー ブランチにあります)。

  • cloud-to-device のツイン機能は、IoT Hub の基本層では使用できません。 ただし、IoT Hub では、適切に構成されたトレース コンテキスト ヘッダーを認識した場合には、Azure Monitor にログを記録します。

  • 効率的な操作を確実にするために、IoT Hub は、分散トレースの一部として発生する可能性のあるログ記録のレートにスロットルを適用します。

  • 分散トレース機能は、次のリージョンで作成された IoT ハブでのみサポートされています。

    • 北ヨーロッパ
    • 東南アジア
    • 米国西部 2

Azure IoT 分散トレースを理解する

Azure IoT 参照アーキテクチャを含む多くの IoT ソリューションは、通常、マイクロサービス アーキテクチャのバリアントに準拠しています。 IoT ソリューションが複雑になるにつれて、数多くのマイクロサービスを使用することになります。 これらのマイクロサービスは、Azure のマイクロサービスのものである場合とそうでない場合があります。

IoT メッセージのドロップまたはスローダウンが発生している場所を正確に特定することは困難である可能性があります。 たとえば、5 つの異なる Azure サービスと 1,500 台のアクティブ デバイスを使用する IoT ソリューションがあるとします。 device-to-cloud メッセージがデバイスごとに毎秒 10 件 (合計で毎秒 15,000 件) 送信されます。 ただし、Web アプリには毎秒 10,000 件のメッセージしか表示されません。 どのようにして原因を見つけることができるのでしょうか。

サービス間での IoT メッセージのフローを再構築するには、各サービスで、メッセージを一意に識別する関連付け ID を伝達する必要があります。 Azure Monitor が一元管理されたシステムで関連付け ID を収集すると、それらの ID を使用してメッセージのフローを確認できます。 この方法は、分散トレース パターンと呼ばれます。

Microsoft は、分散トレースのより広範な採用をサポートするために、分散トレースの W3C 標準の提案に寄与しています。 IoT Hub の分散トレースのサポートが有効な場合、生成されたメッセージごとに次のフローに従います。

  1. IoT デバイスでメッセージが生成されます。
  2. IoT デバイスでは、このメッセージにトレース コンテキストを割り当てる必要があるかを (クラウドからサポートを受けて) 判断します。
  3. SDK によって、メッセージ作成タイムスタンプを格納する tracestate 値がメッセージ プロパティに追加されます。
  4. IoT デバイスによって、IoT Hub にメッセージが送信されます。
  5. メッセージが IoT Hub ゲートウェイに到着します。
  6. IoT Hub で、メッセージ プロパティ内の tracestate 値が調べられ、それが正しい形式であるかどうか確認されます。 その場合、IoT Hub によって、メッセージのグローバルに一意の trace-id 値、および "ホップ" の場合は span-id 値が生成されます。IoT Hub では、これらの値が DiagnosticIoTHubD2C 操作で IoT Hub 分散トレース ログに記録されます。
  7. メッセージの処理が終了すると、IoT Hub によって別の span-id 値が生成され、DiagnosticIoTHubIngress の操作で既存の trace-id 値とともにそれが記録されます。
  8. メッセージに対してルーティングが有効になっている場合、IoT Hub はそれをカスタム エンドポイントに書き込みます。 IoT Hub では、同じ trace-id 値を持つ別の span-id 値を DiagnosticIoTHubEgress カテゴリに記録します。

IoT ハブで分散トレースを構成する

このセクションでは、分散トレース属性 (関連付け ID とタイムスタンプ) を記録するように IoT ハブを構成します。

  1. Azure portal で、IoT ハブに移動します。

  2. IoT ハブの左側のウィンドウで、下にスクロールして [監視] セクションを表示し、[診断設定] を選択します。

  3. [診断設定の追加] を選択します。

  4. [診断設定の名前] ボックスに、新しい診断設定の名前を入力します。 たとえば、「DistributedTracingSettings」と入力します。

    診断設定の名前を追加する場所を示すスクリーンショット。

  5. ログ情報の送信先を決定するために、[宛先の詳細] の下にある次のオプションから 1 つ以上を選択します。

    • [ストレージ アカウントへのアーカイブ] :ログ情報を格納するようにストレージ アカウントを構成します。
    • [イベント ハブへのストリーム] :ログ情報を格納するようにイベント ハブを構成します。
    • [Log Analytics への送信]: ログ情報を格納するようにログ分析ワークスペースを構成します。
  6. [ログ] セクションで、ログに記録する操作を選択します。

    [分散トレース] を含め、ログを保持する日数に対して [リテンション] 期間を構成します。 ログのリテンション期間は、ストレージのコストに影響します。

    IoT Hub 診断設定の分散トレース操作の場所を示すスクリーンショット。

  7. [保存] を選択します。

  8. (省略可能) 異なる場所へのメッセージ フローを確認するために、2 つ以上の異なるエンドポイントへのルーティング規則を設定します。

ログ記録を有効にすると、次の状況のいずれかで有効なトレース プロパティを含むメッセージが検出されたときに、IoT Hub によってログが記録されます。

  • メッセージが IoT ハブのゲートウェイに到着する。
  • IoT ハブがメッセージを処理する。
  • メッセージがカスタム エンドポイントにルーティングされる。 ルーティングを有効にする必要があります。

これらのログとそのスキーマの詳細については、IoT Hub の監視IoT Hub リソース ログの分散トレースに関する記事を参照してください。

サンプリング オプションを更新する

クラウドからトレースするメッセージの割合を変更するには、デバイス ツインを更新する必要があります。 更新するには、Azure portal または IoT Hub サービス SDK の JSON エディターを使用します。 次のサブセクションで例を示します。

1 つのデバイスを更新する

Azure portal または Visual Studio Code 用 Azure IoT Hub 拡張機能 (VS Code) を使って、1 台のデバイスのサンプリング レートを更新できます。

  1. Azure portal で IoT ハブに移動し、メニューの [デバイス管理] セクションから [デバイス] を選びます。

  2. デバイスを選択します。

  3. [分散トレース (プレビュー)] で、歯車アイコンを選びます。 開いたパネルで、次の操作を行います。

    1. [有効化] オプションをオンにします。
    2. [サンプリング レート] で、0 から 100 の割合を選択します。
    3. [保存] を選択します。

    Azure portal で分散トレースを有効にする方法を示すスクリーンショット。

  4. 数秒待ってから [最新の情報に更新] を選択します。 デバイスが変更を正常に認識すると、チェック マークが付いた同期アイコンが表示されます。

複数のデバイスを一括更新する

複数のデバイスの分散トレース サンプリング構成を更新するには、自動デバイス構成を使用します。 次のツイン スキーマに従います。

{
    "properties": {
        "desired": {
            "azureiot*com^dtracing^1": {
                "sampling_mode": 1,
                "sampling_rate": 100
            }
        }
    }
}
要素名 必須 タイプ 説明
sampling_mode はい Integer サンプリングのオンとオフを切り替えるために、現在 2 つのモード値がサポートされています。 1 がオンで、2 がオフです。
sampling_rate はい Integer この値は、パーセンテージです。 0 から 100 までの値 (両端を含む) のみ許可されます。

トレースのクエリと視覚化

IoT ハブによってログされたすべてのトレースを表示するには、診断設定で選んだログ ストアに対してクエリを実行します。 このセクションでは、Log Analytics を使用してクエリを実行する方法について説明します。

リソース ログを使って Log Analytics を設定した場合、DistributedTracing カテゴリでログを探すことでクエリを実行します。 たとえば、次のクエリでは、記録されたすべてのトレースが表示されます。

// All distributed traces 
AzureDiagnostics 
| where Category == "DistributedTracing" 
| project TimeGenerated, Category, OperationName, Level, CorrelationId, DurationMs, properties_s 
| order by TimeGenerated asc  

Log Analytics のログの例をいくつか次に示します。

生成時刻 操作の名前 カテゴリ Level 関連付け ID 実行時間 (ミリ秒) Properties
2018-02-22T03:28:28.633Z DiagnosticIoTHubD2C DistributedTracing Informational 00-8cd869a412459a25f5b4f31311223344-0144d2590aacd909-01 {"deviceId":"AZ3166","messageSize":"96","callerLocalTimeUtc":"2018-02-22T03:27:28.633Z","calleeLocalTimeUtc":"2018-02-22T03:27:28.687Z"}
2018-02-22T03:28:38.633Z DiagnosticIoTHubIngress DistributedTracing Informational 00-8cd869a412459a25f5b4f31311223344-349810a9bbd28730-01 20 {"isRoutingEnabled":"false","parentSpanId":"0144d2590aacd909"}
2018-02-22T03:28:48.633Z DiagnosticIoTHubEgress DistributedTracing Informational 00-8cd869a412459a25f5b4f31311223344-349810a9bbd28730-01 23 {"endpointType":"EventHub","endpointName":"myEventHub", "parentSpanId":"0144d2590aacd909"}

ログの種類については、Azure IoT Hub の分散トレース ログに関する記事を参照してください。

サンプル アプリケーションを実行する

このセクションでは、Azure IoT C SDK で使用する開発環境を準備します。 次に、サンプルの 1 つを変更して、デバイスのテレメトリ メッセージに対して分散トレースを有効にします。

これらの手順は、Windows でサンプルを構築するためのものです。 その他の環境では、C SDK のコンパイルに関するページ、またはプラットフォーム固有の開発用のパッケージ済み C SDK に関するページを参照してください。

ソース コードを複製し、初期化する

  1. Visual Studio 2022 用の C++ によるデスクトップ開発ワークロードをインストールします。 Visual Studio 2019 もサポートされます。

  2. CMake をインストールします。 コマンド プロンプトで cmake -version を入力し、これが PATH に含まれていることを確認します。

  3. コマンド プロンプトまたは Git Bash シェルを開きます。 次のコマンドを実行して、Azure IoT C SDK GitHub リポジトリのパブリックプレビュー ブランチの最新リリースをクローンします。

    git clone -b public-preview https://github.com/Azure/azure-iot-sdk-c.git
    cd azure-iot-sdk-c
    git submodule update --init
    

    この操作が完了するまで数分かかることが予想されます。

  4. azure-iot-sdk-c ディレクトリから次のコマンドを実行して cmake サブディレクトリを作成し、cmake フォルダーに移動します。

    mkdir cmake
    cd cmake
    cmake ..
    

    CMake で C++ コンパイラが見つからない場合は、上記のコマンドの実行中にビルド エラーが発生している可能性があります。 これが発生した場合は、Visual Studio コマンド プロンプトでコマンドを実行してください。

    ビルドが成功すると、最後のいくつかの出力行は次のようになります。

    $ cmake ..
    -- Building for: Visual Studio 15 2017
    -- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.17134.
    -- The C compiler identification is MSVC 19.12.25835.0
    -- The CXX compiler identification is MSVC 19.12.25835.0
    
    ...
    
    -- Configuring done
    -- Generating done
    -- Build files have been written to: E:/IoT Testing/azure-iot-sdk-c/cmake
    

テレメトリ サンプルを編集して分散トレースを有効にする

このセクションでは、SDK リポジトリ内の iothub_ll_telemetry_sample.c サンプルを編集して、分散トレースを有効にします。 また、編集されたバージョンのサンプルを azure-iot-distributed-tracing-sample リポジトリからコピーすることもできます。

  1. エディターを使用して、azure-iot-sdk-c/iothub_client/samples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.c ソース ファイルを開きます。

  2. 次の connectionString 定数の宣言を探します。

    /* Paste in the your iothub connection string  */
    static const char* connectionString = "[device connection string]";
    #define MESSAGE_COUNT        5000
    static bool g_continueRunning = true;
    static size_t g_message_count_send_confirmations = 0;
    

    connectionString 定数の値を、送信テレメトリのクイックスタートの「デバイスの登録」セクションで保存したデバイス接続文字列に置き換えます。

  3. IoTHubDeviceClient_LL_SetConnectionStatusCallback を呼び出しているコード行を見つけ、送信メッセージのループ前に接続状態のコールバック関数を登録します。 その行の下にコードを追加して IoTHubDeviceClient_LL_EnablePolicyConfiguration を呼び出し、デバイスの分散トレースを有効にします。

    // Setting connection status callback to get indication of connection to iothub
    (void)IoTHubDeviceClient_LL_SetConnectionStatusCallback(device_ll_handle, connection_status_callback, NULL);
    
    // Enabled the distrubted tracing policy for the device
    (void)IoTHubDeviceClient_LL_EnablePolicyConfiguration(device_ll_handle, POLICY_CONFIGURATION_DISTRIBUTED_TRACING, true);
    
    do
    {
        if (messages_sent < MESSAGE_COUNT)
    

    IoTHubDeviceClient_LL_EnablePolicyConfiguration 関数により、デバイス ツインを介して構成される特定の IoT Hub 機能のポリシーが有効になります。 追加のコード行を使用することで POLICY_CONFIGURATION_DISTRIBUTED_TRACING が有効になると、デバイスのトレース動作は、デバイス ツインで行われた分散トレースの変更を反映します。

  4. すべてのクォータを使い尽くさずにサンプル アプリを実行し続けるために、送信メッセージ ループの末尾に 1 秒の遅延を追加します。

        else if (g_message_count_send_confirmations >= MESSAGE_COUNT)
        {
            // After all messages are all received stop running
            g_continueRunning = false;
        }
    
        IoTHubDeviceClient_LL_DoWork(device_ll_handle);
        ThreadAPI_Sleep(1000);
    
    } while (g_continueRunning);
    

コンパイルと実行

  1. 前に作成した CMake ディレクトリ (azure-iot-sdk-c/cmake) から iothub_ll_telemetry_sample プロジェクト ディレクトリに移動し、サンプルをコンパイルします。

    cd iothub_client/samples/iothub_ll_telemetry_sample
    cmake --build . --target iothub_ll_telemetry_sample --config Debug
    
  2. アプリケーションを実行します。 デバイスにより、分散トレースをサポートするテレメトリが送信されます。

    Debug/iothub_ll_telemetry_sample.exe
    
  3. そのままアプリを実行します。 コンソール ウィンドウで、IoT Hub に送信されるメッセージを確認できます。

クラウドからサンプリング決定を受信できるクライアント アプリの場合は、分散トレース サンプル リポジトリにある iothub_devicetwin_sample.c サンプルを試してください。

Microsoft 以外のクライアントの回避策

C SDK を使用せずに分散トレース機能を実装する方が複雑です。 それは推奨されません。

最初に、開発者ガイド「IoT Hub メッセージを作成し、読み取る」に従って、すべての IoT Hub プロトコル プリミティブをご自身のメッセージで実装する必要があります。 次に、MQTT および AMQP メッセージのプロトコル プロパティを編集して、tracestate をシステム プロパティとして追加します。

具体的な内容は次のとおりです。

  • MQTT の場合は、%24.tracestate=timestamp%3d1539243209 をメッセージ トピックに追加します。 1539243209 は、Unix タイムスタンプ形式のメッセージ作成時に置き換える必要があります。 例としては、C SDK の実装を参照してください。
  • AMQP の場合は、key("tracestate")value("timestamp=1539243209") をメッセージの注釈として追加します。 参照実装については、uamqp_messaging.c ファイルを参照してください。

このプロパティを含むメッセージの割合を制御するには、ツインの更新など、クラウドによって開始されたイベントをリッスンするロジックを実装します。

次のステップ