应用程序网关诊断日志

应用程序网关日志提供有关与资源及其操作相关的事件的详细信息。 这些日志可用于访问、活动、防火墙和性能等事件(仅适用于 V1)。 使用此原始数据排查问题或生成分析仪表板时,日志中的精细信息非常有用。

日志可用于应用程序网关的所有资源;但是,要使用它们,必须在所选的存储位置启用其集合。 Azure 应用程序网关中的日志记录由 Azure Monitor 服务启用。 建议使用 Log Analytics 工作区,因为可以轻松使用其预定义的查询,并根据特定的日志条件设置警报。

诊断日志的类型

可在 Azure 中使用不同类型的日志来对应用程序网关进行管理和故障排除。 可以在下面了解有关这些类型的详细信息:

  • 活动日志:可使用 Azure 活动日志(以前称为操作日志和审核日志)查看提交到 Azure 订阅的所有操作及其状态。 默认情况下会收集活动日志条目,可在 Azure 门户中查看这些条目。
  • 访问日志:可以使用此日志查看应用程序网关访问模式并分析重要信息。 此日志包括调用方的 IP、请求的 URL、响应延迟、返回代码,以及传入和传出的字节数。访问日志每 60 秒收集一次。 此日志包含每个应用程序网关实例的一条记录。 应用程序网关实例由 instanceId 属性标识。
  • 性能日志:可使用此日志查看应用程序网关实例的执行情况。 此日志会捕获每个实例的性能信息,包括服务的总请求数、吞吐量(以字节为单位)、失败请求计数、运行正常和运行不正常的后端实例计数。 每隔 60 秒会收集一次性能日志。 性能日志仅适用于 v1 SKU。 对于 v2 SKU,请对性能数据使用指标
  • 防火墙日志:可使用此日志查看通过应用程序网关(配置有 Web 应用程序防火墙)的检测模式或阻止模式记录的请求。 防火墙日志每 60 秒收集一次。

注意

日志仅适用于在 Azure 资源管理器部署模型中部署的 Azure 资源。 你不能将日志用于经典部署模型中的资源。 若要更好地了解两种模型,请参阅了解 Resource Manager 部署和经典部署一文。

存储位置

可以使用以下选项将日志存储在首选位置。

Log Analytic 工作区:此选项让你可以轻松使用预定义的查询、可视化效果并根据特定的日志条件设置警报。 Log Analytics 工作区中资源日志使用的表取决于资源使用的集合类型:

Azure 诊断:数据写入到 Azure 诊断表。 Azure 诊断表在多种资源类型之间共享,其中每种类型会添加自身的自定义字段。 当引入到 Azure 诊断表的自定义字段数超过 500 时,新字段不会添加为顶级字段,而是作为动态键值对添加到“AdditionalFields”字段。

特定于资源(建议):将数据写入每个资源类别的专用表中。 在资源特定的模式下,将在所选工作区中为诊断设置中选择的每个日志类别分配其自身的表。 这样可以带来多种好处,包括:

对于应用程序网关,资源特定的模式将创建三个表:

  • AGWAccessLogs
  • AGWPerformanceLogs
  • AGWFirewallLogs

注意

资源特定的选项目前在所有公共区域中可用
现有用户可以继续使用 Azure 诊断,或者通过在 API 目标中将诊断设置中的切换开关切换为“资源特定”或“专用”来选择使用专用表。 不支持双重模式。 所有日志中的数据可以流向 Azure 诊断或专用表。 但是,可以同时指定多个诊断设置,其中一个数据流指向 Azure 诊断,另一个数据流使用资源特定的表。

在 Log Analytics 中选择目标表:所有 Azure 服务最终都会使用资源特定的表。 在进行这种转换的过程中,可以在诊断设置中使用切换按钮选择 Azure 诊断或资源特定的表。 默认情况下,该切换开关设置为“资源特定”,在此模式下,新选定类别的日志将发送到 Log Analytics 中的专用表,而现有流保持不变。 请参阅以下示例。

门户中应用程序网关的资源 ID 的屏幕截图。

