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

许多应用程序将信息记录到文本或 JSON 文件,而不是标准日志记录服务(如 Windows 事件日志或 Syslog)。 本文介绍如何通过创建数据收集规则 (DCR),使用 Azure Monitor 代理从受监视计算机上的文本和 JSON 文件收集日志数据。

注意

JSON 引入目前为预览版。

先决条件

如果要完成此过程,需要:

  • Log Analytics 工作区,你在其中至少拥有参与者权限

  • 一个或两个数据收集终结点,具体取决于虚拟机和 Log Analytics 工作区是否位于同一区域。

    有关详细信息,请参阅如何根据部署设置数据收集终结点

  • 在工作区中创建数据收集规则对象的权限

  • 将日志写入文本或 JSON 文件的虚拟机、虚拟机规模集、已启用 Arc 的本地服务器或者 Windows 本地客户端上的 Azure Monitoring Agent。

    文本和 JSON 文件要求和最佳做法:

    • 请将文件存储在运行 Azure Monitor 代理的计算机的本地驱动器上以及正在监视的目录中。
    • 请用行尾划定记录的结尾。
    • 请使用 ASCII 或 UTF-8 编码。 不支持其他格式,如 UTF-16。
    • 请每天创建一个新的日志文件,以便可以轻松删除旧文件。
    • 请清除受监视目录中的所有日志文件。 跟踪过多日志文件可能会提高代理 CPU 和内存使用率。 请至少等待 2 天,以便有足够的时间处理所有日志。
    • 请勿使用新记录覆盖现有文件。 你应该仅将新记录追加到文件的末尾。 覆盖将导致数据丢失。
    • 请勿先将文件重命名为新名称,然后再打开具有相同名称的新文件。 这可能会导致数据丢失。
    • 请勿重命名与文件扫描模式匹配的大型日志文件或将其复制到受监视的目录。 如果必须这样做,则每分钟不得超过 50MB。
    • 请勿将与文件扫描模式匹配的文件重命名为同样与文件扫描模式匹配的新名称。 这将导致引入重复数据。

创建自定义表

在脚本中创建的表有两列:

  • TimeGenerated(日期/时间)
  • RawData(字符串)

这是从文本和 JSON 文件收集的日志数据的默认表架构。 如果知道最终架构,则可以在创建表之前在脚本中添加列。 如果没有,则可以使用 Log Analytics 表 UI 添加列

要进行 REST 调用,最简单方法是从 Azure 云 PowerShell 命令行 (CLI)。

将此脚本复制并粘贴到 PowerShell 中,以在工作区中创建表:

