排查 Azure Monitor Application Insights 中缺少的应用程序遥测问题

本文介绍如何使用 PowerShell 或 curl 测试连接和遥测引入,从而确定处理管道中导致遥测丢失的步骤。

可能导致遥测丢失的步骤

下图显示了在引入和使用过程中可能会丢失遥测数据的步骤:

遥测在处理管道中传递的步骤。

如果Azure 门户中未显示应用程序遥测,则处理管道中跨步骤失败可能是原因:

  • Application Insights SDK 或代理配置错误,不会将应用程序遥测数据发送到引入终结点。
  • SDK 或代理配置正确,但网络会阻止对引入终结点的调用。
  • 引入终结点会删除或限制入站遥测数据。
  • 由于 服务运行状况,引入管道在处理遥测过程中会下降或严重减慢。
  • (不常见的) Log Analytics 在保存遥测记录时面临服务运行状况问题。
  • (不常见) 查询 API 在 api.applicationinsights.io 从 Log Analytics 查询记录时失败。
  • Azure 门户无法拉取或呈现您尝试查看的记录。

通过发送示例遥测记录来识别步骤

配置问题或暂时性问题可能发生在 Application Insights 服务的任意位置。 若要确定处理管道中导致无数据或缺少数据症状的步骤,请使用 PowerShell 或 curl 发送示例遥测记录。 对于 PowerShell 脚本或 curl 命令,请转到以下部分:

如果 Web 应用在本地服务器或 Azure VM 上运行,请连接到服务器或 VM,并使用 PowerShell 将单个遥测记录发送到 Application Insights 服务实例。 如果发送遥测数据时出现问题的 Web 应用在 Kudu 上运行,请从 Azure Web 应用 中的 Kudu 的 PowerShell 调试控制台运行以下脚本。

$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri $url -Method POST -Body $availabilityData -UseBasicParsing

注意

  • 在运行 Invoke-WebRequest cmdlet 之前,请发出 $ProgressPreference = "SilentlyContinue" cmdlet。
  • 不能使用 -Verbose-Debug。 请改用 -UseBasicParsing

使用 PowerShell 发送示例遥测记录后,导航到Azure 门户中的“Application Insights 日志”选项卡,如果到达,检查。 如果显示示例遥测记录,则会消除大部分处理管道。

正确保存并显示的示例遥测记录意味着:

  • 本地服务器或 VM 具有解析为正确 IP 地址的 DNS。
  • 网络在没有阻止或删除的情况下将示例传送到引入终结点。
  • 引入终结点接受示例有效负载并通过引入管道进行处理。
  • Log Analytics 正确保存了示例记录。
  • “Azure 门户日志”选项卡能够查询 API (api.applicationinsights.io) 并在Azure 门户中呈现示例记录。

如果生成的示例记录到达 Application Insights 实例,并且可以使用 “日志”资源 菜单查询示例记录, 请对 Application Insights SDK 或代理进行故障排除。 然后,可以继续收集 SDK 日志、自我诊断日志或探查器跟踪,以适用于 SDK 或代理版本为准。

以下部分提供有关使用 PowerShell 或 curl 发送示例遥测记录的信息。

用于发送可用性测试结果的 PowerShell 脚本

可用性测试结果是用于测试的理想遥测类型。 原因是引入管道从不对可用性测试结果进行采样。 如果发送请求遥测记录,则启用引入采样后,可能会对其进行采样。 从示例可用性测试结果开始,然后根据需要尝试其他遥测类型。

下面是发送可用性测试结果的示例 PowerShell 脚本:

# Info: Provide either the connection string or ikey for your Application Insights resource
$ConnectionString = ""
$InstrumentationKey = ""
function ParseConnectionString {
param ([string]$ConnectionString)
  $Map = @{}
  foreach ($Part in $ConnectionString.Split(";")) {
     $KeyValue = $Part.Split("=")
     $Map.Add($KeyValue[0], $KeyValue[1])
  }
  return $Map
}
# If ikey is the only parameter supplied, we'll send telemetry to the global ingestion endpoint instead of regional endpoint found in connection strings
If (($InstrumentationKey) -and ("" -eq $ConnectionString)) {
$ConnectionString = "InstrumentationKey=$InstrumentationKey;IngestionEndpoint=https://dc.services.visualstudio.com/"
}
$map = ParseConnectionString($ConnectionString)
$url = $map["IngestionEndpoint"] + "v2/track"
$ikey = $map["InstrumentationKey"]
$lmUrl = $map["LiveEndpoint"]
$time = (Get-Date).ToUniversalTime().ToString("o")
$availabilityData = @"
{
  "data": {
        "baseData": {
            "ver": 2,
            "id": "SampleRunId",
            "name": "Microsoft Support Sample Webtest Result",
            "duration": "00.00:00:10",
            "success": true,
            "runLocation": "Region Name",
            "message": "Sample Webtest Result",
            "properties": {
                "Sample Property": "Sample Value"
                }
        },
        "baseType": "AvailabilityData"
  },
  "ver": 1,
  "name": "Microsoft.ApplicationInsights.Metric",
  "time": "$time",
  "sampleRate": 100,
  "iKey": "$ikey",
  "flags": 0
}
"@
# Uncomment one or more of the following lines to test client TLS/SSL protocols other than the machine default option
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::SSL3
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS11
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS13
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri $url -Method POST -Body $availabilityData -UseBasicParsing