工作区转换:选择“资源特定”选项可以在使用工作区转换引入数据之前筛选和修改数据。 这样可以提供精细控制,使你能够通过降低数据成本并增强安全性来重点关注日志中最相关的信息。 有关设置工作区转换的详细说明,请参阅:教程:使用 Azure 门户将工作区转换添加到 Azure Monitor 日志

使用工作区转换优化访问日志的示例

示例 1:列的选择性投影:假设你的应用程序网关访问日志包含 20 列,但你只想分析 6 个特定列中的数据。 通过工作区转换,可以将这 6 列投影到工作区中,从而有效地排除其他 14 列。 即使不会存储这些已排除列中的原始数据,但它们的空占位符仍然会出现在“日志”边栏选项卡中。 此方法优化了存储并确保仅保留相关数据进行分析。

注意

在“日志”边栏选项卡中,选择“试用新的 Log Analytics”选项可以更好地控制用户界面中显示的列

示例 2:重点关注特定的状态代码:在分析访问日志时,无需处理所有日志条目,而可以编写一个查询来仅检索具有特定 HTTP 状态代码(例如 4xx 和 5xx)的行。 由于在理想情况下,大多数请求都属于 2xx 和 3xx 类别(表示成功的响应),因此重点关注有问题的状态代码可以缩小数据集的范围。 这种有针对性的方法使你能够提取最相关和可操作的信息,因此既可以带来便利,也可以产生经济效益。

从 Azure 诊断过渡到资源特定的表的建议策略

  1. 评估当前数据保留期:确定 Azure 诊断表中当前保留数据的持续时间(例如:假设诊断表将数据保留 15 天)。
  2. 建立资源特定的保留:使用资源特定的表实现新的诊断设置。
  3. 并行数据收集:在临时性的一段时间内,在 Azure 诊断和资源特定的设置中并行收集数据。
  4. 确认数据准确度:验证两种设置中的数据收集是否准确且一致。
  5. 删除 Azure 诊断设置:删除 Azure 诊断设置以防止重复进行数据收集。

其他存储位置:

  • Azure 存储帐户:如果日志存储时间较长并且希望能根据需要随时查看,最好使用存储帐户。
  • Azure 事件中心:要集成其他安全信息和事件管理 (SIEM) 工具以获取资源警报,最好使用事件中心。
  • Azure Monitor 合作伙伴集成

详细了解 Azure Monitor 的诊断设置目标

通过 PowerShell 启用日志记录

每个 Resource Manager 资源都会自动启用活动日志记录。 必须启用访问和性能日志记录才能开始收集通过这些日志提供的数据。 若要启用日志记录,请执行以下步骤:

  1. 记下存储帐户的资源 ID,其中存储日志数据。 此值的形式为:/subscriptions/<subscriptionId>/resourceGroups/<资源组名称>/providers/Microsoft.Storage/storageAccounts/<存储帐户名称>。 可以使用订阅中的任何存储帐户。 可使用 Azure 门户查找此信息。

    存储帐户终结点的屏幕截图

  2. 记下为其启用日志记录的应用程序网关的资源 ID。 此值的形式为:/subscriptions/<subscriptionId>/resourceGroups/<资源组名称>/providers/Microsoft.Network/applicationGateways/<应用程序网关名称>。 可以使用门户查找以下信息。

    应用网关属性的屏幕截图

  3. 使用以下 PowerShell cmdlet 启用诊断日志记录:

    Set-AzDiagnosticSetting  -ResourceId /subscriptions/<subscriptionId>/resourceGroups/<resource group name>/providers/Microsoft.Network/applicationGateways/<application gateway name> -StorageAccountId /subscriptions/<subscriptionId>/resourceGroups/<resource group name>/providers/Microsoft.Storage/storageAccounts/<storage account name> -Enabled $true     
    

提示

活动日志不需要单独的存储帐户。 使用存储来记录访问和性能需支付服务费用。

