如何開啓Dubbo框架內部的日誌?

歡迎加入DUBBO交流羣:259566260

這裏將對如何在本身的項目裏面開啓dubbo框架本身的日誌,並對輸出的日誌進行控制。在講這些以前,先看看dubbo在處理日誌的時候是怎麼作的?   java

在dubbo框架內全部的日誌輸出都是經過 LoggerFactory這個靜態工廠類來得到Logger的對象實體,而且抽離了一個LoggerAdapter用於對接第三方日誌框架,因此就有了JDKLoggerAdapter,Log4jLoggerAdapter,SLF4JLoggerAdapter等一些實現子類,分別對接了不一樣Log第三方實現。既然dubbo可以支持這麼多log實現,那麼這些實如今dubbo中優先級是在呢麼樣的呢?這裏的優先級是隻未配置指定的logger提供方的狀況下,由dubbo框架本身選擇。優先級以下:  
 

第三方日誌框架 優先級
Log4j 最高(默認就用這個)
SLF4J 次高(上面沒有采用這個)
Common Logging(jcl就是common logging) 次低(Log4j和SLF4J在項目中均沒有就用這個)
JDK log 最低(最後的選擇)

上面說的有和沒有是指你的項目classpath下面有沒有對應的jar包,若是有則表示支持對應的日誌實現。下面粘貼出Dubbo選擇日誌提供方的代碼: spring

// 查找經常使用的日誌框架
    static {
        String logger = System.getProperty("dubbo.application.logger");
        if ("slf4j".equals(logger)) {
            setLoggerAdapter(new Slf4jLoggerAdapter());
        } else if ("jcl".equals(logger)) {
            setLoggerAdapter(new JclLoggerAdapter());
        } else if ("log4j".equals(logger)) {
            setLoggerAdapter(new Log4jLoggerAdapter());
        } else if ("jdk".equals(logger)) {
            setLoggerAdapter(new JdkLoggerAdapter());
        } else {
            try {
                setLoggerAdapter(new Log4jLoggerAdapter());
            } catch (Throwable e1) {
                try {
                    setLoggerAdapter(new Slf4jLoggerAdapter());
                } catch (Throwable e2) {
                    try {
                        setLoggerAdapter(new JclLoggerAdapter());
                    } catch (Throwable e3) {
                        setLoggerAdapter(new JdkLoggerAdapter());
                    }
                }
            }
        }
    }



  上面這段靜態塊是在LoggerFactory裏面,說明只要LoggerFactory類一加載就會去選擇對應的日誌提供方。你們可能會發現對日誌的提供方實際上是能夠經過配置來指定的,由於靜態塊一開始是從當前jvm環境中獲取dubbo.application.logger,這個參數是同java -Ddubbo.application.logger=xxxx去指定的,若是是放在容器裏面,就須要配置在容器啓動的jvm參數裏面。上面介紹了dubbo中日誌相關的實現。下面講講在項目總怎麼來讓dubbo可以在項目裏面輸出日誌。  
1、你項目當前使用的是Log4j來提供日誌輸出  
恭喜你,你不用作過多的處理就能夠開啓dubbo的日誌,由於dubbo默認就是使用log4j。你惟一須要作的就是配置一個name是"com.alibaba.dubbo"的logger就能夠了,而後關聯到對應的appender。以下:  

<appender name="dubboAppender" class="org.apache.log4j.DailyRollingFileAppender"> 
        <param name="File" value="E:/dubbo.log" />  
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />  
        <layout class="org.apache.log4j.PatternLayout"> 
         <param name="ConversionPattern"
            value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n" /> 
        </layout>  
</appender> 
<logger name="com.alibaba.dubbo" additivity="false"> 
        <priority value ="info"/>  
        <appender-ref ref="dubboAppender" />  
</logger>



2、你的項目當前使用的是非Log4j來提供日誌輸出 這種狀況,默認是看不到dubbo的日誌輸出的,除非出現異常,被你當前系統的日誌框架攔截住了。我這裏就拿當前使用最多的日誌框架logback來作示例。咱們知道logback天生和slf4j進行了集成,因此要在項目裏面使用logback,調用slf4j暴露的接口就能夠。因此要把dubbo的日誌輸出切換到logback,也就變成了切換到slf4j了。一下列舉出幾種狀況來切換。  
1)經過設置jvm啓動參數來指定slf4j  
這個方式最簡單,可是也很粗暴,由於你須要在jvm啓動參數上動手腳,這樣致使對於項目部署來講不是方便。  
2)當前項目只依賴slf4j和logback的包,並無依賴log4j的包  
這個就須要嚴格肯定,不能存在log4j的相關接口的包,這個排查起來可能比較痛苦。若是使用maven那就更痛苦了,由於你可能會間接的依賴log4j的包,更可惡的就是有些jar包把log4j的接口直接打到它本身的包裏面,這種「捆綁銷售」讓咱們很爲難。若是排查清楚了,肯定沒有log4j,那麼這是最好了。  
3)編程方式來指定slf4j  
這種方式貌似比第一種更粗暴,可是若是遇到了那種"捆綁銷售"的現象,咱們還能怎麼辦呢?這裏的編程方式是怎麼來實現的呢?咱們從上面知道dubbo在選擇日誌提供方的時候是在static塊裏面,那麼就說明是在加載LoggerFactory的時候去選擇的。首先他是會檢查jvm環境中是否配置了"dubbo.application.logger"參數,若是配置了則使用指定的日誌提供方。那麼這裏的切入點就是要在加載LoggerFactory以前往jvm裏面設置"dubbo.application.logger"參數,雖然這種方式和第一種相似,可是這種方式對於應用來講更加的靈活。要在加載LoggerFactory以前植入這個參數,就須要知道何時加載LoggerFactory這個類的,既然LoggerFactory是dubbo裏面的,那就是啓動dubbo框架以前設置確定能夠。因爲大部分場景都是dubbo+spring的方式,因此這裏就經過spring來作這件事情吧。我作了下面一件事情:  

public class CustomContextLoaderListener extends ContextLoaderListener {
    static{
        //設置dubbo使用slf4j來記錄日誌
        System.setProperty("dubbo.application.logger","slf4j");
    }
}



<listener>
    <listener-class> com.xxx.xxx.CustomContextLoaderListener</listener-class>
</listener>



我寫了一個spring的ContextLoaderListener,裏面只有一個靜態塊,設置"dubbo.application.logger"參數。因爲dubbo+spring模式,dubbo框架是由spring框架來觸發初始化的,因此在這裏作手腳在適合不過了。那麼這樣我就能夠經過編程的方式來配置輸出日誌的提供方了。  
下面貼出logback的日誌配置:  

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <substitutionProperty name="LOG_HOME_DUBBO" value="C:/wls/dubbo"/>
    <timestamp key="byDate" datePattern="yyyyMMdd"/>
    <!-- dubbo log -->
    <appender name="dubboRolling" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <Encoding>UTF-8</Encoding>
        <file>${LOG_HOME_DUBBO}/MTP-DUBBO.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME_DUBBO}/DEMO-%d{yyyy-MM-dd}.%i-DUBBO.zip</fileNamePattern>
            <maxHistory>30</maxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>100MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <immediateFlush>true</immediateFlush>
        </encoder>
    </appender>
    <logger name="com.alibaba.dubbo" level="DEBUG">
        <appender-ref ref="dubboRolling"/>
    </logger>
</configuration>



對與使用其餘日誌提供方的,也能夠採起logback方式相似的途徑來達到效果。【想知道更多dubbo內容點這裏
相關文章
相關標籤/搜索