2022 Zabbix中国峰会
2022 Zabbix中国峰会

#6 日志文件监控

概述

Zabbix 可用于有/无日志轮询支持的日志文件的集中监控和分析。

当日志文件包含某些字符串或字符串模式时,可以使用通知来警告用户。

要监控日志文件,必须具有如下:

  • 主机上已运行Zabbix agent
  • 设置日志监控项

被监控日志文件的大小限制取决于大文件支持

配置

验证agent 参数

确保在 agent 配置文件 中已设置:

  • 'Hostname'参数与前端的主机名一致
  • 'ServerActive'参数中的服务器被指定用于处理主动检查
监控项配置

配置日志监控 item

所有必填输入字段都标有红色星号。

具体来说,对于日志监控监控项,您输入:

类型 在此处选择 Zabbix agent(主动式)
使用以下监控项键之一:
log[]logrt[]
这两个监控项键允许监控日志并通过内容正则表达式(如果存在)过滤日志条目。
例如:log[/var/log/syslog,error]。确保文件对“zabbix”用户具有读取权限,否则监控项状态将设置为“不支持”。
log.count[]logrt.count[]
这两个监控项键仅允许返回匹配行数。
有关使用这些监控项键及其参数的详细信息,请参阅支持的 Zabbix agent 监控项 键部分。
信息类型 自动预填充:
对于 log[] 或 logrt[] 监控项 - Log
对于 log.count[] 或 logrt.count[] 监控项 - Numeric (unsigned)
如果可选地使用 output 参数,您可以手动选择除 Log 之外的适当信息类型。
请注意,选择非日志类型的信息将导致本地时间戳丢失。
更新间隔(秒) 该参数定义 Zabbix agent 检查日志文件中任何更改的频率。将其设置为 1 秒将确保您尽快获得新记录。
日志时间格式 在此字段中,您可以选择指定用于解析日志行时间戳的模式。
如果留空,则不会解析时间戳。
支持的占位符:
* y年 (0001-9999)
* M月 (01-12)
* d日 (01-31)
* h小时 (00-23)
* m分钟 (00-59)
* s秒 (00-59)
例如,请考虑 Zabbix agent 日志文件中的以下行:
“23480:20100328:154718.045 Zabbix agent 已启动。Zabbix 1.8.2(修订版 11211)。”
它以 PID 的六个字符位置开始,然后是日期、时间和其余的行。
此行的日志时间格式为“pppppp:yyyyMMdd:hhmmss”。
请注意,“p”和“:”字符只是占位符,可以是除“yMdhms”之外的任何内容。

