使用 Azure Monitor 代理从 JSON 文件收集日志

自定义 JSON 日志是数据收集规则 (DCR) 中使用的数据源之一。 有关创建 DCR 的详细信息,请参阅使用 Azure Monitor 代理收集数据。 本文提供有关文本和 JSON 日志类型的其他详细信息。

许多应用程序和服务将信息记录到 JSON 文件,而不是标准日志记录服务(例如 Windows 事件日志或 Syslog)。 可以使用 Azure Monitor 代理收集此数据,并将其存储在 Log Analytics 工作区中,其中包含从其他源收集的数据。

先决条件

基本操作

下图显示了从 json 文件收集日志数据的基本操作。

  1. 该代理监视与本地磁盘上的指定名称模式匹配的任何日志文件。
  2. 将收集日志中的每个条目并将其发送到 Azure Monitor。 用户定义的传入流用于将日志数据解析为列。
  3. 如果传入流的架构与目标表的架构匹配,则使用默认转换。

屏幕截图显示日志查询返回逗号分隔的文件收集结果。

JSON 文件要求和最佳做法

Azure Monitor 代理所监视的文件必须满足以下要求:

  • 文件必须存储在运行 Azure Monitor 代理的计算机本地驱动器上所监视的目录中。
  • 每条记录都必须具有行尾符。
  • 文件必须使用 ASCII 或 UTF-8 编码。 不支持其他格式,如 UTF-16。
  • 新记录应附加到文件末尾,而不是覆盖旧记录。 覆盖将导致数据丢失。
  • JSON 文本必须包含在一行中。 不支持 JSON 正文格式。 请查看以下示例。

遵循以下建议,确保不会遇到数据丢失或性能问题:

  • 每天创建一个新的日志文件,以便可以轻松清理旧文件。
  • 持续清理受监视目录中的日志文件。 跟踪过多日志文件可能会提高代理 CPU 和内存使用率。 请至少等待 2 天,以便有足够的时间处理所有日志。
  • 请勿将与文件扫描模式匹配的文件重命名为同样与文件扫描模式匹配的其他名称。 这将导致引入重复数据。
  • 请勿重命名与文件扫描模式匹配的大型日志文件或将其复制到受监视的目录。 如果必须这样做,则每分钟不得超过 50MB。

自定义表

在从 JSON 文件收集日志数据之前,必须在 Log Analytics 工作区中创建一个自定义表来接收数据。 表架构必须与传入流中的列匹配,或者必须添加转换,以确保输出架构与表匹配。

警告

不应使用 Log Analytics 代理使用的现有自定义表。 一旦第一个 Azure Monitor 代理写入表,旧代理将无法写入该表。 为 Azure Monitor 代理创建新表,用于防止 Log Analytics 代理数据丢失。

例如,可以使用以下 PowerShell 脚本来创建包含多个列的自定义表。

$tableParams = @'
{
    "properties": {
        "schema": {
               "name": "{TableName}_CL",
               "columns": [
                    {
                        "name": "TimeGenerated",
                        "type": "DateTime"
                    }, 
                    {
                        "name": "MyStringColumn",
                        "type": "string"
                    },
                    {
                        "name": "MyIntegerColumn",
                        "type": "int"
                    },
                    {
                        "name": "MyRealColumn",
                        "type": "real"
                    },
                    {
                        "name": "MyBooleanColumn",
                        "type": "bool"
                    },
                    {
                        "name": "FilePath",
                        "type": "string"
                    },
                    {
                        "name": "Computer",
                        "type": "string"
                    }
              ]
        }
    }
}
'@

Invoke-AzRestMethod -Path "/subscriptions/{subscription}/resourcegroups/{resourcegroup}/providers/microsoft.operationalinsights/workspaces/{WorkspaceName}/tables/{TableName}_CL?api-version=2021-12-01-preview" -Method PUT -payload $tableParams

为 JSON 文件创建数据收集规则

注意

基于代理的 JSON 自定义文件引入目前为预览版,在门户中尚未提供完整的 UI 体验。 虽然可以使用门户创建 DCR,但必须对其进行修改以定义传入流中的列。 本部分包含有关如何使用 ARM 模板创建 DCR 的详细信息。

传入流架构

注意

预计 2024 年 10 月中旬将推出多行支持,届时可以将 ISO 8601 时间戳用于分隔事件

JSON 文件包含每个值的属性名称,并且 DCR 中的传入流需要包含与每个属性名称匹配的列。 需要使用日志中的列修改 ARM 模板的 columns 部分。

下表介绍了除了定义日志文件中的数据的列之外,还可以包括的可选列。

类型​​ 说明
TimeGenerated datetime 生成记录的时间。 如果记录未包含在传入流中,则此值将自动填充为记录添加到 Log Analytics 工作区的时间。
FilePath string 如果将此列添加到 DCR 中的传入流,则会使用日志文件的路径进行填充。 此列不是自动创建的,无法使用门户进行添加。 必须手动修改门户创建的 DCR,或使用另一种可以显式定义传入流的方法来创建 DCR。
Computer string 如果将此列添加到 DCR 中的传入流,则会通过日志文件使用计算机的名称填充它。 此列不是自动创建的,无法使用门户进行添加。 必须手动修改门户创建的 DCR,或使用另一种可以显式定义传入流的方法来创建 DCR。