$tableParams = @'
{
    "properties": {
        "schema": {
               "name": "{TableName}_CL",
               "columns": [
        {
                                "name": "TimeGenerated",
                                "type": "DateTime"
                        }, 
                       {
                                "name": "RawData",
                                "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

应会收到 200 个响应并看到刚刚创建的表的详细信息。

注意

列名区分大小写。 例如,Rawdata 无法正确收集事件数据。 它必须是 RawData

创建数据收集规则以从文本或 JSON 文件收集数据

数据收集规则定义:

  • Azure Monitor 代理扫描哪些源日志文件以查找新事件。
  • Azure Monitor 如何在引入期间转换事件。
  • Azure Monitor 将数据发送到的目标 Log Analytics 工作区和表。

可以定义数据收集规则,以将数据从多台计算机发送到多个 Log Analytics 工作区,包括不同区域或租户中的工作区。 在 Log Analytics 工作区所在的同一区域中创建数据收集规则。

注意

若要跨租户发送数据,必须先启用 Azure Lighthouse

若要在 Azure 门户中创建数据收集规则,请执行以下操作:

  1. 在的“监视”菜单中,选择“数据收集规则”。

  2. 选择“创建”,创建新的数据收集规则和关联。

    显示“数据收集规则”屏幕上的“创建”按钮的屏幕截图。

  3. 输入规则名称,并指定订阅、资源组、区域、平台类型和数据收集终结点:

    • “区域”指定将在其中创建 DCR 的位置。 虚拟机及其关联可以处于租户中的任何订阅或资源组中。
    • “平台类型”指定此规则可应用到的资源类型。 “自定义”选项允许 Windows 和 Linux 两种类型。
    • 数据收集终结点”指定 Azure Monitor 代理向其发送收集的数据的数据收集终结点。 此数据收集终结点必须与 Log Analytics 工作区位于同一区域。 有关详细信息,请参阅如何根据部署设置数据收集终结点

    显示“数据收集规则”屏幕的“基本信息”选项卡的屏幕截图。

  4. 在“资源”选项卡上:

    1. 选择“+ 添加资源”并将资源关联到数据收集规则。 资源可以是虚拟机、虚拟机规模集和 Azure Arc for servers。 Azure 门户将在尚未安装 Azure Monitor 代理的资源上安装 Azure Monitor 代理。

      重要

      门户可以在目标资源上启用系统分配的托管标识,还包括现有的用户分配的标识(如有)。 对于现有应用程序,除非在请求中指定用户分配的标识,否则计算机将默认使用系统分配的标识。

    2. 选择“启用数据收集终结点”。

    3. 为与数据收集规则关联的每个虚拟机选择数据收集终结点。

      此数据收集终结点将配置文件发送到虚拟机,并且必须与虚拟机位于同一区域。 有关详细信息,请参阅如何根据部署设置数据收集终结点

    显示“数据收集规则”屏幕的“资源”选项卡的屏幕截图。

  5. 在“收集和传递”选项卡上,选择“添加数据源”以添加数据源并设置目标。

  6. 从“数据源类型”下拉列表中,选择“自定义文本日志”或“JSON 日志”。

  7. 指定下列信息:

    • 文件模式 - 确定日志文件在本地磁盘上的位置。 可以输入以逗号分隔的多个文件模式(在 Linux 上,需要使用 AMA 版本 1.26 或更高版本从以逗号分隔的文件模式列表中进行收集)。

      有效输入的示例:

      • 20220122-MyLog.txt
      • ProcessA_MyLog.txt
      • ErrorsOnly_MyLog.txt, WarningOnly_MyLog.txt

      注意

      同一目录中通常存在多个相同类型的日志文件。 例如,计算机可能会每天创建一个新文件,以防止日志文件变得过大。 若要在此方案中收集日志数据,可以使用文件通配符。 对于 Windows,使用格式 C:\directoryA\directoryB\*MyLog.txt,对于 Linux,使用 /var/*.log。 不支持目录通配符。

    • 表名称 - 在 Log Analytics 工作区中创建的目标表的名称。 有关详细信息,请参阅创建自定义表

    • 记录分隔符 - 将来将用于允许除当前支持的行尾 (/r/n) 之外的分隔符。

    • 转换 - 添加引入时间转换,如果不需要转换收集的数据,则保留为源。

  8. 在“目标”选项卡上,为数据源添加一个或多个目标。 你可以选择多个相同或不同类型的目标。 例如,你可以选择多个 Log Analytics 工作区,这也称为多宿主。

    显示 Azure 门户中数据收集规则的“添加数据源”屏幕的“目标”选项卡的屏幕截图。

  9. 选择“查看 + 创建”,查看数据收集规则的详细信息以及与虚拟机集的关联。

  10. 选择“创建”,创建数据收集规则。

注意

创建数据收集规则后,可能需要最多 5 分钟的时间来将数据发送到目标。

示例日志查询

此处使用的列名仅用作示例。 你的日志的列名很可能不同。

  • 通过代码统计事件的数量。

    MyApp_CL
    | summarize count() by code
    

警报规则示例

  • 对任何错误事件创建警报规则。

    MyApp_CL
    | where status == "Error"
    | summarize AggregatedValue = count() by Computer, bin(TimeGenerated, 15m)
    

疑难解答

使用以下步骤排查从文本和 JSON 文件中收集日志的问题。

使用 Azure Monitor 代理疑难解答

使用 Azure Monitor 代理疑难解答查找常见问题并与 Azure 共享结果。

检查是否已将数据引入自定义表

首先,通过在 Log Analytics 中运行以下查询来检查是否有任何记录已引入到自定义日志表:

<YourCustomTable>_CL
| where TimeGenerated > ago(48h)
| order by TimeGenerated desc

如果未返回任何记录,请查看其他部分以了解可能的原因。 此查询将查找过去两天的条目,但你也可修改为其他时间范围。 新数据可能需要 5-7 分钟才能显示在表中。 在将数据收集规则与虚拟机相关联后,Azure Monitor 代理仅收集写入文本或 JSON 文件的数据。

验证是否创建了自定义表

必须先在 Log Analytics 工作区中创建自定义日志表,然后才能向其发送数据。

验证代理是否成功发送了检测信号

验证 Azure Monitor 代理是否正常通信,方法是在 Log Analytics 中运行以下查询,以检查检测信号表中是否有任何记录。

Heartbeat
| where TimeGenerated > ago(24h)
| where Computer has "<computer name>"
| project TimeGenerated, Category, Version
| order by TimeGenerated desc

验证是否在数据收集规则中指定了正确的日志位置

数据收集规则包含如下所示的节。 filePatterns 元素指定要从代理计算机收集的日志文件的路径。 检查代理计算机以验证此设置是否正确。

"dataSources": [{
            "configuration": {
                "filePatterns": ["C:\\JavaLogs\\*.log"],
                "format": "text",
                "settings": {
                    "text": {
                        "recordStartTimestampFormat": "yyyy-MM-ddTHH:mm:ssK"
                    }
                }
            },
            "id": "myTabularLogDataSource",
            "kind": "logFile",
            "streams": [{
                    "stream": "Custom-TabularData-ABC"
                }
            ],
            "sendToChannels": ["gigl-dce-00000000000000000000000000000000"]
        }
    ]

此文件模式应与代理计算机上的日志相对应。

代理计算机上的文本日志文件的屏幕截图。

验证是否填充了日志

代理仅收集写入到日志文件(正在收集该文件)的新内容。 如果要试验从文本或 JSON 文件收集日志,可使用以下脚本生成示例日志。

# This script writes a new log entry at the specified interval indefinitely.
# Usage:
# .\GenerateCustomLogs.ps1 [interval to sleep]
#
# Press Ctrl+C to terminate script.
#
# Example:
# .\ GenerateCustomLogs.ps1 5

param (
    [Parameter(Mandatory=$true)][int]$sleepSeconds
)

$logFolder = "c:\\JavaLogs"
if (!(Test-Path -Path $logFolder))
{
    mkdir $logFolder
}

$logFileName = "TestLog-$(Get-Date -format yyyyMMddhhmm).log"
do
{
    $count++
    $randomContent = New-Guid
    $logRecord = "$(Get-Date -format s)Z Record number $count with random content $randomContent"
    $logRecord | Out-File "$logFolder\\$logFileName" -Encoding utf8 -Append
    Start-Sleep $sleepSeconds
}
while ($true)

后续步骤

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