重要说明

  • server 和agent 在两个计数器中跟踪受监控日志的大小和上次修改时间(对于 logrt)。此外:
  • agent 还在内部使用 inode 编号(在 UNIX/GNU/Linux 上)、文件索引(在 Microsoft Windows 上)和前 512 个日志文件字节的 MD5 总和,以便在日志文件被截断和轮换时改进决策。
  • 在 UNIX/GNU/Linux 系统上,假定存储日志文件的文件系统报告 inode 编号,这些编号可用于跟踪文件。
  • 在 Microsoft Windows 上,Zabbix agent 确定日志文件所在的文件系统类型并使用:
  • 在 NTFS 文件系统上,使用 64 位文件索​​引。
  • 在 ReFS 文件系统上(仅限 Microsoft Windows Server 2012)使用 128 位文件 ID。
  • 在文件索引发生变化的文件系统(例如 FAT32、exFAT)上,当日志文件轮换导致多个日志文件具有相同的最后修改时间时,将使用回退算法在不确定的情况下采取合理的方法。
  • Inode 编号、文件索引和 MD5 总和由 Zabbix agent 内部收集。它们不会传输到 Zabbix server,并且在 Zabbix agent 停止时会丢失。
  • 不要使用“touch”实用程序修改日志文件的最后修改时间,不要复制日志文件并在以后恢复原始名称(这将更改文件 inode 编号)。 在这两种情况下,文件都将被视为不同文件,并将从一开始就进行分析,这可能会导致重复警报。
  • 如果有多个与 logrt[] 项匹配的日志文件,并且 Zabbix agent 正在跟踪其中最新的日志文件,而这个最新的日志文件被删除,则会记录一条警告消息 “在 "<directory>" 中没有与 "<regexp mask>" 匹配的文件”。Zabbix agent 会忽略修改时间小于agent 看到的用于正在检查的 logrt[] 项的最近修改时间的日志文件。
  • agent 从上次停止的位置开始读取日志文件。
  • 已分析的字节数(大小计数器)和上次修改时间(时间计数器)存储在 Zabbix 数据库中,并发送给agent 以确保agent 从此点开始读取日志文件,以防agent 刚启动或收到之前被禁用或不支持的监控项。但是,如果agent 从服务器收到非零大小计数器,但 logrt[] 或 logrt.count[] 项无法找到匹配的文件,则大小计数器如果文件稍后出现,则将时间 重置为 0,以便从头开始分析。
  • 每当日志文件变得小于agent 已知的日志大小计数器时,计数器将重置为零,并且agent 将时间计数器考虑在内,从头开始读取日志文件。
  • 如果目录中有多个匹配文件具有相同的最后修改时间,则agent 会尝试正确分析所有具有相同修改时间的日志文件,并避免跳过数据或分析相同的数据两次,尽管不能保证在所有情况下都能做到这一点。agent 不会假设任何特定的日志文件轮换方案,也不会确定一个方案。当呈现多个具有相同最后修改时间的日志文件时,agent 将按字典顺序降序处理它们。因此,对于某些轮换方案,日志文件将按其原始顺序进行分析和报告。对于其他轮换方案,将不遵守原始日志文件顺序,这可能导致以改变的顺序报告匹配的日志文件记录(如果日志文件具有不同的最后修改时间,则不会发生此问题)。
  • Zabbix agent 每 更新间隔 秒处理一次日志文件的新记录。
  • Zabbix agent每秒发送的日志文件不超过 maxlines。此限制可防止网络和 CPU 资源过载,并覆盖 agent 配置文件MaxLinesPerSecond 参数提供的默认值。 - 为了找到所需的字符串,Zabbix 将处理比 MaxLinesPerSecond 中设置多 10 倍的新行。因此,例如,如果 log[]logrt[] 监控项的 更新间隔 为 1 秒,则默认情况下,agent 将分析不超过 200 个日志文件记录,并在一次检查中向 Zabbix 服务器发送不超过 20 个匹配记录。通过增加agent 配置文件中的MaxLinesPerSecond 或​​在监控项键中设置 maxlines 参数,限制可以增加到 10000 个分析的日志文件记录和 1000 个匹配的记录在一次检查中发送到 Zabbix 服务器。如果将 更新间隔 设置为 2 秒,则一次检查的限制将比 更新间隔 为 1 秒时高 2 倍。
  • 此外,即使其中没​​有非日志值,log 和 log.count 值也始终限制为agent 发送缓冲区大小的 50%。因此,对于在一个连接中(而不是在多个连接中)发送的 maxlines 值,agent BufferSize 参数必须至少为 maxlines x 2。Zabbix agent可以在日志收集期间上传数据,从而释放缓冲区,而 Zabbix agent2 将停止日志收集,直到数据上传并释放缓冲区,这是异步执行的。
  • 在没有日志项的情况下,所有agent 缓冲区大小都用于非日志值。当日志值进入时,它们会根据需要替换较旧的非日志值,最高可达指定的 50%。
  • 对于长度超过 256kB 的日志文件记录,只有前 256kB 与正则表达式匹配,其余记录将被忽略。但是,如果 Zabbix agent 在处理长记录时停止,agent 内部状态将丢失,并且在agent 重新启动后,可能会再次以不同的方式分析长记录。
  • 关于“\”路径分隔符的特别说明:如果 file_format 为“file\.log”,则不应有“file”目录,因为无法明确定义“.”是转义的还是文件名的第一个符号。
  • 仅在文件名中支持“logrt”的正则表达式,不支持目录正则表达式匹配。
  • 在 UNIX 平台上,如果不存在预期找到日志文件的目录,则“logrt[]”项将变为 NOTSUPPORTED。
  • 在 Microsoft Windows 上,如果目录不存在,则该监控项不会变为 NOTSUPPORTED(例如,如果监控项键中的目录拼写错误)。
  • logrt[] 监控项的日志文件缺失不会使其变为 NOTSUPPORTED。读取 logrt[] 监控项的日志文件的错误将作为警告记录到 Zabbix agent日志文件中,但不会使该监控项变为 NOTSUPPORTED。
  • Zabbix agent 日志文件有助于找出 log[]logrt[] 监控项变为 NOTSUPPORTED 的原因。Zabbix 可以监控其agent 日志文件,但 DebugLevel=4 或 DebugLevel=5 除外。
  • 如果文本文件包含 NUL 符号,则使用正则表达式搜索问号(例如 \?)可能会导致误报,因为 Zabbix 会将这些符号替换为“?”以继续处理该行,直到换行符。