转换

转换可能会修改传入流以筛选记录,或修改架构以匹配目标表。 如果传入流的架构与目标表的相同,则可以使用 source 的默认转换。 否则,请使用返回所需架构的 KQL 查询修改 ARM 模板的 transformKql 部分。

ARM 模板

使用以下 ARM 模板创建用于收集文本日志文件的 DCR,并做出前面部分中所述的更改。 下表描述了在部署模板时需要值的参数。

设置 说明
数据收集规则名称 DCR 的唯一名称。
数据收集终结点资源 ID 数据收集终结点 (DCE) 的资源 ID。
位置 DCR 的区域。 必须与 Log Analytics 工作区位于同一位置。
文件模式 标识本地磁盘上日志文件的位置和名称。 对不同的文件名使用通配符,例如每天用新名称创建新文件时。 可以输入多个以逗号分隔的文件模式(Linux 上的多个文件模式需要 AMA 1.26 或更高版本)。

示例:
- C:\Logs\MyLog.json
- C:\Logs\MyLog*.json
- C:\App01\AppLog.json, C:\App02\AppLog.json
- /var/mylog.json
- /var/mylog*.json
表名 Log Analytics 工作区中目标表的名称。
工作区资源 ID 具有目标表的 Log Analytics 工作区的资源 ID。

重要

使用 ARM 模板创建 DCR 时,仍必须将 DCR 与要使用它的代理相关联。 可以在 Azure 门户中编辑 DCR,然后选择代理,如添加资源中所述

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "dataCollectionRuleName": {
            "type": "string",
            "metadata": {
                "description": "Unique name for the DCR. "
            }
        },
        "dataCollectionEndpointResourceId": {
            "type": "string",
            "metadata": {
              "description": "Resource ID of the data collection endpoint (DCE)."
            }
        },
        "location": {
            "type": "string",
            "metadata": {
                "description": "Region for the DCR. Must be the same location as the Log Analytics workspace. "
            }
        },
        "filePatterns": {
            "type": "string",
            "metadata": {
                "description": "Path on the local disk for the log file to collect. May include wildcards.Enter multiple file patterns separated by commas (AMA version 1.26 or higher required for multiple file patterns on Linux)."
            }
        },
        "tableName": {
            "type": "string",
            "metadata": {
                "description": "Name of destination table in your Log Analytics workspace. "
            }
        },
        "workspaceResourceId": {
            "type": "string",
            "metadata": {
                "description": "Resource ID of the Log Analytics workspace with the target table."
            }
        }
    },
    "variables": {
        "tableOutputStream": "[concat('Custom-', parameters('tableName'))]"
    },
    "resources": [
        {
            "type": "Microsoft.Insights/dataCollectionRules",
            "apiVersion": "2022-06-01",
            "name": "[parameters('dataCollectionRuleName')]",
            "location": "[parameters('location')]",
            "properties": {
                "dataCollectionEndpointId": "[parameters('dataCollectionEndpointResourceId')]",
                "streamDeclarations": {
                    "Custom-Json-stream": {
                        "columns": [
                            {
                                "name": "TimeGenerated",
                                "type": "datetime"
                            },
                            {
                                "name": "FilePath",
                                "type": "string"
                            },
                            {
                                "name": "MyStringColumn",
                                "type": "string"
                            },
                            {
                                "name": "MyIntegerColumn",
                                "type": "int"
                            },
                            {
                                "name": "MyRealColumn",
                                "type": "real"
                            },
                            {
                                "name": "MyBooleanColumn",
                                "type": "boolean"
                            }
                        ]
                    }
                },
                "dataSources": {
                    "logFiles": [
                        {
                            "streams": [
                                "Custom-Json-stream"
                            ],
                            "filePatterns": [
                                "[parameters('filePatterns')]"
                            ],
                            "format": "json",
                            "name": "Custom-Json-stream"
                        }
                    ]
                },
                "destinations": {
                    "logAnalytics": [
                        {
                            "workspaceResourceId": "[parameters('workspaceResourceId')]",
                            "name": "workspace"
                        }
                    ]
                },
                "dataFlows": [
                    {
                        "streams": [
                            "Custom-Json-stream"
                        ],
                        "destinations": [
                            "workspace"
                        ],
                        "transformKql": "source",
                        "outputStream": "[variables('tableOutputStream')]"
                    }
                ]
            }
        }
    ]
}

故障排除

如果没有从预期的 JSON 日志中收集到数据,请执行以下步骤。

  • 验证数据是否正在写入到所收集的日志文件。
  • 验证日志文件的名称和位置是否与指定的文件模式匹配。
  • 验证 DCR 中传入流的架构是否与日志文件中的架构匹配。
  • 验证目标表的架构是否与传入流匹配,或者你是否具有将传入流转换为正确架构的转换。
  • 请参阅验证操作,以验证代理是否正在运行,以及是否正在接收数据。

后续步骤

了解有关以下方面的详细信息: