正如本 log4j2 bug 报告中提到的,log4j2 的开发人员将 SyslogAppender 编码为 SocketAppender 硬连线到 SyslogLayout
因为它旨在符合原始系统日志格式或 RFC 5424。不应允许任何其他布局。
不幸的是,他们没有意识到 RFC 5424 规范并未对日志中包含的消息强制执行任何特定格式,在 Log4j2 实现中仅是日志的
%m
部分。
为了解决这个问题,一个解决方案(在同一个错误报告中建议)是在 SocketAppender 内使用 PatternLayout 重现 syslog 格式,就像这样
<Socket name="SYSLOG" host="localhost" port="514" protocol="UDP">
<PatternLayout
pattern="<1>%d{MMM dd HH:mm:ss} ${hostName} appName: {
"host":"${hostName}",
"thread":"%t",
"level":"%p",
"logger":"%c{1}",
"line":%L,
"message":"%enc{%m}",
"exception":"%exception"
}%n"
/>
</Socket>
这将通过 UDP 将格式良好的 RFC5424 日志写入本地 514 端口。以下是示例日志输出:
Sep 14 10:40:50 app-hostname app-name: { "host":"host-name-01", "thread":"http-nio-8080-exec-4", "level":"DEBUG", "logger":"ExecuteTimeInterceptor", "line":52, "message":"GET /health 200 served in 3", "exception":"" }
我不相信您可以在基本 Syslog 附加程序上使用模式。
从文档中可以看出
“SyslogAppender 是一个 SocketAppender,它将其输出写入由主机和端口指定的远程目标,格式符合 BSD Syslog 格式或 RFC 5424” http://logging.apache.org/log4j/2.x/manual/appenders.html#SyslogAppender
但是,它确实允许您指定“format = RFC 5424”
如果您使用 RFC 5424
然后你可以在loggerFields参数中放置一个PatterLayout。 请参阅http://logging.apache.org/log4j/2.x/manual/layouts.html#RFC5424Layout
希望有帮助!
您可以使用 LoggerFields 标签向 RFC5424 格式的 SyslogAppender 消息添加其他元素,如下所示:
<LoggerFields>
<KeyValuePair key="thread" value="%t"/>
<KeyValuePair key="priority" value="%p"/>
<KeyValuePair key="category" value="%c"/>
<KeyValuePair key="exception" value="%ex"/>
</LoggerFields>
然后我使用 rsyslog 的 RFC5424 解析模块 mmpstrucdata 将它们拉出,以创建 json 树。用于访问它们的 rsyslog.conf 模板如下所示:
template(name="jsondump" type="string" string="'%$!rfc5424-sd!mdc@18060!thread%', '%$!rfc5424-sd!mdc@18060!priority%', '%$!rfc5424-sd!mdc@18060!category%', '%$!rfc5424-sd!mdc@18060!exception%'")
我只是想做同样的事情,并认为我会分享对我有用的东西。 - 萨姆
您可以使用 SocketAppender 和 PatternLayout 来格式化 syslog (syslog-ng) 消息。
为了使用固定设施支持动态严重性(例如:“用户级消息” - 请参阅RFC5424),模式应如下所示:
<Socket name="SYSLOG" host="${env:INTERFACE}" port="514" protocol="UDP">
<PatternLayout pattern="<%level{TRACE=15, DEBUG=15, INFO=14, WARN=12, ERROR=11, Fatal=11}>%replace{${env:APPLICATION_NAME}}{\r}{}[%X{PID}] %t(%T) %c{10} - %m%n"/>
</Socket>
Syslog: Facility | Severity
Numerical Code: 1 6
Bin: 0 0 0 0 1 | 1 1 0
Dec: 8 + 6 = 14
我使用butcher82发布的配置,但必须对其进行一些更改才能产生我需要的结果。
我最终得到的是一条具有正确优先级、时间戳(几天前没有前导零)、主机和消息部分的消息。 syslog 和 log4J 级别之间的映射按照 org.apache.log4j.Level 中的定义使用,并且设施设置为 1(用户级消息),以简化优先级计算。
此模式应与 RFC-3164 兼容:
<Socket name="SysLogAppender" host="localhost" port="514" protocol="UDP">
<PatternLayout pattern="<%level{TRACE=7, DEBUG=7, INFO=6, WARN=4, ERROR=3, Fatal=0}>%d{MMM d hh:mm:ss} ${hostName} %m%n"/>
</Socket>
以下是生成的输出:
<3>Dec 15 09:59:16 foo.bar.hostname this is a test message
注意: 可以在主机名后添加应用程序名称或 pid。