当前位置: 首页 > 面试题库 >

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

颛孙沈义
2023-03-14
问题内容

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


问题答案:

如果您愿意使用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.



 类似资料:
  • 问题内容: 在运行时,我经常创建/修改 log4j Logger,Appenders,Levels,Layouts,并且有时需要将所有内容重置为默认值。 Log4j 系统具有定义明确的 默认初始化过程 ,该 过程 在将 log4j 类加载到内存时执行。有什么方法可以稍后在运行时以编程方式重新执行整个过程吗? 我在 log4j 文档中找到了几种方法,但是不确定它们中的任何一种是否可以执行 默认初始化

  • 考虑以下代码 VS2013编译器发出以下警告: 警告C4351:新行为:数组“B::member”的元素将默认初始化1 这里有记载 使用C 11,并应用“默认初始化”的概念,意味着B. part的元素将不会被初始化。 但我认为,成员{}应该执行值初始化,而不是默认初始化。VS2013编译器是否损坏? 8.5美元/6 默认初始化类型为T的对象意味着:-如果T是(可能是cv限定的)类类型(第9条),则

  • 场景如下:我有一个现有的web应用程序,它通过servlet初始化log4j: 不,我想重写这个初始化通过一个外部文件传递log4j.configurationJVM ardument:-Dlog4j.configuration=file:/usr/本地/log4j.xml 当我启动应用程序服务器时,我可以看到外部文件首先被拾取,但随后通过初始化servlet的内部文件将覆盖这些更改。 我的问题是

  • 根据我的参考,基元类型具有默认值,对象为null。我测试了一段代码。 行将是指向变量的错误,表示,而在给定引用中,将作为默认值。但是,使用下面给定的代码,它将实际打印。 第一个代码可能会出什么问题?类变量的行为是否与局部变量不同?

  • 问题内容: 将log4j添加到我的应用程序后,每次执行我的应用程序时,都会得到以下输出: 看来这意味着缺少配置文件。此配置文件应位于何处,什么是良好的入门内容? 我使用纯Java开发桌面应用程序。因此没有网络服务器等… 问题答案: 默认情况下,在上查找名为或的文件。 您可以按照此处所述通过设置系统属性来控制它用来初始化自身的文件(查找“默认初始化过程”部分)。 例如: 将导致在类路径上查找名为的文

  • 问题内容: 当搜寻通过Java语言规范来回答这个问题),我学到的是 在初始化类之前,必须先初始化其直接超类, 但不初始化由该类实现的接口。 同样,在初始化接口之前,不会初始化接口的超级接口。 出于我自己的好奇心,我尝试了一下,并且未如预期的那样对接口进行了初始化。 该程序打印 但是,如果接口声明了一个方法,则确实会发生初始化。考虑给定的接口 然后上面的相同程序将打印 换句话说,接口的字段已初始化(