log4j2利用SocketAppender將日志寫入rsyslog


log4j2利用SocketAppender將日志寫入rsyslog

摘要:利用elk(elasticsearch/logstash/kibana)做些簡單的分布式日志查看還是比較高效方便的。這周將線上項目的日志升級到log4j2,但是比較坑的是log4j2的SyslogAppender無法自定義PatternLayout。本文將介紹一下如何利用SocketAppender將數(shù)據(jù)寫入rsyslog。

背景

上文scala接入log4j2中我們介紹了log4j2的一些基本配置,本以為已經(jīng)完全ready了,沒想到上線之后,在kibana中并不能查到相關日志。

查看/var/log/syslog可以看到我們的日志已經(jīng)正常寫入了,但是跟運維排查過后,發(fā)現(xiàn)我們的日志是需要寫入我們自定的模塊LOCAL4

問題解決

一度懷疑是log4j2的propertie配置文件支持有問題,于是我將properties配置文件切換到xml配置文件。于是我們看到,日志是可以正常打入到LOCAL4模塊的,但是看了pattern是不符合我們設置的預期。無奈,繼續(xù)查找如何修改pattern。

google查到Log4j2- Syslog appender and PatternLayout一文,發(fā)現(xiàn)這是log4j2的bug,但是里面提到可以利用SocketAppender來模擬消息,給rsyslog發(fā)送消息。

SocketAppender

按其中答案來設置發(fā)現(xiàn)消息并未如愿發(fā)到Local4模塊(其實他是將INFO日志發(fā)送到local1,而我的需求是發(fā)送到local4)。

可以看到我們需要模擬一個消息頭部,syslog的具體協(xié)議可參考[1],但是這個頭部具體該如何模擬呢?

我們可以看到stackoverflow中的答案,F(xiàn)acility和Severity跟頭部code的對應關系。

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

Numerical Code和Facility/Severity的對應關系請參考[2]

猜想意思是Facility code需要左移三位,猜想是不是正確的呢?翻下GitHub源碼

private static int toPriority(final Facility aFacility, final Severity aSeverity) {
    return (aFacility.getCode() << 3) + aSeverity.getCode();
}

證實我們的猜想是正確的。
具體的消息是拼接成什么樣的呢?我們繼續(xù)翻下源碼

public String toSerializable(final LogEvent event) {
    final StringBuilder buf = getStringBuilder();

    buf.append('<');
    buf.append(Priority.getPriority(facility, event.getLevel()));
    buf.append('>');
    addDate(event.getTimeMillis(), buf);
    buf.append(Chars.SPACE);
    buf.append(localHostname);
    buf.append(Chars.SPACE);

    String message = event.getMessage().getFormattedMessage();
    if (null != escapeNewLine) {
        message = NEWLINE_PATTERN.matcher(message).replaceAll(escapeNewLine);
    }
    buf.append(message);

    if (includeNewLine) {
        buf.append('\n');
    }
    return buf.toString();
}

結合我們對syslog的協(xié)議的理解,我們需要<Code>這樣的一個頭部消息。

其中Code為Facility和Severity拼接成的,在我們的場景中,我們的Facility=20Severity=6,所以我們的code=166

后續(xù)

正當我以為全部問題都解決了,發(fā)現(xiàn)最終打到我們Local4模塊的主機名還是不對的,我們寫入elasticsearch的字段需要的是真正的hostname,而不是localhost.

通過Google發(fā)現(xiàn)如何獲取client名字一文

查閱文檔我們發(fā)現(xiàn)log4j2配置文件支持Property,參考[3]。
而Property又支持環(huán)境變量,參考[4]。

完整配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" dev="err">
  <Appenders>
    <Console name="STDOUT">
      <PatternLayout pattern="%d{DEFAULT} %tid [%tn] %p %c{1}: %m%n"/>
    </Console>
    <Syslog name="RFC5424" format="RFC5424" host="localhost" port="514"
            protocol="UDP" appName="recommend-metric-log:"
            facility="LOCAL4" enterpriseNumber="18060" newLine="true"
            messageId="Audit" mdcId="mdc">
      <!--<PatternLayout pattern="${hostName} recommend-metric-log: %m%n"/>-->
      <LoggerFields>
        <KeyValuePair key="thread" value="%t"/>
        <KeyValuePair key="priority" value="%p"/>
        <KeyValuePair key="category" value="%c"/>
        <KeyValuePair key="exception" value="%ex"/>
        <KeyValuePair key="message" value="%m"/>
      </LoggerFields>
    </Syslog>
    <Socket name="SYSLOG" host="${hostName}" port="514" protocol="UDP">
      <PatternLayout pattern="&lt;166&gt;recommend-metric-log: %m%n"/>
    </Socket>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="STDOUT"/>
    </Root>
    <Logger name="com.dxy.data.utils.SyslogPrinter$">
      <Property name="hostName">$${HOSTNAME}</Property>
      <Appender-ref ref="SYSLOG"/>
    </Logger>
  </Loggers>
</Configuration>

總結

我們可以看到rsyslog就是通過一個udp請求,將日志寫入rsyslog。
最后,elk雖然能很好的收集展示分布式日志,但是還是無法做到查看日志上下文的

Reference

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • syslog服務器可以用作一個網(wǎng)絡中的日志監(jiān)控中心,所有能夠通過網(wǎng)絡來發(fā)送日志的設施(包含了Linux或Windo...
    hello大象閱讀 12,920評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評論 19 139
  • 1 概述 系統(tǒng)日志是記錄系統(tǒng)中硬件、軟件和系統(tǒng)問題的信息,同時還可以監(jiān)視系統(tǒng)中發(fā)生的事件。用戶可以通過它來檢查錯誤...
    ghbsunny閱讀 4,205評論 0 0
  • 日志管理Rsyslog [TOC] 背景 有一個4臺機器的分布式服務,不多不少,上每臺機器上查看日志比較麻煩,用F...
    ferret閱讀 31,802評論 0 6
  • 陽光正好,歲月不老。 我還在最美的年華
    公子不世閱讀 364評論 0 0

友情鏈接更多精彩內(nèi)容