6 日志文件监控

概述

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

当日志file包含特定字符串或string模式时,可通过通知功能向用户发出告警。

监控日志file需满足以下条件:

  • 在主机上运行的Zabbix agent
  • 已配置日志监控监控项

受监控日志file的大小限制取决于large file support

配置

验证 agent 参数

确保在agent configuration file中:

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

配置日志监控 概述

所有必填输入字段均以红色星号标记。

特别针对日志监控 监控项,您需要输入以下内容:

类型 此处选择 Zabbix agent(主动)
键值 使用以下 监控项 键之一:
log[]logrt[]
这两个 监控项 键允许监控日志,并根据内容正则表达式(如果存在)过滤日志条目。
例如:log[/var/log/syslog,error]。请确保 file 对 'zabbix' 用户具有读取权限,否则该 监控项 的状态将被设置为“不支持”。
log.count[]logrt.count[]
这两个 监控项 键仅允许返回匹配行的数量。
有关使用这些 监控项 键及其参数的详细信息,请参见支持的 支持的-监控项-键 键部分。
信息类型 自动预填:
对于 log[] 或 logrt[] 监控项 - Log
对于 log.count[] 或 logrt.count[] 监控项 - Numeric (unsigned)
如果可选地使用 output 参数,您可以手动选择除 Log 以外的适当信息类型。
请注意,选择非日志类型的信息将导致丢失本地时间戳。
更新间隔(秒) 该参数定义了 Zabbix agent 检查日志文件中任何更改的频率。将其设置为 1 秒将确保您能尽快 get 新记录。
日志时间格式 在此字段中,您可以可选地指定用于解析日志行时间戳的模式。支持的占位符:
* y: 年(1970-2038)
* M: 月(01-12)
* d: 日(01-31)
* h: 时(00-23)
* m: 分(00-59)
* s: 秒(00-59)
如果留空,则时间戳将被设置为 Unix 时间中的 0,表示 1970 年 1 月 1 日。
例如,考虑来自 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 系统上)、file 索引(在 Microsoft Windows 系统上)以及日志 file 前 512 字节的 MD5 校验和,以便在日志文件 get 被截断和轮换时优化决策。
    • 在UNIX/GNU/Linux系统上,假定存储日志文件的file系统会报告inode编号,这些编号可用于跟踪文件。
    • 在Microsoft Windows上,Zabbix agent决定了日志文件所在的file系统类型并使用:
      • 在NTFS file系统上使用64位 file索引。
      • 在ReFS file系统上(仅限Microsoft Windows Server 2012及更高版本)使用128位file ID。
      • 在file系统上,当file索引发生变化时(例如FAT32、exFAT),会使用回退算法在不确定条件下采取合理方法处理日志file轮转导致多个日志文件具有相同最后修改时间的情况。
    • inode编号、file索引和MD5校验和由Zabbix agent内部采集。 它们不会被传输到Zabbix server,并且在Zabbix agent停止时会丢失。
    • 不要修改日志file的最后修改时间(例如使用touch),也不要通过将受监控的日志file复制回其原始名称来替换file(这会创建一个新的inode)。 无论哪种情况,Zabbix都可能将file视为不同的file并从头开始重新读取,这可能会产生重复警报。
    • 如果有多个匹配的日志文件用于logrt[] 监控项且Zabbix agent正在跟踪其中最新的日志文件,当这个最新的日志file被删除时,系统会记录一条警告消息"there are no files matching "<regexp mask>" in "<directory>"。 Zabbix agent 会忽略修改时间早于 agent 针对正在检查的 logrt[] 监控项 所记录的最新修改时间的日志文件
  • agent 开始从上次停止的位置继续读取日志 file
  • 已分析的字节数(大小计数器)和最后修改时间(时间计数器)存储在Zabbix数据库中,并发送到agent,以确保在agent刚启动或收到之前被禁用或不支持的监控项时,agent从该点开始读取日志file。 然而,如果agent已从服务器接收到非零大小的计数器,但logrt[]或logrt.count[]监控项无法找到匹配的文件,则会将大小计数器重置为0,以便在文件稍后出现时从头开始分析。
  • 当日志file的大小小于agent已知的日志大小计数器时,计数器将被重置为零,且agent会从日志file的开头开始读取,同时考虑时间计数器。
  • 如果目录中存在多个具有相同最后修改时间的匹配文件,agent会尝试正确分析所有具有相同修改时间的日志文件,避免数据遗漏或重复分析,尽管无法在所有情况下保证这一点。 agent 不假定任何特定的日志 file 轮转方案,也不会自行确定一个方案。 当多个日志文件的最后修改时间相同时,agent 将按字典序降序处理它们。 因此,对于某些轮转方案,日志文件将按其原始顺序进行分析和报告。 对于其他轮换方案,原始日志file的顺序将不会被保留,这可能导致报告匹配的日志file记录以变更后的顺序呈现(如果日志文件的最后修改时间不同,则不会发生此问题)。
  • Zabbix agent 每隔 更新间隔 秒处理一次日志 file 的新记录。
  • Zabbix agent 每秒发送的日志file不超过maxlines行. 该限制可防止网络和CPU资源过载,并覆盖agent configuration fileMaxLinesPerSecond参数提供的默认值。
  • 为了找到所需的string,Zabbix将处理比MaxLinesPerSecond设置多10倍的新行。 因此,例如,如果log[]logrt[] 监控项的更新间隔为1秒,默认情况下agent将分析不超过200条日志file记录,并且在一次检查中向Zabbix server发送不超过20条匹配记录。 通过增加agent配置file中的MaxLinesPerSecond参数 或 在监控项键中设置maxlines参数 可将限制提升至每次检查分析10000条日志file记录 并向Zabbix server发送1000条匹配记录 如果更新间隔设置为2秒,则单次检查的限制将比更新间隔为1秒时高出2倍。
  • 此外,即使缓冲区中没有非日志值,log和log.count的值也始终限制为agent发送缓冲区大小的50%。 因此,为了使maxlines值在一个连接中发送(而不是在多个连接中发送),agent BufferSize参数必须至少为maxlines x 2。 Zabbix agent 可以在日志收集过程中上传数据从而释放缓冲区,而 Zabbix agent 2 会停止日志收集直到数据上传完成且缓冲区被释放,这一过程是异步执行的。
  • 当缺少日志监控项时,所有agent缓冲区大小将用于非日志值。 当日志值传入时,它们会根据需要替换较旧的非日志值,直至达到指定的50%容量。
  • 对于超过256kB的日志file记录,仅前256kB会与正则表达式进行匹配,记录的其余部分将被忽略。 然而,如果Zabbix agent在处理长记录时停止,agent的内部状态将丢失,且在agent重新启动后,该长记录可能会被再次且以不同方式分析。
  • 关于"\"路径分隔符的特殊说明:如果file_format的值为"file\.log",则不应存在"file"目录,因为无法明确界定"."是被转义的字符还是file名称的首字母。
  • 文件名支持logrt的正则表达式匹配,但不支持目录的正则表达式匹配。
  • 在UNIX平台上,如果预期存放日志文件的目录不存在,logrt[] 监控项会变为NOTSUPPORTED。
  • 在Microsoft Windows上,如果目录不存在,监控项不会变为NOTSUPPORTED(例如,当目录在监控项键中被拼写错误时)。
  • 缺少logrt[] 监控项的日志文件并不会使其变为NOTSUPPORTED状态 读取logrt[] 监控项日志文件的错误会被记录为警告到Zabbix agent日志file中,但不会导致监控项变为NOTSUPPORTED状态。
  • Zabbix agent 日志 file 有助于查明为何 log[]logrt[] 监控项 变为 NOTSUPPORTED 状态. Zabbix可以监控其agent日志file,除非处于DebugLevel=4或DebugLevel=5级别时除外。
  • 使用正则表达式搜索问号时,例如\?,如果文本file包含NUL符号,则可能导致误报,因为这些符号会被Zabbix替换为"?"以继续处理该行直到换行符。

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

