欢迎加入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());
}
}
}
}
}
|
一、你项目当前使用的是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
>
|
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
>
|
下面贴出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
>
|