Bootstrap

排查log4j:WARN No appenders could be found for logger (org.apache.dubbo.common.logger.LoggerFactory)

日志信息

有关启动dubbo服务,报出如下错误:

log4j:WARN No appenders could be found for logger (org.apache.dubbo.common.logger.LoggerFactory).
log4j:WARN Please initialize the log4j system properly.

在这里插入图片描述
用过log4j的同学应该能看出来,就是少个log4j.properties配置文件,不知道dubbo为什么默认使用的是log4j,咱还是看下源码,在依赖包中找到目标类:

public class LoggerFactory {
    // search common-used logging frameworks
    static {
        String logger = System.getProperty("dubbo.application.logger", "");
        switch (logger) {
            case "slf4j":
                setLoggerAdapter(new Slf4jLoggerAdapter());
                break;
            case "jcl":
                setLoggerAdapter(new JclLoggerAdapter());
                break;
            case "log4j":
                setLoggerAdapter(new Log4jLoggerAdapter());
                break;
            case "jdk":
                setLoggerAdapter(new JdkLoggerAdapter());
                break;
            case "log4j2":
                setLoggerAdapter(new Log4j2LoggerAdapter());
                break;
            default:
                List<Class<? extends LoggerAdapter>> candidates = Arrays.asList(
                        Log4jLoggerAdapter.class,
                        Slf4jLoggerAdapter.class,
                        Log4j2LoggerAdapter.class,
                        JclLoggerAdapter.class,
                        JdkLoggerAdapter.class
                );
                for (Class<? extends LoggerAdapter> clazz : candidates) {
                    try {
                        setLoggerAdapter(clazz.newInstance());
                        break;
                    } catch (Throwable ignored) {
                    }
                }
        }
    }

小编用的是dubbo2.7.7,显然这是一个静态代码块,一启动及开始加载,首先找系统属性 dubbo.application.logger ,没有就开始加载LoggerAdapter适配器,显然Log4jLoggerAdapter排到了第一位,就用log4j了。

解决办法:

1 使用log4j,添加log4j.properties配置文件
2 启动类添加 System.setProperty(“dubbo.application.logger”,“log4j2”) 指定项目中使用的日志框架
3 设置jvm启动参数 -Ddubbo.application.logger=log4j2

关于dubbox:

用过dubbox的童鞋应该没出现过此类问题,这是因为源码已修改,这也是可以采取的解决方案,下载dubbo源码,然后自己修改源代码,重新打包jar。看下dubbox中此类的实现方式:

// 查找常用的日志框架
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());
                   }
               }
           }
   	}
}

dubbox中如果出现异常还是会再使用Slf4jLoggerAdapter适配一次,大多项目都是采用slf4j门面,所以没有此问题。

;