Slf4j 搭配雲日誌系統

基本概念

性能

應該滿足這幾個關鍵點:

(1)易使用,一行代碼搞不定都屬於是有問題。

(2)易集成,Ctrl C/V兩分鐘搞定的那種。

(3)高性能,對業務本身不能造成影響,或者必要情況下影響最低,如果一個業務耗費了10毫秒,有9毫秒是花在日誌上,那就別扯了。

(4)易維護,容易管理,不容易丟,單主機就存主機,集羣就找個統一的地方存。

(5)易查,在遇到問題的能快速定位到地方。

分類

(1)TREC - 羅裏吧嗦的日誌(絕大部分可直接忽略)

(2)DEBUG - 調試日誌

(3)INFO - 日常日誌

(4)WARN - 警告日誌

(5)ERROR - 錯誤日誌

規範

似乎都沒有一個比較統一的規範,做好分級即可,然後日誌採集的時候儘可能的詳細、流程清晰,至於表現形式,無特殊要求。

採集方式

Slf4j等主流的框架已經實現按需按量打印到控制檯並按照指定文件格式寫入指定文件了,所以這探討的不是這種。

因爲採用的是騰訊雲的日誌系統(用雲的或者是用自建的,都是同樣的邏輯),那邊也提供有相關的SDK,所以只需要在合適的地方將日誌上傳上去就好。

(1)在Slf4j之前上傳,說白了就是自己再封裝一層,寫個Log,ALog啥的。

(2)在Slf4j上傳,主要是繼承他原本的過濾器,然後在過濾器中上傳。

第一種方式感覺也沒啥好說的了,這裏採用的是第二種方式。

開搞

導包

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

這玩意是一個工具包,裏面集成了Slf4j和其他實用的一些東西,集成了這玩意之後,打印只需要log.info()即可,十分方便。

配置

在項目的resources目錄下新建一個logconfig目錄,裏面放了四個文件,logconfig_dev.xml、logconfig_test.xml、logconfig_prod.xml、logconfig_pre.xml,分別對應四種不同的環境。

然後在application.xml合適的位置加上配置

logging:
  level:
    com.alibaba.nacos.client.config.impl: WARN
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicExtractor: INFO
    com.ys.adage.mapper: INFO
    org.springframework: INFO
  config: classpath:logconfig/logconfig_dev.xml

level-指定一些庫的日誌級別

config-配置文件的路徑

貼上某個logconfig_xxx.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--輸出日誌格式-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                %d - %msg%n
            </pattern>
        </layout>
    </appender>
    <!--只保存info日誌-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滾動輸出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路徑-->
            <fileNamePattern>/root/logs/email/info/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存warn日誌-->
    <appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滾動輸出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路徑-->
            <fileNamePattern>/root/logs/email/warn/warn.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存error日誌-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滾動輸出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路徑-->
            <fileNamePattern>/root/logs/email/error/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileWarnLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

</configuration>

這裏主要定義了日誌文件的文件規則,哪些日誌類型需要打印和寫入文件中,哪些不需要。

分爲三個級別(error/info/warn),這三個級別這是寫入文件的級別,具體你可以定義這三個級別分別要打印什麼級別的日誌,如開發環境的話,info就可以打印info級別跟debug級別的日誌。

過濾

核心就在這個logconfig配置文件這裏,這裏需要過濾掉一些跟等級無關的日誌,所以配置了兩個日誌過濾器LevelFilter、ThresholdFilter,兩者的區別在於LevelFilter只打印指定級別的日誌,ThresholdFilter打印高於當前設置級別的日誌。

所以,我們只需要重寫一下這兩個過濾類(一個也夠了),把日誌打印出來之前傳到騰訊的SDK即可。

重寫好的類其實也很簡單

public class LogFilter extends LevelFilter {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        FilterReply filterReply = super.decide(event);
        if (FilterReply.DENY != filterReply) {
            //確定是需要打印的日誌級別
            TencentLog.putLog(event.getLevel().levelStr, event.getMessage());//傳到SDK
        }
        return filterReply;
    }
}

然後改一下ipconfig_xxx.xml配置文件裏面的filter標籤,把過濾器的路徑指定到我們重寫的LogFilter類即可。

最後,傳到SDK的代碼那裏,最好是開個線程池處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章