提取正则表达式的匹配部分

有时,我们可能只想从目标文件中提取感兴趣的值,而不是在找到正则表达式匹配时返回整行。

日志项能够从匹配的行中提取所需的值。这是通过 loglogrt 项中的附加 output 参数实现的。

使用“输出”参数可以指示我们可能感兴趣的匹配的“捕获组”。

因此,例如

log[/path/to/the/file,"large result buffer assignment.*Entries: ([0-9]+)",,,,\1]

应允许返回条目计数,如以下内容所示:

Fr Feb 07 2014 11:07:36.6690 */Thread Id 1400 (GLEWF) large result buffer assignment - /Length: 437136/Entries: 5948/Client Ver: >=10/RPC ID: 41726453/User: AUser/Form: CFG:ServiceLevelAgreement

只会返回数字,因为\1 指的是第一个也是唯一的捕获组:([0-9]+).

并且,通过提取和返回数字的能力,该值可以用于定义触发器。

使用maxdelay参数

日志监控项中的“maxdelay”参数允许忽略日志文件中的一些较旧的行,以便在“maxdelay”秒内获取最近分析的行。

指定'maxdelay'>0可能导致忽略重要的日志文件记录和错过的报警,只有在必要时才使用否则后果自负。

默认情况下,日志监控项将跟踪出现在日志文件中的所有新行。 但是,有些应用程序在某些情况下开始在其日志文件中写入大量的消息。例如,如果数据库或DNS服务器不可用,则此类应用程序会向日志文件中注入数千条几乎相同错误消息,直到恢复正常为止。默认情况下,所有这些消息将被完全分析,并将匹配的行发送到配置为loglogrt监控项的服务器上。

内置的过载保护包括一个可配置的“maxlines”参数(保护服务器免受过多传入匹配日志行的影响)和 10*“maxlines”限制(保护主机 CPU 和 I/O 免于agent在一次检查中过载) . 尽管如此,内置保护仍存在两个问题。 首先,大量可能不那么有用的消息被报告给服务器并占用数据库空间。 其次,由于每秒分析的行数有限,agent可能会落后于最新的日志记录数小时。 很可能,您可能更愿意尽快了解日志文件中的当前情况,而不是花几个小时在旧记录中爬行。

这两个问题的解决方案是使用“maxdelay”参数。 如果指定 'maxdelay' > 0,则在每次检查处理的字节数时,测量剩余字节数和处理时间。 agent根据这些数字计算估计的延迟——分析日志文件中所有剩余记录需要多少秒。

如果延迟不超过“maxdelay”,那么agent将像往常一样继续分析日志文件。

如果延迟大于“maxdelay”,那么agent将通过“跳转”到一个新的估计位置来忽略日志文件的一个块,以便在“maxdelay”秒内分析剩下的行。

请注意,agent甚至不会将忽略的行读入缓冲区,而是计算要在文件中跳转的大致位置。

跳过日志文件行的事实记录在agent 日志文件中,如下所示:

14287:20160602:174344.206 item:"logrt["/home/zabbix32/test[0-9].log",ERROR,,1000,,,120.0]"
       logfile:"/home/zabbix32/test1.log" skipping 679858 bytes
       (from byte 75653115 to byte 76332973) to meet maxdelay

“to byte”数字是近似的,因为在“跳转”之后,agent将文件中的位置调整到日志行开头,日志行可能在文件中更远或更早。

根据增长速度与分析日志文件的速度的不同,你可能会看到没有"跳转"、少有或经常"跳转"、大或小的"跳转",甚至每次检查中的"跳转"都很小。系统负载和网络延迟的波动也会影响延迟的计算,因此"跳转"可以跟上“maxdelay”参数。

