rsyslog 中的 #012 和 #015 是什么?如何处理?
#012 与 #015 是 rsyslog 日志中的 ASCII 控制字符转义:#012 是换行符 LF、#015 是回车符 CR。Windows 风格 CRLF 日志或消息内换行会以这种形式出现。本文给出规范化处理方法。
#012 = 换行符 LF(\n),#015 = 回车符 CR(\r)——rsyslog 通常在接收解析阶段按转义设置把控制字符变为这种八进制形式,输出模板收到的可能已是字面文本,所以你会在日志文件里看到字面量 #012#015。
为什么会出现
- 日志来自 Windows 系统(行尾 CRLF);
- 应用日志消息里本身含换行(如多行堆栈被打平);
- 网络设备/Syslog 源的换行习惯不同。
处理方法
1. 模板中替换掉(推荐):用 RainerScript 的 replace() 函数:
template(name="cleanfmt" type="list") {
property(name="$.clean")
constant(value="\n")
}
# 在输出动作之前处理字面转义,再使用此模板
set $.clean = replace($msg, "#015#012", " ");
set $.clean = replace($.clean, "#012", " ");
set $.clean = replace($.clean, "#015", " ");
action(type="omfile" file="/var/log/clean.log" template="cleanfmt")
模板的控制字符选项只处理实际控制字符,不会自动识别字面 #012;上述替换也无法区分源文本中本来就存在的同名字串,应先验证样本。
2. 全局转义控制:rsyslog 的 $EscapeControlCharactersOnReceive off(或对应 RainerScript 参数 global(parser.escapeControlCharactersOnReceive="off"))让 rsyslog 不再把 CR/LF 转义成 #015/#012——收到的原始字符直接写盘(注意这会真的产生换行,可能把一条日志拆成多行)。
3. 下游处理:在下游解析层统一处理消息内的控制字符,先用包含真实 CR/LF 与字面量转义的样本分别测试。
常见问题(FAQ)
Q:#012#015 连着出现是什么? 这是 LF 后接 CR;Windows CRLF 的顺序是 #015#012。
Q:关了转义后日志被拆行? 是的,这是双刃剑——消息内含真换行的场景建议保持转义、下游再处理。