有时我们可能希望从目标file中仅提取感兴趣的值,而不是在正则表达式匹配时返回整行内容。

日志监控项具备从匹配行中提取所需值的能力。 这是通过在loglogrt监控项中添加output参数实现的。

使用'output'参数可以指定我们可能感兴趣的匹配"捕获组"。

例如

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

应该能返回在以下内容中找到的条目计数:

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

由于\1指向第一个也是唯一的捕获组:([0-9]+),因此仅返回数字。

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

使用 maxdelay 参数

log 监控项中的maxdelay参数允许忽略日志文件中的一些较早行,以便在maxdelay秒内get最近分析的行。

将'maxdelay'设置为大于0可能会导致忽略重要的日志file记录并错过警报。 请谨慎使用,仅在必要时自行承担风险。

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

内置过载保护机制包含可配置的maxlines参数(防止服务器接收过多匹配的日志行)以及10倍'maxlines'限制(防止单次检查中主机的CPU和I/O因agent而过载)。 然而,内置保护仍存在两个问题。 首先,大量可能信息量不大的消息会被报告到服务器,并占用数据库空间。 其次,由于每秒分析的行数有限,agent可能会滞后于最新日志记录数小时。 您很可能更希望及时了解日志文件中的当前情况,而不是花费数小时翻阅旧记录。

这两个问题的解决方案是使用maxdelay参数。 如果指定了 maxdelay > 0,在每次检查期间会测量已处理的字节数、剩余的字节数以及处理时间。 根据这些数字,agent会计算出一个预估延迟——即分析日志file中所有剩余记录所需的秒数。

如果延迟不超过maxdelay,则agent会继续按常规分析日志file。

如果延迟超过maxdelay,则agent通过"跳过"方式忽略日志file的一个数据块,跳转到新的预估位置,以便在maxdelay秒内分析剩余行。

