如何开启Dubbo框架内部的日志?

欢迎加入DUBBO交流群:259566260

这里将对如何在自己的项目里面开启dubbo框架自己的日志,并对输出的日志进行控制。在讲这些之前,先看看dubbo在处理日志的时候是怎么做的?  

在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选择日志提供方的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 查找常用的日志框架
     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能够在项目里面输出日志。      
一、你项目当前使用的是Log4j来提供日志输出      
恭喜你,你不用做过多的处理就可以开启dubbo的日志,因为dubbo默认就是使用log4j。你唯一需要做的就是配置一个name是"com.alibaba.dubbo"的logger就可以了,然后关联到对应的appender。如下:    

?
1
2
3
4
5
6
7
8
9
10
11
12
< 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 >



二、你的项目当前使用的是非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来做这件事情吧。我做了下面一件事情:    

?
1
2
3
4
5
6
public class CustomContextLoaderListener extends ContextLoaderListener {
     static {
         //设置dubbo使用slf4j来记录日志
         System.setProperty( "dubbo.application.logger" , "slf4j" );
     }
}



?
1
2
3
< listener >
     < listener-class > com.xxx.xxx.CustomContextLoaderListener</ listener-class >
</ listener >



我写了一个spring的ContextLoaderListener,里面只有一个静态块,设置"dubbo.application.logger"参数。由于dubbo+spring模式,dubbo框架是由spring框架来触发初始化的,所以在这里做手脚在适合不过了。那么这样我就可以通过编程的方式来配置输出日志的提供方了。      
下面贴出logback的日志配置:      

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? 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内容点这里      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值