在linux中用rsyslog输出标准json日志,需启用json-c支持、定义符合elk规范的json类型模板(如使用timereported+rfc3339、format="json"转义message),并正确应用至文件或tcp输出。

在 Linux 中用 Rsyslog 的 template 模块输出标准 JSON 日志,核心是定义结构化模板并确保字段名、类型和嵌套符合 Logstash 或 Filebeat 的预期(如 @timestamp、host、message 等),同时避免非法字符和格式错误。
确认 Rsyslog 版本并启用 json-c 支持
Rsyslog v8.16+ 原生支持 json 模板类型,但需编译时启用了 libjson-c。运行以下命令验证:
$ rsyslogd -v | grep -i json
若无输出或提示 no json support,需重装带 json 支持的版本(如 Ubuntu/Debian 安装 rsyslog-gnutls 和 libjson-c-dev 后源码编译,或使用官方 PPA)。
编写符合 ELK 规范的 JSON Template
ELK(尤其是 Logstash 的 json codec 或 Filebeat 的 json.keys_under_root: true)期望日志为单行合法 JSON 对象。推荐使用 json 类型模板(非 legacy string 拼接),自动转义、类型推断更可靠:
$template elk_json,"{\"@timestamp\":\"%TIMESTAMP:::date-rfc3339%\",\"host\":\"%HOSTNAME%\",\"program\":\"%PROGRAMNAME%\",\"pid\":\"%PROCID%\",\"severity\":\"%syslogseverity-text%\",\"facility\":\"%syslogfacility-text%\",\"message\":\"%msg%\"}"
更健壮的做法是用 json 模板类型(Rsyslog v8.19+):
$template elk_json, "elk_json", json
$ActionFileDefaultTemplate elk_json
并在 /etc/rsyslog.d/20-elk.conf 中显式声明字段(推荐):
template(name="elk_json" type="list") {
constant(value="{")
constant(value="\"@timestamp\":\"")
property(name="timereported" dateFormat="rfc3339")
constant(value="\",\"host\":\"")
property(name="hostname")
constant(value="\",\"program\":\"")
property(name="programname")
constant(value="\",\"message\":\"")
property(name="msg" format="json")
constant(value="\"}")
}
关键点:
-
property(name="msg" format="json")自动对 message 内容做 JSON 转义,防止双引号、换行破坏结构 -
timereported比timestamp更准确(含接收时间),且dateFormat="rfc3339"输出如2024-05-22T14:30:45.123Z,Logstash 可直接解析为@timestamp - 避免在 template 中硬编码
\n或多余空格,保证单行 JSON
将模板应用到日志输出(文件或 TCP)
例如写入本地 JSON 文件供 Filebeat 采集:
if $programname == 'nginx' then {
action(type="omfile" file="/var/log/nginx/json-access.log" template="elk_json")
stop
}
# 或转发到 Logstash 的 TCP 端口(需启用 omfwd)
*.* action(type="omfwd" protocol="tcp" target="192.168.1.100" port="5044" template="elk_json")
若走 TCP,确保 Logstash input 配置为:
input {
tcp {
port => 5044
codec => "json"
}
}
验证与排错要点
生成日志后,立即检查输出是否为合法单行 JSON:
$ tail -n1 /var/log/nginx/json-access.log | python3 -m json.tool
常见问题及修复:
-
解析失败:Unexpected token → 检查是否有未转义的双引号或控制字符;改用
format="json"处理msg -
@timestamp 为空或格式错误 → 确认用的是
timereported+dateFormat="rfc3339",而非timestamp -
字段缺失(如 host 为 localhost) → 在
/etc/rsyslog.conf中设置$LocalHostName your-real-hostname,并重启服务 -
中文乱码或特殊字符异常 → 确保系统 locale 为 UTF-8(
locale | grep UTF),Rsyslog 默认按 UTF-8 处理
重启生效:sudo systemctl restart rsyslog,再用 rsyslogd -N1 检查配置语法。











