log4j2 - Syslog appender和PatternLayout

时间:2013-07-30 12:54:15

标签: java log4j syslog log4j2

我需要将事件记录到syslog中。 我使用lo4j2和syslog appender。 log4j2.xml中的我的appenders块看起来像这样:

<appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %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-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>          
    </appenders>

正如您所看到的,我有一个Console appender和RollingFile appender以及一个特定的PatternLayout。 我想为Syslog appender使用相同的PatternLayout。 但是,syslog中的日志消息似乎总是使用预定义的布局。 我试着做以下事情:

<Syslog name="syslog" host="localhost" port="514" protocol="UDP" charset="ISO-8859-1">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Syslog>

但这没有任何效果。系统日志消息仍然具有相同的预定义格式。

如何确定进入系统日志的日志消息的格式?

5 个答案:

答案 0 :(得分:17)

正如本log4j2 bug report所述,log4j2的开发人员将SyslogAppender编码为SocketAppender硬连线到SyslogLayout

  

因为它要符合原始的syslog格式或RFC 5424.不允许使用其他布局。

遗憾的是,他们没有意识到RFC 5424规范没有对日志中包含的消息强制执行任何特定格式,而Log4j2实现中只是日志的%m部分。

要解决此问题,解决方案(在同一错误报告中建议)是使用SocketAppender中的PatternLayout重现syslog格式,如此

<Socket name="SYSLOG" host="localhost" port="514" protocol="UDP">
  <PatternLayout
    pattern="&lt;1&gt;%d{MMM dd HH:mm:ss} ${hostName} appName: {
      &quot;host&quot;:&quot;${hostName}&quot;,
      &quot;thread&quot;:&quot;%t&quot;,
      &quot;level&quot;:&quot;%p&quot;,
      &quot;logger&quot;:&quot;%c{1}&quot;,
      &quot;line&quot;:%L,
      &quot;message&quot;:&quot;%enc{%m}&quot;,
      &quot;exception&quot;:&quot;%exception&quot;
      }%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 &#x2F;health 200 served in 3", "exception":"" }

答案 1 :(得分:7)

我不相信你可以在基本的Syslog appender上使用模式。

从文档中可以看出

  

“SyslogAppender是一个SocketAppender,它将输出写入主机和端口指定的远程目标,格式符合BSD Syslog格式或RFC 5424”   http://logging.apache.org/log4j/2.x/manual/appenders.html#SyslogAppender

但是,它允许您指定“format = RFC 5424”

如果您使用RFC 5424

  

然后,您可以将PatterLayout放在loggerFields参数中。   见http://logging.apache.org/log4j/2.x/manual/layouts.html#RFC5424Layout

希望有所帮助!

答案 2 :(得分:2)

您可以使用SocketAppender和PatternLayout格式化syslog(syslog-ng)消息。
要使用固定工具支持动态严重性(例如:“用户级消息” - 请参阅RFC5424),模式应如下所示:

some_feature


要计算Facility'用户级消息'和Severity'信息性消息'的优先级值(PRIVAL) - 请参阅RFC5424),以下示例可能有所帮助:

<Socket name="SYSLOG" host="${env:INTERFACE}" port="514" protocol="UDP">
   <PatternLayout pattern="&lt;%level{TRACE=15, DEBUG=15, INFO=14, WARN=12, ERROR=11, Fatal=11,&gt;%replace{${env:APPLICATION_NAME}}{\r}{}[%X{PID}] %t(%T) %c{10} - %m%n"/>
</Socket>

答案 3 :(得分:1)

您可以使用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%'")

我只是想做同样的事情并且认为我分享了对我有用的东西。 - 山姆

答案 4 :(得分:0)

我使用了config posted by butcher82,但必须稍微更改一下才能生成我需要的结果。

我最终得到的是一条消息,其中包含正确的优先级,时间戳(几天没有前导零),主机和消息部分。 syslog和log4J级别之间的映射按 org.apache.log4j.Level 中的定义使用,设施设置为1(用户级消息),以简化优先级计算。

此模式应与RFC-3164兼容:

Enumerable.Except

以下是产生的输出:

.Except()

注意:可以在主机名后添加应用程序名称或pid。