05.dubbo日志机制
dubbo对于其日志机制,设计的还是比较灵活的,可以自由配置选用哪种日志框架。这样就能达成跟你的项目所采用的日志框架一致的目的。这是做中间件开发的同学一个值得学习的设计。tomcat是一直到8点几版本才开始能方便的支持不同日志框架的对接。早些版本都是要替换jar之类的办法,还是有一点麻烦的。有些开源框架只支持一种日志框架对接,这样就不是很好了。
入手处
分析其日志机制,从哪边入手呢?随便翻一个其用到日志的类,就可以作为入口了。比如我们前面刚讲过的ExtensionLoader。
private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);
public interface Logger {}
public class LoggerFactory {}
日志机制实现分析
Logger是一个接口。dubbo为其做了Log4jLogger、Slf4jLogger、JdkLogger等实现。
LoggerFactory的getLogger主要由LoggerAdapter(LOGGER_ADAPTER)完成。LoggerAdapter有对应slf4j、log4j等实现。
public static Logger getLogger(Class<?> key) {
FailsafeLogger logger = LOGGERS.get(key.getName());
if (logger == null) {
LOGGERS.putIfAbsent(key.getName(), new FailsafeLogger(LOGGER_ADAPTER.getLogger(key)));// LOGGER_ADAPTER完成Logger实例的获取
logger = LOGGERS.get(key.getName());
}
return logger;
}
那LOGGER_ADAPTER是什么时候什么逻辑指定的呢?
LoggerFactory的static块中指定的:
static {
String logger = System.getProperty("dubbo.application.logger");// 根据指定的日志框架名称设置LOGGER_ADAPTER
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());
}
}
}
}
}
public static void setLoggerAdapter(LoggerAdapter loggerAdapter) {
if (loggerAdapter != null) {
Logger logger = loggerAdapter.getLogger(LoggerFactory.class.getName());
logger.info("using logger: " + loggerAdapter.getClass().getName());
LoggerFactory.LOGGER_ADAPTER = loggerAdapter; // 设置LOGGER_ADAPTER
for (Map.Entry<String, FailsafeLogger> entry : LOGGERS.entrySet()) {
entry.getValue().setLogger(LOGGER_ADAPTER.getLogger(entry.getKey()));
}
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!