## 使用
private static final Logger logger = LoggerFactory.getLogger(ZookeeperRegistry.class);
原理
dubbo的日志实现机制比较简单 通过LoggerFactory来初始化具体的实现方式,Logger的实现通过loggerAdapter适配,LoggerAdapter接口使用@SPI注解,表示其使用的是dubbo的spi机制扩展,loggerAdapter的实现类有4种log4j,sl4j,jcl,jdk.
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.alibaba.dubbo.common.logger;import com.alibaba.dubbo.common.extension.SPI;import java.io.File;@SPIpublic interface LoggerAdapter { Logger getLogger(Class var1); Logger getLogger(String var1); Level getLevel(); void setLevel(Level var1); File getFile(); void setFile(File var1);}
Log4jLoggerAdapter实现如下
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.alibaba.dubbo.common.logger.log4j;import com.alibaba.dubbo.common.logger.LoggerAdapter;import java.io.File;import java.util.Enumeration;import org.apache.log4j.Appender;import org.apache.log4j.FileAppender;import org.apache.log4j.Level;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class Log4jLoggerAdapter implements LoggerAdapter { private File file; public Log4jLoggerAdapter() { try { Logger logger = LogManager.getRootLogger(); if (logger != null) { Enumerationappenders = logger.getAllAppenders(); if (appenders != null) { while(appenders.hasMoreElements()) { Appender appender = (Appender)appenders.nextElement(); if (appender instanceof FileAppender) { FileAppender fileAppender = (FileAppender)appender; String filename = fileAppender.getFile(); this.file = new File(filename); break; } } } } } catch (Throwable var6) { ; } } private static Level toLog4jLevel(com.alibaba.dubbo.common.logger.Level level) { if (level == com.alibaba.dubbo.common.logger.Level.ALL) { return Level.ALL; } else if (level == com.alibaba.dubbo.common.logger.Level.TRACE) { return Level.TRACE; } else if (level == com.alibaba.dubbo.common.logger.Level.DEBUG) { return Level.DEBUG; } else if (level == com.alibaba.dubbo.common.logger.Level.INFO) { return Level.INFO; } else if (level == com.alibaba.dubbo.common.logger.Level.WARN) { return Level.WARN; } else { return level == com.alibaba.dubbo.common.logger.Level.ERROR ? Level.ERROR : Level.OFF; } } private static com.alibaba.dubbo.common.logger.Level fromLog4jLevel(Level level) { if (level == Level.ALL) { return com.alibaba.dubbo.common.logger.Level.ALL; } else if (level == Level.TRACE) { return com.alibaba.dubbo.common.logger.Level.TRACE; } else if (level == Level.DEBUG) { return com.alibaba.dubbo.common.logger.Level.DEBUG; } else if (level == Level.INFO) { return com.alibaba.dubbo.common.logger.Level.INFO; } else if (level == Level.WARN) { return com.alibaba.dubbo.common.logger.Level.WARN; } else { return level == Level.ERROR ? com.alibaba.dubbo.common.logger.Level.ERROR : com.alibaba.dubbo.common.logger.Level.OFF; } } public com.alibaba.dubbo.common.logger.Logger getLogger(Class key) { return new Log4jLogger(LogManager.getLogger(key)); } public com.alibaba.dubbo.common.logger.Logger getLogger(String key) { return new Log4jLogger(LogManager.getLogger(key)); } public com.alibaba.dubbo.common.logger.Level getLevel() { return fromLog4jLevel(LogManager.getRootLogger().getLevel()); } public void setLevel(com.alibaba.dubbo.common.logger.Level level) { LogManager.getRootLogger().setLevel(toLog4jLevel(level)); } public File getFile() { return this.file; } public void setFile(File file) { }}
最重要的是LoggerFactory类
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.alibaba.dubbo.common.logger;import com.alibaba.dubbo.common.extension.ExtensionLoader;import com.alibaba.dubbo.common.logger.jcl.JclLoggerAdapter;import com.alibaba.dubbo.common.logger.jdk.JdkLoggerAdapter;import com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter;import com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter;import com.alibaba.dubbo.common.logger.support.FailsafeLogger;import java.io.File;import java.util.Iterator;import java.util.Map.Entry;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;public class LoggerFactory { //缓存Classs名称和Logger具体实现映射 private static final ConcurrentMapLOGGERS = new ConcurrentHashMap(); //当前LoggerAdapter实现 volatile保证内存可见性 private static volatile LoggerAdapter LOGGER_ADAPTER; private LoggerFactory() { } //通过spi机制 得到LoggerAdapter实现 public static void setLoggerAdapter(String loggerAdapter) { if (loggerAdapter != null && loggerAdapter.length() > 0) { setLoggerAdapter((LoggerAdapter)ExtensionLoader.getExtensionLoader(LoggerAdapter.class).getExtension(loggerAdapter)); } } public static void setLoggerAdapter(LoggerAdapter loggerAdapter) { if (loggerAdapter != null) { Logger logger = loggerAdapter.getLogger(LoggerFactory.class.getName()); logger.info("using logger: " + loggerAdapter.getClass().getName()); //此处设置LoggerAdapter实现 LOGGER_ADAPTER = loggerAdapter; //此处遍历LOGGERS缓存,设置value值(FailsafeLogger类)的成员变量Logger实现 Iterator i$ = LOGGERS.entrySet().iterator(); while(i$.hasNext()) { Entry entry = (Entry)i$.next(); ((FailsafeLogger)entry.getValue()).setLogger(LOGGER_ADAPTER.getLogger((String)entry.getKey())); } } } public static Logger getLogger(Class key) { FailsafeLogger logger = (FailsafeLogger)LOGGERS.get(key.getName()); if (logger == null) { LOGGERS.putIfAbsent(key.getName(), new FailsafeLogger(LOGGER_ADAPTER.getLogger(key))); logger = (FailsafeLogger)LOGGERS.get(key.getName()); } return logger; } public static Logger getLogger(String key) { FailsafeLogger logger = (FailsafeLogger)LOGGERS.get(key); if (logger == null) { LOGGERS.putIfAbsent(key, new FailsafeLogger(LOGGER_ADAPTER.getLogger(key))); logger = (FailsafeLogger)LOGGERS.get(key); } return logger; } public static Level getLevel() { return LOGGER_ADAPTER.getLevel(); } public static void setLevel(Level level) { LOGGER_ADAPTER.setLevel(level); } public static File getFile() { return LOGGER_ADAPTER.getFile(); } //当调用LoggerFactory.getLogger(ZookeeperRegistry.class)方法时,触发jvm加载当调用LoggerFactory类,从而执行static代码块。 //首先获取系统变量,如果指定了实现方式 则设置LoggerAdapter成员变量 //如果没指定,按照Log4jLoggerAdapter,Slf4jLoggerAdapter,JclLoggerAdapter,JdkLoggerAdapter顺序依次设置LoggerAdapter实现, //比如设置Log4jLoggerAdapter时 没有引入对应依赖,则抛ClassNotFound依次,接着尝试设置其他LoggerAdapter static { String logger = System.getProperty("dubbo.application.logger"); if ("slf4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } else if ("jcl".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } else if ("log4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } else if ("jdk".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } else { try { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } catch (Throwable var6) { try { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } catch (Throwable var5) { try { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } catch (Throwable var4) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } } } } }}