你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用分布式跟踪(预览版)跟踪 Azure IoT 设备到云的消息

在 IoT 中心内使用分布式跟踪(预览版)在 IoT 消息通过 Azure 服务时监视这些消息。 IoT 中心是用于支持分布式跟踪的第一批 Azure 服务之一。 随着支持分布式跟踪的 Azure 服务越来越多,以后可以在解决方案涉及的所有 Azure 服务中跟踪物联网 (IoT) 消息。 有关该功能的详细信息,请参阅什么是分布式跟踪?

为 IoT 中心启用分布式跟踪时,可以:

  • 使用跟踪上下文监视每条消息流经 IoT 中心的情况。 跟踪上下文包含关联 ID,使用关联 ID 可将来自一个组件的事件与来自另一个组件的事件相关联。 可以使用设备孪生将其应用于一部分或所有 IoT 设备消息。
  • 将跟踪上下文记录到 Azure Monitor 日志
  • 度量并了解设备与 IoT 中心之间的消息流和延迟以及路由终结点。

重要

对 Azure IoT 中心的分布式跟踪目前以预览版提供。 有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Microsoft Azure 预览版的补充使用条款

先决条件

  • 在以下区域之一中创建的 Azure IoT 中心。

    • 北欧
    • 东南亚
    • 美国西部 2
  • 已注册到 IoT 中心的设备。 如果没有设备,请按照在 IoT 中心注册新设备中的步骤操作,并保存要在本文中使用的设备连接字符串。

  • 本文假设读者知道如何将遥测消息发送到 IoT 中心。

  • 最新版本的 Git

公共预览版限制和注意事项

请考虑以下限制,以确定此预览版功能是否适合你的场景:

  • W3C 跟踪上下文标准提案目前正在草拟中。

  • 客户端 SDK 当前支持的唯一开发语言是 C,位于 C 版 Azure IoT 设备 SDK 的公共预览版分支中

  • 云到设备孪生功能不适用于 IoT 中心基本层。 但是,如果 IoT 中心看到了适当撰写的跟踪上下文标头,则它仍会将日志记录到 Azure Monitor。

  • 为确保有效的操作,IoT 中心会针对分布式跟踪期间的日志记录速率施加限制。

  • 分布式跟踪功能仅支持在以下区域中创建的 IoT 中心:

    • 北欧
    • 东南亚
    • 美国西部 2

了解 Azure IoT 分布式跟踪

许多 IoT 解决方案,包括 Azure IoT 参考体系结构,通常遵循微服务体系结构的某种变体。 随着 IoT 解决方案变得越来越复杂,最终会使用十多个甚至更多的微服务。 这些微服务可能来自 Azure 或可能不是来自 Azure。

可能很难查明 IoT 消息是在哪个位置删除或减慢的。 例如,假设某个 IoT 解决方案使用 5 个不同的 Azure 服务和 1500 个活动设备。 每个设备每秒发送 10 条设备到云的消息,每秒总共发送 15,000 条消息。 但注意,Web 应用每秒只能看到 10,000 条消息。 如何查明原因?

若要跨服务重建 IoT 消息流,每个服务应该传播一个用于唯一标识消息的关联 ID。 Azure Monitor 在集中式系统中收集相关 ID 后,可以使用这些 ID 查看消息流。 此方法称为分布式跟踪模式

为了使分布式跟踪得到更广泛的采用,Microsoft 正在努力制定分布式跟踪的 W3C 标准提案。 启用对 IoT 中心的分布式跟踪支持后,对于每个生成的消息,它将遵循以下流:

  1. 在 IoT 设备上生成消息。
  2. IoT 设备确定(借助于云)应为此消息分配跟踪上下文。
  3. SDK 会向消息属性添加一个 tracestate 值,其中包含用于创建消息的时间戳。
  4. IoT 设备将消息发送到 IoT 中心。
  5. 消息抵达 IoT 中心网关。
  6. IoT 中心会在消息属性中查找 tracestate 值,并检查其格式是否正确。 如果正确,IoT 中心将为消息生成全局唯一的 trace-id 值,并为“跃点”生成 span-id 值。IoT 中心将这些值记录在 DiagnosticIoTHubD2C 操作下的 IoT 中心分布式跟踪日志中。
  7. 在消息处理完成后,IoT 中心会生成另一个 span-id 值,并将它连同现有的 trace-id 值一起记录到 DiagnosticIoTHubIngress 操作下。
  8. 如果为消息启用了路由,则 IoT 中心会将消息写入自定义终结点。 IoT 中心在 DiagnosticIoTHubEgress 类别下记录另一个具有相同 trace-id 值的 span-id 值。

在 IoT 中心内配置分布式跟踪

在本部分,你将配置一个 IoT 中心来记录分布式跟踪属性(关联 ID 和时间戳)。

  1. 转到 Azure 门户中的 IoT 中心。

  2. 在 IoT 中心的左窗格中,向下滚动到“监视”部分并选择“诊断设置”。

  3. 选择“添加诊断设置”。

  4. 在“诊断设置名称”框中,输入新诊断设置的名称。 例如输入“DistributedTracingSettings”。

    显示用于为诊断设置添加名称的位置的屏幕截图。

  5. 在“目标详细信息”下选择以下一个或多个选项,以确定日志记录信息的发送目标:

    • 存档到存储帐户:配置用于包含日志记录信息的存储帐户。
    • 流式传输到事件中心:配置用于包含日志记录信息的事件中心。
    • 发送到 Log Analytics:配置用于包含日志记录信息的 Log Analytics 工作区。
  6. 在“日志”部分中,选择要记录的操作。

    请包含“分布式跟踪”,并配置“保留期”以指定要将日志记录保留几天。 保留日志会影响存储费用。

    显示分布式跟踪操作用于 IoT 中心诊断设置的位置的屏幕截图。

  7. 选择“保存”。

  8. (可选)若要了解消息如何流向不同的位置,请对至少两个不同的终结点设置路由规则

