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

本文可帮助你确定处理管道中的步骤,该步骤会导致遥测数据丢失,方法是使用 PowerShell 或 curl 测试连接和遥测引入。

可能导致遥测丢失的步骤

下图显示了引入和消耗期间可能缺少遥测的步骤:

遥测传入处理管道的步骤。

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

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

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

应用程序见解服务中的任何位置都可能出现配置问题或暂时性问题。 若要在处理管道中标识导致无数据或缺失数据症状的步骤,请使用 PowerShell 或 curl 发送示例遥测记录。 对于 PowerShell 脚本或 curl 命令,请转到以下部分:

如果 Web 应用在本地服务器或 Azure VM 上运行,请连接到服务器或 VM,并使用 PowerShell 将单个遥测记录发送到 Applications 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 证书卸载的防火墙或代理服务器,请通过在 cmdlet 前面 Invoke-WebRequest 添加以下代码片段来忽略任何 SSL 证书问题:

    # 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 反馈社区