Log4j2 - Syslog appender и PatternLayout

Мне нужно записывать события в syslog. Я использую lo4j2 и syslog appender. Блок добавления appender в 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>

Как вы можете видеть, у меня есть консольный appender и приложение RollingFile с определенным шаблономLayout. Я хочу использовать тот же PatternLayout для Syslog appender. Однако сообщения журнала в 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 все еще имеют одинаковую форматированную форму.

Как определить формат сообщений журнала, которые входят в syslog?

Ответ 1

Как упоминалось в этом отчете об ошибке log4j2, разработчики log4j2 закодировали SyslogAppender как SocketAppender, связанный с SyslogLayout

поскольку он предназначен для соответствия либо исходному формату syslog, либо RFC 5424. Никакой другой макет не должен быть разрешен.

Они, к сожалению, не понимали, что спецификации RFC 5424 не применяют какой-либо конкретный формат для сообщения, содержащегося в журнале, что в реализации Log4j2 является только частью %m журнала.

Чтобы решить эту проблему, решение (предлагаемое в том же отчете об ошибке) состоит в том, чтобы воспроизвести формат syslog с помощью PatternLayout внутри SocketAppender, так

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

Это приведет к записи хорошо отформатированных журналов RFC5424 в локальный порт 514 через UDP. Ниже приведен пример вывода журнала:

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":"" }

Ответ 2

Я не считаю, что вы можете использовать шаблон для основного приложения Syslog.

В документах указано, что

"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

Надеюсь, что это поможет!

Ответ 3

Вы можете использовать SocketAppender и PatternLayout для форматирования сообщений syslog (syslog-ng).
Для поддержки динамических проблем с фиксированным средством (например: "сообщения на уровне пользователя" - см. 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>


Чтобы вычислить значение приоритета (PRIVAL) для сообщений об уровне обслуживания пользователя и информационных сообщений Severity, см. RFC5424) следующее пример может помочь:

Syslog:          Facility  | Severity
Numerical Code:      1          6
Bin:             0 0 0 0 1 |  1 1 0
Dec:                 8     +    6    =  14

Ответ 4

Вы можете добавить дополнительные элементы в сообщение SyslogAppender, отформатированное в RFC5424, используя тег LoggerFields следующим образом:

<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="'%[email protected]!thread%', '%[email protected]!priority%', '%[email protected]!category%', '%[email protected]!exception%'")

Я просто пытался сделать то же самое и думал, что поделюсь тем, что сработало для меня. - Сэм

Ответ 5

Я использовал конфигурацию размещенную butcher82, но мне пришлось немного изменить ее, чтобы получить нужный мне результат.

В итоге я получил сообщение с правильным приоритетом, меткой времени (без начальных нулей в течение нескольких дней), хостом и частью сообщения. Отображение между уровнями syslog и log4J используется, как определено в org.apache.log4j.Level, и для установки для 1-го уровня (для сообщений уровня пользователя) установлено значение 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 после имени хоста.

Ответ 6

Кто-нибудь знает, как отключить дату и имя хоста с начала вывода логгера SocketAppender.

Ответ 7

Какая польза от lt; и gt; в следующей команде?

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