16

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

<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>

如您所见,我有一个带有特定 PatternLayout 的 Console appender 和 RollingFile appender。我想为 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>

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

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

4

5 回答 5

19

正如这个log4j2 错误报告中提到的, log4j2的开发人员将 SyslogAppender 编码为硬连线到SyslogLayout的SocketAppender

因为它旨在符合原始系统日志格式或 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>

This will write well-formatted RFC5424 logs to local 514 port through UDP. Following is a sample log output:

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":"" }
于 2015-09-14T13:00:01.897 回答
7

我不相信您可以在基本的 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

希望有帮助!

于 2013-07-30T15:54:35.070 回答
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%'")

我只是试图做同样的事情,并认为我会分享对我有用的东西。- 山姆

于 2014-04-06T13:59:14.310 回答
2

You can use SocketAppender and PatternLayout to format syslog (syslog-ng) messages.
To support dynamic Severities with a fixed Facility (e.g.: 'user-level messages' - see RFC5424) the pattern should look like this:

<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>

To calculate the Priority value (PRIVAL) for Facility 'user-level message' and Severity 'informational messages' - see [RFC5424](https://www.rfc-editor.org/rfc/rfc5424/)) the following example might help:
Syslog:          Facility  | Severity
Numerical Code:      1          6
Bin:             0 0 0 0 1 |  1 1 0
Dec:                 8     +    6    =  14

于 2017-02-08T17:23:34.903 回答
1

I used the config posted by butcher82, but had to change it a bit to produce the result I needed.

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

此模式应与 RFC-3164 兼容:

<Socket name="SysLogAppender" host="localhost" port="514" protocol="UDP">
    <PatternLayout pattern="&lt;%level{TRACE=7, DEBUG=7, INFO=6, WARN=4, ERROR=3, Fatal=0}&gt;%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。

于 2017-12-15T10:01:25.167 回答