日志结构
commons和slf4j是日志规范;其他的是日志的具体实现
日志使用
//001 声明使用 外观接口private static final Logger LOGGER = LoggerFactory.getLogger(DeployRecordController.class);
具体分析
//002 获得类名
public static Logger getLogger(Class clazz) {
return getLogger(clazz.getName());
}
public static Logger getLogger(String name) {
//003 获得logger工厂
ILoggerFactory iLoggerFactory = getILoggerFactory();
//034 通过类名返回logger对象
return iLoggerFactory.getLogger(name);
}
public static ILoggerFactory getILoggerFactory() {
//004 判断是否进行初始化
if (INITIALIZATION_STATE == UNINITIALIZED) {
INITIALIZATION_STATE = ONGOING_INITIALIZATION;
//005 初始化
performInitialization();
}
//033 错误处理
switch (INITIALIZATION_STATE) {
case SUCCESSFUL_INITIALIZATION:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case NOP_FALLBACK_INITIALIZATION:
return NOP_FALLBACK_FACTORY;
case FAILED_INITIALIZATION:
throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
case ONGOING_INITIALIZATION:
// support re-entrant behavior.
// See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
return TEMP_FACTORY;
}
throw new IllegalStateException("Unreachable code");
}
private final static void performInitialization() {
//006
bind();
if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
//020 获取JDK的版本与Slf4j支持的版本进行比较,如果版本相同则通过,如果不相同,那么进行失败提示
versionSanityCheck();
}
}
private final static void bind() {
try {
//007 获得实现日志的加载路径
Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
//014 查看路径是否合法
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
//015 初始化StaticLoggerBinder对象
StaticLoggerBinder.getSingleton();
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
//016 寻找合适的实现方式使用
reportActualBinding(staticLoggerBinderPathSet);
emitSubstituteLoggerWarning();
} catch (NoClassDefFoundError ncde) {
//017 如果找不到指定的类,就会报错!
String msg = ncde.getMessage();
if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.report("Defaulting to no-operation (NOP) logger implementation");
Util.report("See " + NO_STATICLOGGERBINDER_URL
+ " for further details.");
} else {
failedBinding(ncde);
throw ncde;
}
} catch (java.lang.NoSuchMethodError nsme) {
//018 如果找不到指定的类,就会报错!
String msg = nsme.getMessage();
if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
INITIALIZATION_STATE = FAILED_INITIALIZATION;
Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
Util.report("Your binding is version 1.5.5 or earlier.");
Util.report("Upgrade your binding to version 1.6.x.");
}
throw nsme;
} catch (Exception e) {
//019 报错!
failedBinding(e);
throw new IllegalStateException("Unexpected initialization failure", e);
}
private static Set findPossibleStaticLoggerBinderPathSet() {
//008 创建一个Set,因为有可能有多个实现。
Set staticLoggerBinderPathSet = new LinkedHashSet();
try {
//009 获取LoggerFactory的类加载器!
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration paths;
//010 如果获取不到类加载器则说明是系统加载器,那么在系统路径下获取该资源文件
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
//011 获取到了类加载器,则用该类加载器加载指定的资源文件。
paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
}
//012 解析类加载器的地址。
while (paths.hasMoreElements()) {
URL path = (URL) paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException ioe) {
Util.report("Error getting resources from path", ioe);
}
//013 返回加载器地址的集合
return staticLoggerBinderPathSet;
}
//021 对比jdk和slfj4的版本
private final static void versionSanityCheck() {
try {
String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
boolean match = false;
for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
match = true;
}
}
if (!match) {
Util.report("The requested version " + requested
+ " by your slf4j binding is not compatible with "
+ Arrays.asList(API_COMPATIBILITY_LIST).toString());
Util.report("See " + VERSION_MISMATCH + " for further details.");
}
} catch (java.lang.NoSuchFieldError nsfe) {
// given our large user base and SLF4J's commitment to backward
// compatibility, we cannot cry here. Only for implementations
// which willingly declare a REQUESTED_API_VERSION field do we
// emit compatibility warnings.
} catch (Throwable e) {
// we should never reach here
Util.report("Unexpected problem occured during version sanity check", e);
}
}