不推荐设置 'maxdelay' <'update interval'(这可能会导致频繁的"jumps")

处理“copytruncate”日志文件轮换的注意事项

带有copytruncate 选项的logrt假定不同的日志文件有不同的记录(至少它们的时间戳不同),因此初始块的MD5(最多512字节)将不同。两个具有相同的MD5初始块和的文件意味着其中一个是原始块,另一个是副本。

使用copytruncate选项的logrt将努力正确处理日志文件副本,而不报告副本。但是,与logrt[]监控项更新间隔相比,生成具有相同时间戳的多个日志文件副本、日志文件轮询频率更高、不建议频繁重新启动agent。agent试图合理地处理所有这些情况,但是在所有情况下都不能保证良好的结果。

关于 log*[] 监控项的持久文件的注释

I/O负载

每一批数据 (包含监控项的数据)成功发送到服务器后,监控项的持久文件就会更新, 例如, 默认的 'BufferSize'是100。如果一个日志项找到 70 条匹配记录, 那么前 50 条记录将分批发送,持久化文件将被更新,然后剩余 20 条记录将被发送(可能会有一些延迟,更多数据积累) 在第二批中,并且将再次更新持久文件。

agent 与server 之间通信失败时的操作

log[]logrt[] 项中的每一条匹配行以及每个 log.count[]logrt.count[] 项检查的结果都需要agent 发送缓冲区中指定 50% 区域中的空闲插槽。缓冲区元素定期发送到server(或 proxy),缓冲区插槽再次空闲。

当agent 发送缓冲区中指定的日志区域中有空闲插槽并且agent 与server(或proxy)之间的通信失败时,日志监控结果会累积在发送缓冲区中。这有助于缓解短暂的通信故障。

在较长的通信故障期间,所有日志插槽都会被占用,并采取以下操作:

  • log[]logrt[] 项检查停止。当通信恢复并且缓冲区中有空闲插槽时,检查将从之前的位置恢复。没有匹配的行丢失,它们只是稍后报告。
  • 如果maxdelay = 0(默认),则停止log.count[]logrt.count[] 检查。行为类似于上面描述的log[]logrt[] 项。请注意,这可能会影响log.count[]logrt.count[] 结果:例如,一次检查计数日志文件中的 100 个匹配行,但由于缓冲区中没有空闲插槽,因此检查停止。当通信恢复时,agent 会计数相同的 100 个匹配行以及 70 个新的匹配行。agent 现在发送 count = 170,就好像它们是在一次检查中找到的一样。
  • 使用maxdelay > 0log.count[]logrt.count[] 检查:如果检查期间没有“跳跃”,则行为类似于上面描述的。如果发生日志文件行的“跳跃”,则保留“跳跃”之后的位置并丢弃计数结果。因此,即使在通信失败的情况下,agent 也会尝试跟上不断增长的日志文件。

处理正则表达式编译和运行时错误

如果 PCRE 或 PCRE2 库无法编译 log[]logrt[]log.count[]logrt.count[] 项中使用的正则表达式,则该项将进入 NOTSUPPORTED 状态并显示错误消息。要继续监控日志项,应修复正则表达式。

如果正则表达式编译成功,但在运行时失败(在某些或所有日志记录上),则日志项仍受支持并继续监控。运行时错误记录在 Zabbix agent 日志文件中(没有日志文件记录)。

记录率限制为每次检查一个运行时错误,以允许 Zabbix agent 监控其自己的日志文件。 例如,如果分析了 10 条记录,其中 3 条记录因正则表达式运行时错误而失败,则agent 日志中会生成一条记录。

例外:如果 MaxLinesPerSecond=1 且更新间隔=1(每次检查只允许分析 1 条记录),则不会记录正则表达式运行时错误。

zabbix_agentd 在发生运行时错误时记录监控项键,zabbix_agent2 记录监控项 ID 以帮助识别哪个日志监控项有运行时错误。 建议在发生运行时错误时重新设计正则表达式。

持久文件的目的

当 Zabbix agent启动,它会从Zabbix server 或 proxy接收活动检查列表。对于 log*[]指标,它接收处理后的日志大小和修改时间,以查找从哪里开始日志文件监控。根据文件系统报告的实际日志文件大小和修改时间,agent 决定从已处理的日志大小继续监控日志文件还是从头重新分析日志文件。