请注意,agent 甚至不会将忽略的行读入缓冲区,而是计算在 file 中跳转的近似位置。

跳过日志file行的事实会被记录在agent日志file中 如下所示:

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"数值是近似值,因为在"jump"之后agent会将file中的位置调整到日志行的起始处,该位置可能在file中更靠后或更靠前。

根据日志增长速度与分析速度file的对比情况,您可能观察到以下几种现象:无"跳跃"、偶发或频繁"跳跃"、幅度大小不等的"跳跃",甚至每次检查都会出现小幅"跳跃"。 系统负载和网络延迟的波动也会影响延迟计算,因此需要"跳跃"前进以跟上"maxdelay"参数。

maxdelay 设置为小于 update interval 是不推荐的(可能导致频繁的小幅度"跳动")。

关于处理'copytruncate'日志文件轮转的注意事项

带有copytruncate选项的logrt假定不同日志文件包含不同记录(至少时间戳不同),因此初始块(前512字节)的MD5校验和会不同。 两个文件若具有相同的初始块MD5校验和,意味着其中一个是原始文件,另一个是copy。

带有copytruncate选项的logrt会努力正确处理日志file副本而不报告重复项。 但不建议出现以下情况:生成多个具有相同时间戳的日志file副本、日志file轮转频率高于logrt[] 监控项 update间隔、频繁重启agent。 agent会尝试合理处理这些情况,但无法保证在所有场景下都能获得理想结果。

日志持久化文件注意事项*[] 监控项

持久化文件的用途

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

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

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

主要用例是监控位于镜像file系统上的日志file。 在某个时间点之前,日志file会同时写入两个镜像。 然后镜像被拆分。 在活动copy上,日志file仍在增长,获取新记录。 Zabbix agent分析它并将已处理的日志大小和修改时间发送到服务器。 在被动copy上,日志file保持不变,远远落后于活动copy。 之后,操作系统和Zabbix agent从被动copy重新启动。 Zabbix agent从服务器接收的已处理日志大小和修改时间可能对被动copy上的情况无效。 为了从file系统镜像拆分时agent停止的位置继续日志file监控,agent会从持久化file恢复其状态。

Agent 持久化文件操作

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

在 agent 运行期间,持久化文件会以写入模式打开(使用 fopen(filename, "w"))并用最新数据覆盖。 若覆盖操作与 file 系统镜像分裂同时发生,丢失持久化 file 数据的概率极低,因此未做特殊处理。 写入持久化 file 后不会强制同步到存储介质(未调用 fsync())。

只有在成功向 Zabbix server 报告匹配的日志 file 记录或元数据(已处理的日志大小和修改时间)后,才会用最新数据执行覆盖操作。 若日志 file 持续变化,该操作可能频繁至每个 监控项 检查周期都会发生。

agent 关闭时不执行特殊操作。

在接收到活动检查列表后,agent会将过期的持久化文件标记为待删除。 持久化file在以下情况下会变为过期状态:1) 对应的日志监控项不再被监控,2) 日志监控项被重新配置为与之前不同的persistent_dir存储位置。

删除操作会延迟24小时执行,因为处于NOTSUPPORTED状态的日志文件不会包含在活动检查列表中,但它们后续可能变为SUPPORTED状态,此时其持久化文件仍有用处。

若agent在24小时到期前停止运行,则过期文件不会被删除,因为Zabbix agent无法再从Zabbix server获取这些文件的位置信息。

当agent停止运行时,若用户未手动删除旧的持久化file就将日志监控项的persistent_dir重新配置回旧位置,将导致从旧持久化file恢复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]会导致从agent的活动检查列表中删除监控项 logrt[/home/zabbix/test.log,,,10]并创建logrt[/home/zabbix/test.log,,,20] 监控项(某些属性会在前端/服务器修改时保留,但不会在agent中保留)。

file名称由监控项密钥的MD5哈希值加上监控项密钥长度组成,以降低冲突可能性。 例如,logrt[/home/zabbix50/test.log,,,,,,,,/home/zabbix50/agent_private] 监控项的状态将被保存在持久性file c963ade4008054813bbc0a650bb8e09266中。

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

persistent_dir 的指定需考虑特定的file系统布局、挂载点、挂载选项以及存储镜像配置——持久化file应与被监控日志file位于同一镜像文件系统上。

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

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

I/O 负载

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

当 agent 与服务器通信失败时的操作

来自 log[]logrt[] 的每个匹配行 监控项 以及每个 log.count[]logrt.count[] 监控项 检查的结果都需要在 agent 发送缓冲区指定的50%区域中有一个空闲槽位。 缓冲区元素会定期发送到服务器(或proxy),缓冲区槽位随即被释放。

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

在较长时间的通信故障期间,所有日志槽位get被占用,并采取以下措施:

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

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

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

如果正则表达式编译成功,但在运行时失败(部分或全部日志记录上),则日志监控项仍保持支持状态且监控继续运行。 运行时错误会被记录到Zabbix agent日志file中(不包含日志file记录本身)。

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

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

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