rsyslog 默认单行日志限制4096字节,超长会被静默截断,破坏json/xml结构及trace_id等关键字段;需在主配置开头设$maxmessagesize(如16384),imfile模块须配readmode="2"和maxlinesatonce="1",模板禁用%msg:n:m%截断语法,并通过超长测试与usr1统计验证完整性。

rsyslog 默认对单行日志长度设有限制(通常为 4096 字节),超出部分会被静默截断,导致日志内容不完整、结构错乱,甚至破坏 JSON、XML 或带校验字段的日志指纹(如 trace_id、request_id、checksum 等),进而影响追踪、审计与告警准确性。
调整 $MaxMessageSize 全局上限
这是最直接的控制项,必须在 rsyslog 主配置开头(早于任何模块加载或规则定义)设置,否则无效:
- 编辑 /etc/rsyslog.conf 或 /etc/rsyslog.d/00-global.conf
- 添加一行:$MaxMessageSize 16384(支持 16KB;最大可设至 1048576,即 1MB)
- 注意:该指令仅对传统 syslog 协议输入(如 imudp/imtcp)生效;若使用 imfile 模块读取文件,则需配合其他参数
针对 imfile 模块启用长行兼容模式
当通过 imfile 监控应用日志文件(如 Java、Go 输出的 JSON 日志)时,仅调大 $MaxMessageSize 不够——imfile 默认按 \n 切割,且内部缓冲区仍受限制。需显式启用长行支持:
- 确保 rsyslog ≥ v8.20.0(v8.19+ 开始引入关键修复)
- 在 input 配置中添加:readMode="2"(启用“流式读取”,避免按行截断)和 maxLinesAtOnce="1"(防内存溢出)
- 示例配置片段:
input(type="imfile" File="/var/log/app/access.log" Tag="app-access" readMode="2" maxLinesAtOnce="1" reopenOnTruncate="on")
防止模板渲染阶段二次截断
即使原始消息未被截断,若后续使用模板(template)做格式化(如添加时间戳、主机名),而模板中含 %msg:1:4096% 这类截断语法,仍会破坏指纹。务必检查所有自定义模板:
- 禁用隐式截断:避免在模板中使用
%msg:N:M%形式,除非明确需要裁剪 - 改用安全引用:
%msg%(完整原始消息)或%$!all-json%(若已解析为结构化字段) - 若需控制输出宽度,应在日志生成端(应用层)规范格式,而非在 rsyslog 中硬切
验证与监控关键指标
配置变更后不能仅依赖“看起来正常”,需主动验证完整性:
- 向测试日志文件写入 >8KB 的纯文本或合法 JSON(含嵌套字段和唯一 trace_id)
- 用
logger -i -t "test" "$(python3 -c 'print(\"X\"*12000)')"发送超长 syslog 消息 - 检查接收端日志是否完整,重点比对指纹字段(如
"trace_id":"abc123"是否完整保留) - 启用 rsyslog 内置统计:
systemctl kill -s USR1 rsyslog,再查journalctl -u rsyslog | grep -i "trunc\|drop"










