最近接手一個(gè)廠商移交的項(xiàng)目,發(fā)現(xiàn)后管子系統(tǒng)不打印日志。
項(xiàng)目使用的logback
本地?cái)帱c(diǎn)調(diào)試發(fā)現(xiàn)logback-classic?jar沖突導(dǎo)致?打出的war中沒有?相關(guān)的jar
解決方法:
去除pom?文件中多余的?logback-classic?應(yīng)用,只保留最新版本的。?重新打包環(huán)境后,日志可正常輸出。
java是如何加載logback
我們都知道,當(dāng)我們需要引入logback時(shí),是不是需添加任何配置 來引入logback.xml文件的,只需要將logback.xml配置文件定義到resources目錄即可,那么框架會(huì)自動(dòng)加載這個(gè)日志配置文件,并按照配置幫我自己生成日志到指定的目錄下,那么它是如何自動(dòng)加載的。
很顯然第一個(gè)想到就是通過spi。
在說明如何加載的一個(gè)前提是,你需要知道sl4j、log4j、logback之間的關(guān)系。
可以看這篇 SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系
這里我還是貼一張圖來說明一下:
slf4j是一個(gè)門面,而logback、log4j都是這個(gè)門面的實(shí)現(xiàn)。
所以logback肯定是在sl4j.jar中加載的。
3.1、回顧下我們獲取日志對(duì)象是如何獲取的
上面方法會(huì)加 //加載org/slf4j/impl/StaticLoggerBinder.class這個(gè)類這個(gè)類,那么我們先看下slf4j下有沒有這個(gè)類:
//通過LoggerFactory獲取一個(gè)logger對(duì)象
final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
//通過LoggerFactory獲取一個(gè)logger對(duì)象,那么我們看下這個(gè)方法如下:
它果然是在slf4j這個(gè)門面中定義的。
public static Logger getLogger(Class<?> clazz) {
? ?//看下是如何獲取logger 的
? ?Logger logger = getLogger(clazz.getName());
? ?if (DETECT_LOGGER_NAME_MISMATCH) {
? ? ? ?Class<?> autoComputedCallingClass = Util.getCallingClass();
? ? ? ?if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
? ? ? ? ? ?Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),
? ? ? ? ? ? ? ? ? ? ? ? ? ?autoComputedCallingClass.getName()));
? ? ? ? ? ?Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
? ? ? ?}
? ?}
? ?return logger;
}
?
getLogger
public static Logger getLogger(String name) {
? ? //看下這個(gè)方法
? ? ILoggerFactory iLoggerFactory = getILoggerFactory();
? ? return iLoggerFactory.getLogger(name);
}
?
public static ILoggerFactory getILoggerFactory() {
? ? ?if (INITIALIZATION_STATE == UNINITIALIZED) {
? ? ? ? ?synchronized (LoggerFactory.class) {
? ? ? ? ? ? ?if (INITIALIZATION_STATE == UNINITIALIZED) {
? ? ? ? ? ? ? ? ?INITIALIZATION_STATE = ONGOING_INITIALIZATION;
? ? ? ? ? ? ? ? ?//看這個(gè)方法
? ? ? ? ? ? ? ? ?performInitialization();
? ? ? ? ? ? ?}
? ? ? ? ?}
? ? ?}
? ? ?......
} ? ??
?
查看performInitialization 的bind方法
? private final static void performInitialization() {
? ? ?//綁定
? ? ?bind();
? ? ?if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
? ? ? ? ?versionSanityCheck();
? ? ?}
?}
private final static void bind() {
? ? ....
? ? staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
? ? .....
}
?
?private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
static Set<URL> findPossibleStaticLoggerBinderPathSet() {
? ? ?// use Set instead of list in order to deal with bug #138
? ? ?// LinkedHashSet appropriate here because it preserves insertion order
? ? ?// during iteration
? ? ?Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
? ? ?try {
? ? ? ? ?ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
? ? ? ? ?Enumeration<URL> paths;
? ? ? ? ?if (loggerFactoryClassLoader == null) {
? ? ? ? ?//加載org/slf4j/impl/StaticLoggerBinder.class這個(gè)類
? ? ? ? ? ? ?paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
? ? ? ? ?} else {
? ? ? ? ? ? ?paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
? ? ? ? ?}
? ? ? ? ?while (paths.hasMoreElements()) {
? ? ? ? ? ? ?URL path = paths.nextElement();
? ? ? ? ? ? ?staticLoggerBinderPathSet.add(path);
? ? ? ? ?}
? ? ?} catch (IOException ioe) {
? ? ? ? ?Util.report("Error getting resources from path", ioe);
? ? ?}
? ? ?return staticLoggerBinderPathSet;
?}
這個(gè)jar下沒有這個(gè)路徑,那么肯定是在slf4j-logback.jar,slf4j-log4j.jar這樣的jar包下實(shí)現(xiàn)的。
搜索logback相關(guān)jar,發(fā)現(xiàn)在這個(gè)jar下有這個(gè)路徑類
然后繼續(xù),看bind方法后面
如果你的項(xiàng)目中只有l(wèi)ogback-classic這一個(gè)Jar,沒有其它日志框架,那么直接點(diǎn)到這個(gè)方法中就到logback方法中,如下:
這個(gè)類中靜態(tài)方法就會(huì)執(zhí)行
看下init方法
autoConfig()中findURLOfDefaultConfigurationFile方法
再繼續(xù)看autoConfig()方法
后面就不在細(xì)說明,可以直接到源碼里面看看。
這里整個(gè)logback自動(dòng)注入的過程就完結(jié)了
?
具體排查過程待補(bǔ)充
最終原因?jar包沖突?文章來源:http://www.zghlxwxcb.cn/news/detail-809060.html
表現(xiàn)?war包中沒有?logback-classic.jar?這個(gè)文件,? 解決沖突后 ,logback-classic.jar?出現(xiàn)了?問題解決。文章來源地址http://www.zghlxwxcb.cn/news/detail-809060.html
到了這里,關(guān)于由jar包沖突導(dǎo)致的logback日志不輸出的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!