如何正确使用 Rsyslog 的 imfile 模块解析文本文件?
通过 rsyslog 的 imfile 模块可以采集普通文本日志文件并打进 syslog 管道。本文给出 RainerScript 风格的完整配置、状态文件说明及排错要点,并对比观测云 DataKit 的文件日志采集方案。
核心步骤:加载 imfile 模块 → 用 input(type="imfile" File="..." Tag="...") 声明要监听的文件 → 用规则把带该 Tag 的消息路由到目标位置。关键点是配置可写工作目录与 PersistStateInterval 持久化读取偏移,避免重启后重复采集或漏采。
配置示例(RainerScript 新语法)
在 /etc/rsyslog.d/ 下新建配置:
global(workDirectory="/var/spool/rsyslog")
module(load="imfile")
input(type="imfile"
File="/var/log/myapp/app.log"
Tag="myapp"
Severity="info"
Facility="local0"
PersistStateInterval="100")
# 路由到本地文件(也可改为转发到远程)
if $programname == 'myapp' then /var/log/myapp-collected.log
& stop
改完执行 rsyslogd -N1 检查语法,然后 systemctl restart rsyslog。
关键参数说明
- File:监听的文件路径,支持通配符(需较新版本)。
- Tag:给这批消息打上的标签,后续靠
$programname过滤。 - StateFile:旧语法中必须显式指定,记录读取偏移;新语法自动命名状态文件,但还应配置 PersistStateInterval 及可写工作目录,但生产环境建议确认
workDirectory已设置(global(workDirectory="/var/spool/rsyslog"))。 - readMode:默认按行读;多行日志(如 Java 堆栈)需要设置
readMode="0"配合startmsg.regex做行合并。
常见坑
- SELinux/权限:rsyslog 进程读不到目标文件是最常见的问题,检查文件权限和 SELinux 上下文。
- 日志轮转:重命名轮转与原地截断是不同情形。imfile 可检测轮转;reopenOnTruncate 针对截断且有实现限制,HUP 不是通用 imfile 修复方法,应按实际轮转模式测试。
- 多行堆栈被拆散:不配置多行合并时,Java 异常堆栈的每一行都会成为独立日志。
常见问题(FAQ)
Q:imfile 会重复采集已有内容吗?
A:freshStartTail 默认 off,新文件首次读取从头开始;有效状态文件存在时按偏移继续。startmsg.regex 只控制多行边界,不能选择历史起点;删除状态会导致重读,不应作为常规修复。
Q:采集后消息里的换行不见了?
A:imfile 按行读取,每行是一条独立消息。需要保留多行结构必须配置多行合并。
Q:能直接转发到远程 syslog 服务器吗?
A:可以,在匹配 myapp 的条件或专用 ruleset 中配置 omfwd TCP action,并配置相应队列;无条件 . 会转发其他来源的全部消息,超出仅转发本文件的范围。