通过 Azure 门户启用日志记录

  1. 在 Azure 门户中找到资源,然后选择“诊断设置”。

    对于应用程序网关,提供 3 种日志:

    • 访问日志
    • 性能日志
    • 防火墙日志
  2. 若要开始收集数据,请选择“启用诊断”。

    启用诊断

  3. “诊断设置” 页提供用于诊断日志的设置。 本示例使用 Log Analytics 存储日志。 也可使用事件中心和存储帐户保存诊断日志。

    启动配置过程

  4. 键入设置的名称,确认设置,然后选择“保存”。

活动日志

默认情况下,Azure 生成活动日志。 日志可在 Azure 事件日志存储中保留 90 天。 了解有关这些日志的详细信息,请参阅查看事件和活动日志一文。

访问日志

只有按照上述步骤在每个应用程序网关实例上启用了访问日志,才会生成该日志。 数据存储在启用日志记录时指定的存储帐户中。 应用程序网关的每次访问均以 JSON 格式记录下来,如下所示。

对于应用程序网关和 WAF v2 SKU

注意

  • 有关 TLS/TCP 代理相关信息,请访问数据参考
  • 共享 AzureDiagnostics 表中的某些列仍在移植到专用表。 因此,目前只能通过 AzureDiagnostics 表获取包含相互身份验证详细信息的列。
  • clientIP 值为 127.0.0.1 的访问日志源自在应用程序网关实例上运行的内部安全进程。 可以放心地忽略这些日志条目。
说明
instanceId 处理请求的应用程序网关实例。
clientIP 应用程序网关的直接客户端的 IP。 如果另一个代理位于应用程序网关的前面,则会显示该前面代理的 IP。
httpMethod 请求所用的 HTTP 方法。
requestUri 所收到请求的 URI。
UserAgent HTTP 请求标头中的用户代理。
httpStatus 从应用程序网关返回到客户端的 HTTP 状态代码。
httpVersion 请求的 HTTP 版本。
receivedBytes 接收的数据包的大小(以字节为单位)。
sentBytes 发送的数据包的大小(以字节为单位)。
clientResponseTime 应用程序网关发送到客户端的第一个字节和最后一个字节之间的时间差(以秒为单位)。 有助于衡量应用程序网关处理响应或慢速客户端的时间。
timeTaken 处理客户端请求的第一个字节以及将响应中的最后一个字节发送到客户端所需的时长(以秒为单位)。 必须注意,“所用时间”字段通常包括请求和响应数据包在网络上传输的时间。
WAFEvaluationTime WAF 处理请求所需的时长(以秒为单位)。
WAFMode 值可以是“检测”或“预防”
transactionId 唯一标识符,用于关联从客户端收到的请求
sslEnabled 与后端池的通信是否使用了 TLS。 有效值为 on 和 off。
sslCipher 用于 TLS 通信的密码套件(如果已启用 TLS)。
sslProtocol 使用的 SSL/TLS 协议(如果已启用 TLS)。
serverRouted 应用程序网关将请求路由到的后端服务器。
serverStatus 后端服务器的 HTTP 状态代码。
serverResponseLatency 后端服务器的响应延迟(以秒为单位)。
host 请求的主机标头中列出的地址。 如果使用标头重写进行重写,此字段将包含更新的主机名
originalRequestUriWithArgs 此字段包含原始请求 URL
requestUri 在应用程序网关上执行重写操作后,此字段将包含 URL
upstreamSourcePort 应用程序网关在启动与后端目标的连接时使用的源端口
originalHost 此字段包含原始请求主机名
error_info 4xx 和 5xx 错误的原因。 显示失败请求的错误代码。 有关更多详细信息,请参阅错误代码信息
contentType 应用程序网关正在处理或传送的内容或数据的类型
{
    "timeStamp": "2021-10-14T22:17:11+00:00",
    "resourceId": "/SUBSCRIPTIONS/{subscriptionId}/RESOURCEGROUPS/{resourceGroupName}/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/{applicationGatewayName}",
    "listenerName": "HTTP-Listener",
    "ruleName": "Storage-Static-Rule",
    "backendPoolName": "StaticStorageAccount",
    "backendSettingName": "StorageStatic-HTTPS-Setting",
    "operationName": "ApplicationGatewayAccess",
    "category": "ApplicationGatewayAccessLog",
    "properties": {
        "instanceId": "appgw_2",
        "clientIP": "185.42.129.24",
        "clientPort": 45057,
        "httpMethod": "GET",
        "originalRequestUriWithArgs": "\/",
        "requestUri": "\/",
        "requestQuery": "",
        "userAgent": "Mozilla\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/52.0.2743.116 Safari\/537.36",
        "httpStatus": 200,
        "httpVersion": "HTTP\/1.1",
        "receivedBytes": 184,
        "sentBytes": 466,
        "clientResponseTime": 0,
        "timeTaken": 0.034,
        "WAFEvaluationTime": "0.000",
        "WAFMode": "Detection",
        "transactionId": "592d1649f75a8d480a3c4dc6a975309d",
        "sslEnabled": "on",
        "sslCipher": "ECDHE-RSA-AES256-GCM-SHA384",
        "sslProtocol": "TLSv1.2",
        "sslClientVerify": "NONE",
        "sslClientCertificateFingerprint": "",
        "sslClientCertificateIssuerName": "",
        "serverRouted": "52.239.221.65:443",
        "serverStatus": "200",
        "serverResponseLatency": "0.028",
        "upstreamSourcePort": "21564",
        "originalHost": "20.110.30.194",
        "host": "20.110.30.194",
        "error_info":"ERRORINFO_NO_ERROR",
        "contentType":"application/json"
    }
}