此脚本生成原始 REST 请求,以将单个可用性测试结果传递给 Application Insights 组件。 使用此脚本时,请提供 $ConnectionString$InstrumentationKey 参数。

  • 如果仅提供连接字符串参数,则遥测数据将发送到连接字符串中的区域终结点。
  • 如果仅提供检测密钥 (ikey) 参数,则遥测数据将发送到全局引入终结点。
  • 如果同时提供了 连接字符串 和 ikey 参数,脚本会将遥测数据发送到 连接字符串 中的区域终结点。

注意

  • 测试应用程序建立的连接。 如果在 Azure 门户中启用 Application Insights,则可能依赖于具有区域终结点 的https://<region>.in.applicationinsights.azure.com连接字符串。 如果 SDK 配置仅提供 ikey,则依赖于全局终结点 https://dc.applicationinsights.azure.com。 请确保填充与 Web 应用程序 SDK 配置匹配的脚本参数,提供 连接字符串 或 ikey。
  • 2025 年 3 月 31 日,将结束对检测密钥引入的支持。 检测密钥引入将继续有效,但我们将不再提供该功能的更新或支持。 转换为连接字符串 以利用 新功能

最简单的方法是在 IaaS 或 Azure 虚拟机规模集 实例上从 PowerShell ISE 环境运行此脚本。 还可以将脚本复制并粘贴到 App 服务 Kudu 接口 PowerShell 调试控制台中,然后运行它。

执行脚本时,查找 HTTP 200 响应并查看响应详细信息。 作为响应 JSON 有效负载的一部分,需要以下详细信息:

  • 计数 itemsReceived 与 匹配 itemsAccepted
  • 引入终结点通知客户端:你发送了一条遥测记录,我们接受了一条遥测记录。

请参阅以下屏幕截图作为示例:

显示收到的项数和已接受项数的代码。

用于发送可用性测试结果的 Curl 命令

如果运行的是 Linux VM,请使用 curl 而不是 PowerShell 发送类似的 REST 请求。 需要调整 引入终结点主机名iKey 值和 time 值。 Application Insights 引入终结点不接受任何超过 48 小时的记录。

