小编典典

您如何找到log4j默认初始化中使用的URL?

java

Log4j的默认初始化通过查找和使用URL进行配置的过程。然后,您如何找出最终使用的URL,而不必自己编写相同的过程?(如果您必须自己编写代码,则可能无法获得与log4j完全相同的代码,并且在将来的发行版中它可能会更改。)


阅读 211

收藏
2020-11-16

共1个答案

小编典典

如果您愿意使用AspectJ LTW(加载时编织),则可以看看LogManagerIan Roberts提到的静态初始化。在 log4j
1.2.14中,
它看起来像这样:

static {
    // (...)
    // if there is no default init override, then get the resource
    // specified by the user or the default config file.
    if (override == null || "false".equalsIgnoreCase(override)) {
        // (...)
        URL url = null;

        // (...)    
        // If we have a non-null url, then delegate the rest of the
        // configuration to the OptionConverter.selectAndConfigure method.
        if (url != null) {
            LogLog.debug("Using URL [" + url + "] for automatic log4j configuration.");
            OptionConverter.selectAndConfigure(
                url, configuratorClassName, LogManager.getLoggerRepository()
            );
        } else {
            LogLog.debug("Could not find resource: [" + configurationOptionStr + "].");
        }
    }
}

显然,如果可以确定默认URL,OptionConverter.selectAndConfigure(URL, ..)则将在静态块内的某个位置调用该URL
,以便使用该URL 初始化 log4j

通过 AspectJ ,捕获该方法调用非常简单:

import java.net.URL;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.LogManager;

public aspect Log4jAspect {
    before(URL defaultURL) :
        within(LogManager) &&
        cflow(staticinitialization(LogManager)) &&
        call(* OptionConverter.selectAndConfigure(URL, ..)) &&
        args(defaultURL, ..)
    {
        System.out.println("log4j default URL = " + defaultURL);
    }
}

在散文中,此代码表示:

  • 如果我们在LogManager类中,并且
  • 在静态类初始化的控制流程中,并且
  • OptionConverter.selectAndConfigure叫做,
  • 然后捕获第一个参数(URL),然后
  • 将其打印到控制台(您也可以做其他事情)。

如果没有默认URL,则不会打印任何内容。无需打印URL,您可以将其分配给任何类或任何您喜欢的静态成员。

这是针对您的问题的解决方案,我对其进行了测试并成功运行。即使解决方案使用的是您没有想到的技术,我也很高兴收到悬赏解答您的问题。但这解决了问题。:-)


Edit: It is also possible to explicitly intercept the log call in the case
that no default URL is found, even though I do not think it is necessary. I
just wanted to mention it.

2020-11-16