对于应用程序网关 Standard 和 WAF SKU (v1)

说明
instanceId 处理请求的应用程序网关实例。
clientIP 请求的起始 IP。
clientPort 请求的起始端口。
httpMethod 请求所用的 HTTP 方法。
requestUri 所收到请求的 URI。
RequestQuery 服务器路由:将请求发送到的后端池实例。
X-AzureApplicationGateway-LOG-ID:用于请求的相关 ID。 它可用于排查后端服务器上的流量问题。
SERVER-STATUS:应用程序网关从后端接收的 HTTP 响应代码
UserAgent HTTP 请求标头中的用户代理。
httpStatus 从应用程序网关返回到客户端的 HTTP 状态代码。
httpVersion 请求的 HTTP 版本。
receivedBytes 接收的数据包的大小(以字节为单位)。
sentBytes 发送的数据包的大小(以字节为单位)。
timeTaken 处理请求并发送响应所需的时长(以毫秒为单位)。 此时长按特定的时间间隔(从应用程序网关接收第一个 HTTP 请求字节到完成响应发送操作所需的时间)来计算。 必须注意,“所用时间”字段通常包括请求和响应数据包在网络上传输的时间。
sslEnabled 与后端池的通信是否使用了 TLS/SSL。 有效值为 on 和 off。
host 向后端服务器发送请求时所针对的主机名。 如果正在重写后端主机名,则此名称将反映该主机名。
originalHost 应用程序网关从客户端接收请求时所针对的主机名。
{
    "resourceId": "/SUBSCRIPTIONS/{subscriptionId}/RESOURCEGROUPS/PEERINGTEST/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/{applicationGatewayName}",
    "operationName": "ApplicationGatewayAccess",
    "time": "2017-04-26T19:27:38Z",
    "category": "ApplicationGatewayAccessLog",
    "properties": {
        "instanceId": "ApplicationGatewayRole_IN_0",
        "clientIP": "191.96.249.97",
        "clientPort": 46886,
        "httpMethod": "GET",
        "requestUri": "/phpmyadmin/scripts/setup.php",
        "requestQuery": "X-AzureApplicationGateway-CACHE-HIT=0&SERVER-ROUTED=10.4.0.4&X-AzureApplicationGateway-LOG-ID=874f1f0f-6807-41c9-b7bc-f3cfa74aa0b1&SERVER-STATUS=404",
        "userAgent": "-",
        "httpStatus": 404,
        "httpVersion": "HTTP/1.0",
        "receivedBytes": 65,
        "sentBytes": 553,
        "timeTaken": 205,
        "sslEnabled": "off",
        "host": "www.contoso.com",
        "originalHost": "www.contoso.com"
    }
}

错误代码信息

