如何捕捉 "log4j:WARN No appenders could be found for logger"?

How-to catch "log4j:WARN No appenders could be found for logger"?

我想处理这个错误以设置替代配置 log4j。这可能吗?

我没有任何堆栈跟踪,只有日志的警告

log4j:WARN No appenders could be found for logger (agent.Test1Agent.JavaAgent). 
log4j:WARN Please initialize the log4j system properly. 
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

您可以通过在类路径中提供默认配置文件来设置备用 log4j 配置。由于 log4j 使用 Thread.getContextClassLoader().getResource() 来定位默认配置文件并且不直接检查文件系统,因此它应该包含在您的 jar 中。因此,如果没有提供外部配置,它将退回到默认配置。 有关详细信息,请参阅 http://logging.apache.org/log4j/1.2/faq.html#noconfig

没有办法正确地做你想做的事,因为 log4j 不会抛出任何异常,也不会在配置错误的情况下以某种方式发出通知。但这是可能的。
参见下面的 PoC

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.spi.Configurator;

import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;

public class Log4jAlternativeConfig {

    private static class PrintStreamCallbackSupportDecorator extends PrintStream {

        public PrintStreamCallbackSupportDecorator(OutputStream out, Callback callback) {
            super(out);
            this.callback = callback;
        }

        public interface Callback {
            public void onPrintln(String x);
        }

        private Callback callback;

        @Override
        public void println(String x) {
            callback.onPrintln(x);
            super.println(x);
        }
    }

    public static void main(String[] args) {

        PrintStreamCallbackSupportDecorator.Callback callback = new PrintStreamCallbackSupportDecorator.Callback() {
            @Override
            public void onPrintln(String x) {
                if (x.startsWith("log4j:WARN No appenders could be found for logger")) {
                    Configurator configurator = new PropertyConfigurator();
                    URL url = Loader.getResource("log4j_alternative.properties");
                    configurator.doConfigure(url, LogManager.getLoggerRepository());
                }
            }
        };

        System.setErr(new PrintStreamCallbackSupportDecorator(System.err, callback));

        Logger log = LogManager.getLogger(Log4jAlternativeConfig.class);

        //causes "No appenders could be found for logger" warning
        log.error("test");

        //should be logged as configured in log4j_alternative.properties
        log.error("test 2");
    }
}

该解决方案并不完美,但它有效。