启用日志记录后,在以下任一情况下遇到包含有效跟踪属性的消息时,IoT 中心都会记录日志:

  • 消息抵达 IoT 中心网关。
  • IoT 中心处理消息。
  • 消息路由到自定义终结点。 必须启用路由。

若要详细了解这些日志及其架构,请参阅监视 IoT 中心IoT 中心资源日志中的分布式跟踪

更新采样选项

若要更改要从云跟踪的消息百分比,必须更新设备孪生。 可以使用 Azure 门户中的 JSON 编辑器或 IoT 中心服务 SDK 进行更新。 以下附属部分提供了示例。

更新单个设备

可以使用 Azure 门户或适用于 Visual Studio Code (VS Code) 的 Azure IoT 中心扩展来更新单个设备的采样率。

  1. 转到 Azure 门户中的 IoT 中心,然后从菜单的“设备管理”部分中选择“设备”。

  2. 选择设备。

  3. 在“分布式跟踪(预览版)”下,选择齿轮图标。 在打开的面板中:

    1. 选择“启用”选项。
    2. 选择“采样率”时,请选择介于 0 和 100 之间的百分比。
    3. 选择“保存” 。

    显示如何在 Azure 门户中启用分布式跟踪的屏幕截图。

  4. 等待几秒,然后选择“刷新”。 如果设备成功确认更改,则会显示一个带有复选标记的同步图标。

批量更新多个设备

若要更新多个设备的分布式跟踪采样配置,请使用自动设备配置。 按照此孪生架构:

{
    "properties": {
        "desired": {
            "azureiot*com^dtracing^1": {
                "sampling_mode": 1,
                "sampling_rate": 100
            }
        }
    }
}
元素名称 必须 类型​​ 说明
sampling_mode Integer 目前支持使用两个模式值来启用和禁用采样。 1 表示启用,2 表示禁用。
sampling_rate Integer 此值是百分比。 只允许使用从 0100(含)的值。

查询和可视化跟踪

若要查看 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 中的几个示例日志:

生成时间 操作名称 类别 级别 相关性 ID 持续时间(毫秒) 属性
2018-02-22T03:28:28.633Z DiagnosticIoTHubD2C DistributedTracing 信息 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 信息 00-8cd869a412459a25f5b4f31311223344-349810a9bbd28730-01 20 {"isRoutingEnabled":"false","parentSpanId":"0144d2590aacd909"}
2018-02-22T03:28:48.633Z DiagnosticIoTHubEgress DistributedTracing 信息 00-8cd869a412459a25f5b4f31311223344-349810a9bbd28730-01 23 {"endpointType":"EventHub","endpointName":"myEventHub", "parentSpanId":"0144d2590aacd909"}

若要了解日志类型,请参阅 Azure IoT 中心分布式跟踪日志

运行示例应用程序

在本部分,你将准备一个与 Azure IoT C SDK 配合使用的开发环境。 然后修改某个示例,以针对设备的遥测消息启用分布式跟踪。

这些说明适用于在 Windows 上生成示例。 对于其他环境,请参阅编译 C SDK用于平台特定的开发的预打包 C SDK

克隆源代码并初始化

  1. 安装适用于 Visual Studio 2022 的使用 C++ 的桌面开发工作负载。 还支持 Visual Studio 2019。

  2. 安装 CMake。 通过在命令提示符下输入 cmake -version,确保它位于 PATH 中。

  3. 打开命令提示符或 Git Bash shell。 运行以下命令,以克隆 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 中心功能启用策略。 使用额外代码行启用 POLICY_CONFIGURATION_DISTRIBUTED_TRACING 之后,设备的跟踪行为将反映在设备孪生中所做的分布式跟踪更改。

  4. 若要使示例应用保持运行且不耗尽所有配额,请在发送消息循环的末尾添加一秒钟的延迟:

        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 中心的消息。

对于可从云接收采样决策的客户端应用,请尝试使用分布式跟踪示例存储库中的 iothub_devicetwin_sample.c 示例。

针对非 Microsoft 客户端的解决方法

在不使用 C SDK 的情况下实现分布式跟踪功能更为复杂。 但我们不建议这样做。

首先,必须通过遵循创建和读取 IoT 中心消息开发者指南,在消息中实现所有 IoT 中心协议基元。 然后,在 MQTT 和 AMQP 消息中编辑协议属性,以将 tracestate 添加为系统属性。

具体而言:

  • 对于 MQTT,添加 %24.tracestate=timestamp%3d1539243209 到消息主题。 将 1539243209 替换为 Unix 时间戳格式的消息的创建时间。 请参考 C SDK 中作为示例的实现。
  • 对于 AMQP,请将 key("tracestate")value("timestamp=1539243209") 添加为消息注释。 有关参考实现,请参阅 uamqp_messaging.c 文件。

若要控制包含此属性的消息百分比,请实现相应的逻辑来侦听云发起的事件,例如孪生更新。

后续步骤