log4j2 - Syslog 附加程序和 PatternLayout
Posted
技术标签:
【中文标题】log4j2 - Syslog 附加程序和 PatternLayout【英文标题】:log4j2 - Syslog appender and PatternLayout 【发布时间】:2013-07-30 15:13:44 【问题描述】:我需要将事件记录到系统日志中。
我使用 lo4j2 和 syslog appender。
我在 log4j2.xml
中的 appenders 块看起来像这样:
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%dHH:mm:ss.SSS [%t] %-5level %logger36 - %msg%n"/>
</Console>
<Syslog name="syslog" host="localhost" port="514" protocol="UDP" charset="ISO-8859-1">
</Syslog>
<RollingFile name="AppLog" fileName="/var/log/app.log"
filePattern="/var/log/$$date:yyyy-MM/app-%dMM-dd-yyyy-%i.log.gz">
<PatternLayout pattern="%dHH:mm:ss.SSS [%t] %-5level %logger36 - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</appenders>
如您所见,我有一个带有特定 PatternLayout 的 Console appender 和 RollingFile appender。 我想为 Syslog appender 使用相同的 PatternLayout。 但是,syslog 中的日志消息似乎总是使用预定义的布局。 我尝试执行以下操作:
<Syslog name="syslog" host="localhost" port="514" protocol="UDP" charset="ISO-8859-1">
<PatternLayout pattern="%dHH:mm:ss.SSS [%t] %-5level %logger36 - %msg%n"/>
</Syslog>
但这没有任何效果。系统日志消息仍然具有相同的预定义格式。
如何确定进入 syslog 的日志消息的格式?
【问题讨论】:
【参考方案1】:正如log4j2 bug report 中所述,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>%dMMM dd HH:mm:ss $hostName appName:
"host":"$hostName",
"thread":"%t",
"level":"%p",
"logger":"%c1",
"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":""
【讨论】:
这不允许将消息写入自定义设施,例如 local4。【参考方案2】:我不相信您可以在基本的 Syslog 附加程序上使用模式。
从文档中指出
“SyslogAppender 是一个 SocketAppender,它以符合 BSD Syslog 格式或 RFC 5424 的格式将其输出写入由主机和端口指定的远程目标” http://logging.apache.org/log4j/2.x/manual/appenders.html#SyslogAppender
但是,它确实允许您指定“格式 = RFC 5424”
如果您使用 RFC 5424
然后你可以在loggerFields参数中放一个PatterLayout。 见http://logging.apache.org/log4j/2.x/manual/layouts.html#RFC5424Layout
希望有帮助!
【讨论】:
这似乎是正确的方向,但我不太明白如何在我的log4j2.xml
中使用<loggerFields>
标签。我应该在“关键”属性中添加什么?一个例子会很有用。
@conornicol,我相信你误解了 PatternLayout 部分。到目前为止,不可能将自定义 PatternLayout 注入 RFC-5424 布局。您正在影响的是 [] 中的部分。您不会影响该布局的消息部分。【参考方案3】:
您可以使用 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%'")
我只是尝试做同样的事情,并认为我会分享对我有用的方法。 - 山姆
【讨论】:
有没有办法在 log4j2.properties 文件中添加这些 LoggerFields。我想为 elasticsearch 5x 做它,它只支持 log4j.properties 不支持 log4j2.xml,我在网上看不到任何示例,在属性文件中看不到 LoggerFields 的文档 将此添加到属性文件不起作用 appender.sumo_syslog.loggerFields='key' : 'priority', 'value' : '%p' 您还需要加载正确的 rsyslog 模块才能解析 RFC5424 结构:module(load="mmpstrucdata") action(type="mmpstrucdata")【参考方案4】:您可以使用 SocketAppender 和 PatternLayout 来格式化 syslog (syslog-ng) 消息。 为了支持具有固定设施的动态严重性(例如:“用户级消息” - 请参阅 RFC5424),模式应如下所示:
<Socket name="SYSLOG" host="$env:INTERFACE" port="514" protocol="UDP">
<PatternLayout pattern="<%levelTRACE=15, DEBUG=15, INFO=14, WARN=12, ERROR=11, Fatal=11,>%replace$env:APPLICATION_NAME\r[%XPID] %t(%T) %c10 - %m%n"/>
</Socket>
要计算设施“用户级消息”和严重性“信息性消息”的优先级值 (PRIVAL) - 请参阅 [RFC5424](https://www.rfc-editor.org/rfc/rfc5424/))以下示例可能帮助:
Syslog: Facility | Severity
Numerical Code: 1 6
Bin: 0 0 0 0 1 | 1 1 0
Dec: 8 + 6 = 14
log4j2syslog-ngsocketappenderpatternlayout
【讨论】:
【参考方案5】:我使用了config posted by butcher82,但必须对其进行一些更改才能产生我需要的结果。
我最终得到的是一条具有正确优先级、时间戳(几天没有前导零)、主机和消息部分的消息。 syslog 和 log4J 级别之间的映射按照 org.apache.log4j.Level 中的定义使用,并且该工具设置为 1(用户级别消息),以简化优先级计算。
此模式应与 RFC-3164 兼容:
<Socket name="SysLogAppender" host="localhost" port="514" protocol="UDP">
<PatternLayout pattern="<%levelTRACE=7, DEBUG=7, INFO=6, WARN=4, ERROR=3, Fatal=0>%dMMM d hh:mm:ss $hostName %m%n"/>
</Socket>
下面是生成的输出:
<3>Dec 15 09:59:16 foo.bar.hostname this is a test message
注意:可以在主机名之后添加应用程序名称或 pid。
【讨论】:
以上是关于log4j2 - Syslog 附加程序和 PatternLayout的主要内容,如果未能解决你的问题,请参考以下文章
Mac 上的 Log4j2 Syslog Appender 格式