如果应用程序网关无法完成请求,则其会将以下原因代码之一存储在访问日志的 error_info 字段中。

4XX 错误 (4xx 错误代码指示客户端请求出现问题,应用程序网关无法满足该请求。)
ERRORINFO_INVALID_METHOD 客户发送的请求不符合 RFC 标准。 可能的原因:客户端使用服务器不支持的 HTTP 方法、拼写错误的方法、不兼容的 HTTP 协议版本等。
ERRORINFO_INVALID_REQUEST 由于语法不正确,服务器无法满足请求。
ERRORINFO_INVALID_VERSION 应用程序网关收到包含无效或不受支持的 HTTP 版本的请求。
ERRORINFO_INVALID_09_METHOD 客户端使用 HTTP 协议版本 0.9 发送请求。
ERRORINFO_INVALID_HOST “Host”标头中提供的值缺失、格式不正确或者与预期的 host 值不匹配。 例如,没有基本侦听器,并且多站点侦听器的所有主机名都不与 host 值匹配。
ERRORINFO_INVALID_CONTENT_LENGTH content-Length 标头中客户端指定的内容长度与请求中内容的实际长度不匹配。
ERRORINFO_INVALID_METHOD_TRACE 客户端发送了应用程序网关不支持的 HTTP TRACE 方法。
ERRORINFO_CLIENT_CLOSED_REQUEST 客户端在空闲超时期限过去之前关闭了与应用程序网关的连接。 检查客户端超时期限是否大于应用程序网关的空闲超时期限
ERRORINFO_REQUEST_URI_INVALID 指示客户端请求中提供的统一资源标识符 (URI) 出现问题。
ERRORINFO_HTTP_NO_HOST_HEADER 客户端发送的请求没有主机头。
ERRORINFO_HTTP_TO_HTTPS_PORT 客户端向 HTTPS 端口发送了纯 HTTP 请求。
ERRORINFO_HTTPS_NO_CERT 指示客户端未在相互 TLS 身份验证期间发送正确配置的有效 TLS 证书。
5XX 错误 说明
ERRORINFO_UPSTREAM_NO_LIVE 应用程序网关找不到任何活动或可访问的后端服务器来处理传入请求
ERRORINFO_UPSTREAM_CLOSED_CONNECTION 后端服务器意外或在请求完全处理完毕之前关闭了连接。 出现这种情况的原因可能是后端服务器达到了限制或崩溃等。
ERRORINFO_UPSTREAM_TIMED_OUT 与服务器建立的 TCP 连接已关闭,因为连接花费的时间超过了配置的超时值。

性能日志

只有在每个应用程序网关实例上启用了性能日志,才会生成此日志,如上述步骤所示。 数据存储在启用日志记录时指定的存储帐户中。 每隔 1 分钟生成性能日志数据。 这仅适用于 v1 SKU。 对于 v2 SKU,请对性能数据使用指标。 将记录以下数据:

说明
instanceId 正在为其生成性能数据的应用程序网关实例。 对于多实例应用程序网关,每个实例有一行数据。
healthyHostCount 后端池中运行正常的主机数。
unHealthyHostCount 后端池中运行不正常的主机数。
requestCount 服务的请求数。
latency 从实例到请求服务后端的请求的平均延迟(以毫秒为单位)。
failedRequestCount 失败的请求数。
throughput 自最后一个日志后的平均吞吐量,以每秒字节数为单位。
{
    "resourceId": "/SUBSCRIPTIONS/{subscriptionId}/RESOURCEGROUPS/{resourceGroupName}/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/{applicationGatewayName}",
    "operationName": "ApplicationGatewayPerformance",
    "time": "2016-04-09T00:00:00Z",
    "category": "ApplicationGatewayPerformanceLog",
    "properties":
    {
        "instanceId":"ApplicationGatewayRole_IN_1",
        "healthyHostCount":"4",
        "unHealthyHostCount":"0",
        "requestCount":"185",
        "latency":"0",
        "failedRequestCount":"0",
        "throughput":"119427"
    }
}

注意