正在运行的agent 维护大的属性集,用于在检查之间跟踪所有受监视的日志文件。当agent 停止时,这种内存状态会丢失。

新的可选参数 persistent_dir 指定了一个目录,用于在文件中存储log[], log.count[], logrt[] or logrt.count[] 监控项的状态。Zabbix agent重启后,从持久化文件中恢复日志监控项的状态。

主要的用户场景是监控位于镜像文件系统中的日志文件,直到某个时刻,日志文件被写入两个镜像。然后镜像被分割。在活动副本上,日志文件仍在增长,获取新记录。Zabbix agent 对其进行分析并将处理后的日志大小和修改时间发送到服务端。在被动副本上,日志文件保持不变,远远落后于活动副本。稍后操作系统和 Zabbix agent从被动副本重新启动。Zabbix agent从服务器接收到的已处理日志大小和修改时间可能对被动副本的情况无效。要从文件系统镜像拆分时agent 停止的位置继续进行日志文件监控,agent 会从持久文件恢复其状态。

持久文件的agent 操作

在启动时 Zabbix agent 对持久文件一无所知。只有在收到来自 Zabbix server (proxy)的活动检查列表后,agent 才会看到某些日志项应该由指定目录下的持久文件支持。

在agent 操作期间,持久文件被打开以进行写入(使用 fopen(filename, "w"))并用最新数据覆盖。如果同时发生覆盖和文件系统镜像拆分,丢失持久文件数据的机会非常小,无需特殊处理。写入持久文件后不会强制同步到存储介质(不调用 (fsync())。

在成功向 Zabbix server报告匹配的日志文件记录或元数据(处理的日志大小和修改时间)后,使用最新数据覆盖。这可能与每个监控项检查日志文件是否不断变化一样频繁。

agent 关闭期间没有特殊操作。

在收到活动检查列表后,agent 会将过时的持久文件标记为删除。如果出现以下情况,则持久文件将过时:1) 不再监视相应的日志项,2) 使用与以前不同的persistent_dir位置重新配置日志项

删除会延迟 24 小时完成,因为处于 NOTSUPPORTED 状态的日志文件不包含在活动检查列表中,但它们可能会在稍后变为 SUPPORTED,并且它们的持久文件将很有用。

如果agent 在 24 小时到期之前停止,则不会删除过时的文件,因为 Zabbix agent不再从 Zabbix server获取有关其位置的信息。

在agent 停止时,将日志项 persistent_dir 重新配置回旧的 persistent_dir 位置,用户没有删除就的持久文件 - 将导致从旧的持久化文件中恢复agent 状态,从而导致丢失消息或错误告警。

持久文件的命名和位置

Zabbix agent 通过他们的键来区分活动检查。例如:logrt[/home/zabbix/test.log] 和 logrt[/home/zabbix/test.log,] 是不同的监控项。将前端的项logrt[/home/zabbix/test.log,,,10]修改为 logrt[/home/zabbix/test.log,,,20] 会导致 logrt[/home/zabbix/test.log,,,10]项从agent 的主动检查清单中删除并创建logrt[/home/zabbix/test.log,,,20] 监控项 (某些属性在前端/服务器中进行修改,而不是在agent 中)。

文件名由监控项密钥的 MD5 和加上监控项密钥长度组成,以减少冲突的可能性。例如, logrt[/home/zabbix50/test.log,,,,,,,,/home/zabbix50/agent_private] 监控项的状态将保存在持久文件c963ade4008054813bbc0a650bb8e09266中。

多个日志项可以使用相同的值 persistent_dir

persistent_dir 是通过考虑特定文件系统布局、挂载点和挂载选项以及存储镜像配置来指定的 - 持久文件应该与受监控的日志文件位于同一镜像文件系统上。

如果 persistent_dir 目录无法创建或不存在,或者Zabbix agent 的访问权限不允许创建/写入/读取/删除文件,则日志项将变为 NOTSUPPORTED。

如果在agent 操作期间删除了对持久存储文件的访问权限或发生其他错误(例如磁盘已满),则错误将记录到agent 日志文件中,但日志项不会变为 NOTSUPPORTED。