下面是发送单个可用性测试结果的示例 curl 命令:

  • 适用于 Linux/MacOS 的 Curl 命令:

    curl -H "Content-Type: application/json" -X POST -d '{"data":{"baseData":{"ver":2,"id":"SampleRunId","name":"MicrosoftSupportSampleWebtestResultUsingCurl","duration":"00.00:00:10","success":true,"runLocation":"RegionName","message":"SampleWebtestResult","properties":{"SampleProperty":"SampleValue"}},"baseType":"AvailabilityData"},"ver":1,"name":"Microsoft.ApplicationInsights.Metric","time":"2022-09-01T12:00:00.0000000Z","sampleRate":100,"iKey":"########-####-####-####-############","flags":0}' https://dc.applicationinsights.azure.com/v2.1/track
    
  • 适用于 Windows 的 Curl 命令:

    curl -H "Content-Type: application/json" -X POST -d {\"data\":{\"baseData\":{\"ver\":2,\"id\":\"SampleRunId\",\"name\":\"MicrosoftSupportSampleWebtestResultUsingCurl\",\"duration\":\"00.00:00:10\",\"success\":true,\"runLocation\":\"RegionName\",\"message\":\"SampleWebtestResult\",\"properties\":{\"SampleProperty\":\"SampleValue\"}},\"baseType\":\"AvailabilityData\"},\"ver\":1,\"name\":\"Microsoft.ApplicationInsights.Metric\",\"time\":\"2021-10-05T22:00:00.0000000Z\",\"sampleRate\":100,\"iKey\":\"########-####-####-####-############\",\"flags\":0} https://dc.applicationinsights.azure.com/v2/track
    

用于发送请求遥测记录的 PowerShell 脚本

若要排查缺少请求遥测的问题,请使用以下 PowerShell 脚本测试发送单个请求遥测记录。 此遥测类型容易受到服务器端引入采样配置的影响。 验证 引入采样 是否已关闭,以确认测试记录是否已正确保存。

# Info: Provide either the connection string or ikey for your Application Insights resource
$ConnectionString = ""
$InstrumentationKey = ""
function ParseConnectionString {
param ([string]$ConnectionString)
  $Map = @{}
  foreach ($Part in $ConnectionString.Split(";")) {
     $KeyValue = $Part.Split("=")
     $Map.Add($KeyValue[0], $KeyValue[1])
  }
  return $Map
}
# If ikey is the only parameter supplied, we'll send telemetry to the global ingestion endpoint instead of regional endpoint found in connection strings
If (($InstrumentationKey) -and ("" -eq $ConnectionString)) {
$ConnectionString = "InstrumentationKey=$InstrumentationKey;IngestionEndpoint=https://dc.services.visualstudio.com/"
}
$map = ParseConnectionString($ConnectionString)
$url = $map["IngestionEndpoint"] + "v2/track"
$ikey = $map["InstrumentationKey"]
$lmUrl = $map["LiveEndpoint"]
$time = (Get-Date).ToUniversalTime().ToString("o")
$requestData = @"
{
   "data": {
      "baseType": "RequestData",
      "baseData": {
        "ver": 2,
        "id": "22093920382029384",
        "name": "GET /msftsupport/requestdata/",
        "starttime": "$time",
        "duration": "00:00:01.0000000",
        "success": true,
        "responseCode": "200",
        "url": "https://localhost:8080/requestData/sampleurl",
        "httpMethod": "GET"
       }
   },
   "ver": 1,
   "iKey": "$ikey",
   "name": "Microsoft.ApplicationInsights.Request",
   "time": "$time",
   "sampleRate": 100,
   "flags": 0
}
"@
# Uncomment one or more of the following lines to test client TLS/SSL protocols other than the machine default option
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::SSL3
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS11
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12
# [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS13
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri $url -Method POST -Body $requestData -UseBasicParsing

排查 SSL 或 TLS 配置问题

如果上述脚本失败,请排查 SSL 或 TLS 配置问题。 大多数引入终结点要求客户端使用 TLS 1.2 和特定的密码套件。 在这种情况下,请调整 PowerShell 作为客户端参与 SSL 或 TLS 协议的方式。 如果需要将安全通道诊断为客户端 VM 与引入终结点之间的连接的一部分,请包含以下代码片段。

  • 选项 1:控制 PowerShell 使用哪个 SSL 或 TLS 协议与引入终结点建立连接。

    通过删除 # 字符并将其添加到 PowerShell 脚本中的 cmdlet 之前 Invoke-WebRequest ,以控制测试 REST 请求中使用的协议,来取消注释以下任何一行:

    # Uncomment one or more of these lines to test TLS/SSL protocols other than the machine default option
    # [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::SSL3
    # [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS
    # [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS11
    # [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12
    # [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS13
    
  • 选项 2:忽略任何 SSL 证书验证问题。

    如果有参与 SSL 证书卸载的防火墙或代理服务器,请忽略任何 SSL 证书问题,方法是在 cmdlet 前面 Invoke-WebRequest 添加以下代码片段:

    # Ignore mismatched SSL certificate
    add-type @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class TrustAllCertsPolicy : ICertificatePolicy {
            public bool CheckValidationResult(
                ServicePoint srvPoint, X509Certificate certificate,
                WebRequest request, int certificateProblem) {
                return true;
            }
        }
    "@
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
    

如果应用程序默认为系统或服务器默认 TLS 设置,请在 Windows 计算机上的注册表中更改这些默认设置。 有关详细信息,请参阅 传输层安全性 (TLS) 注册表设置

如果需要更改 .NET 应用程序使用的默认 TLS/SSL 协议,请使用 .NET Framework 遵循传输层安全性 (TLS) 最佳做法中的指导。

排查 Application Insights SDK 或代理的设置或配置问题

如果使用 PowerShell 或 curl 从应用程序的主机发送遥测成功,则缺少遥测可能是由于 Application Insights SDK 或代理的设置或配置问题。 为应用程序主机和编程语言启用 Application Insights 监视,以验证所有配置或代码是否遵循正确的指导和示例。

如果使用 PowerShell 或 curl 执行的测试未能将遥测数据发送到引入终结点,请验证可能导致问题的几个常见的客户端相关问题:

  • 网络上的 DNS 无法将引入终结点解析为正确的 IP 地址。
  • 防火墙或网关设备可能会阻止从应用程序服务器到引入终结点的 TCP 连接。
  • SDK 连接到的引入终结点可能需要 TLS 1.2,但应用程序可能默认使用 TLS 1.0 或 TLS 1.1。
  • 你可能有多个 Azure Monitor 专用链接影响专用网络,这可能会覆盖 DNS 条目,以将引入终结点解析为错误的专用 IP 地址。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 还可以向 Azure 反馈社区提交产品反馈。