延迟时间的计算是从接收到 HTTP 请求的第一个字节开始,到发出 HTTP 响应的最后一个字节为止。 它是应用程序网关处理时间加上后端的网络耗时,再加上后端处理请求所花费的时间之和。

防火墙日志

只有按照上述步骤为每个应用程序网关启用了防火墙日志,才会生成该日志。 此日志还需要在应用程序网关上配置 Web 应用程序防火墙。 数据存储在启用日志记录时指定的存储帐户中。 将记录以下数据:

说明
instanceId 为其生成了防火墙数据的应用程序网关实例。 对于多实例应用程序网关,每个实例有一行数据。
clientIp 请求的起始 IP。
clientPort 请求的起始端口。
requestUri 所收到请求的 URI。
ruleSetType 规则集类型。 可用值为 OWASP。
ruleSetVersion 所使用的规则集版本。 可用值为 2.2.9 和 3.0。
ruleId 触发事件的规则 ID。
message 触发事件的用户友好消息。 详细信息部分提供了更多详细信息。
action 针对请求执行的操作。 可用值为“已阻止”或“已允许”(对于自定义规则),“匹配”(当规则匹配请求的一部分时)和“已检测”和“已阻止”(两者均用于强制规则,具体取决于 WAF 是处于检测模式还是防护模式)。
site 为其生成日志的站点。 目前仅列出 Global,因为规则是全局性的。
详细信息 触发事件的详细信息。
details.message 规则的说明。
details.data 在请求中找到的与规则匹配的特定数据。
details.file 包含规则的配置文件。
details.line 配置文件中触发了事件的行号。
hostname 应用程序网关的主机名或 IP 地址。
transactionId 给定事务的唯一 ID,它有助于对同一请求中发生的多个违反规则的情况进行分组。
{
    "timeStamp": "2021-10-14T22:17:11+00:00",
    "resourceId": "/SUBSCRIPTIONS/{subscriptionId}/RESOURCEGROUPS/{resourceGroupName}/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/{applicationGatewayName}",
    "operationName": "ApplicationGatewayFirewall",
    "category": "ApplicationGatewayFirewallLog",
    "properties": {
        "instanceId": "appgw_2",
        "clientIp": "185.42.129.24",
        "clientPort": "",
        "requestUri": "\/",
        "ruleSetType": "OWASP_CRS",
        "ruleSetVersion": "3.0.0",
        "ruleId": "920350",
        "message": "Host header is a numeric IP address",
        "action": "Matched",
        "site": "Global",
        "details": {
            "message": "Warning. Pattern match \\\"^[\\\\d.:]+$\\\" at REQUEST_HEADERS:Host .... ",
            "data": "20.110.30.194:80",
            "file": "rules\/REQUEST-920-PROTOCOL-ENFORCEMENT.conf",
            "line": "791"
        },
        "hostname": "20.110.30.194:80",
        "transactionId": "592d1649f75a8d480a3c4dc6a975309d",
        "policyId": "default",
        "policyScope": "Global",
        "policyScopeName": "Global"
    }
}

查看和分析活动日志

可使用以下任意方法查看和分析活动日志数据:

查看并分析访问、性能和防火墙日志

Azure Monitor 日志可从 Blob 存储帐户收集计数器和事件日志文件。 它含有可视化和强大的搜索功能,可用于分析日志。

还可以连接到存储帐户并检索访问和性能日志的 JSON 日志条目。 下载 JSON 文件后,可以将其转换为 CSV 并在 Excel、Power BI 或任何其他数据可视化工具中查看。

提示

如果你熟悉 Visual Studio 和更改 C# 中的常量和变量值的基本概念,则可以使用 GitHub 提供的日志转换器工具

通过 GoAccess 分析访问日志

我们发布了一个资源管理器模板,用于安装和运行应用程序网关访问日志的常用 GoAccess 日志分析器。 GoAccess 提供了宝贵的 HTTP 流量统计信息,例如唯一访问者、请求的文件、主机、操作系统、浏览器和 HTTP 状态代码等。 有关更多详细信息,请参阅 GitHub 的资源管理器模板文件夹中的自述文件

后续步骤