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

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

Azure 门户无法拉取或呈现尝试查看的记录

如果 Application Insights 数据收集终结点配置为使用 Microsoft Entra ID(以前为 Azure AD)进行身份验证,则还必须将应用程序配置为使用 Microsoft Entra ID 进行身份验证。 在此方案中,应用程序负责使用 Microsoft Entra ID 进行身份验证。 如果应用程序未正确配置,则遥测将被拒绝,即使检测正确且应用程序正在生成遥测数据,也不会显示在 Azure 门户中。

若要将应用程序配置为使用 Microsoft Entra ID 进行身份验证,请按照 “启用 Microsoft Entra ID(以前为 Azure AD)身份验证”中的步骤进行作。

可能导致遥测丢失的步骤

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

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

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

小窍门

Application Insights 支持团队无法帮助解决网络问题。 提交阻止 Application Insights 接收遥测数据(例如 DNS 解析失败)的网络问题的支持票证时,请确保在产品中指定 Azure 网络或 Azure 专用链接,或在 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 反馈社区