Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何找到log4j默认初始化中使用的URL?_Java_Logging_Log4j - Fatal编程技术网

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

Java 如何找到log4j默认初始化中使用的URL?,java,logging,log4j,Java,Logging,Log4j,执行查找和使用URL进行配置的过程。之后,您如何找到最终使用的URL,而不必自己编写相同的过程?(如果您必须自己编写代码,您可能无法获得与log4j完全相同的代码,并且它可能会在将来的版本中发生更改。)所使用的过程是在LogManager中的静态初始值设定项块中硬编码的,因此似乎没有一种方法可以钩住它。它告诉你发生了什么的唯一地方是 LogLog.debug("Using URL ["+url+"] for automatic log4j configuration."); 但是LogLog本

执行查找和使用URL进行配置的过程。之后,您如何找到最终使用的URL,而不必自己编写相同的过程?(如果您必须自己编写代码,您可能无法获得与log4j完全相同的代码,并且它可能会在将来的版本中发生更改。)

所使用的过程是在
LogManager
中的静态初始值设定项块中硬编码的,因此似乎没有一种方法可以钩住它。它告诉你发生了什么的唯一地方是

LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
但是
LogLog
本身是硬编码的,可以对这些消息使用
System.out.println
,因此我能看到的唯一可能性是打开调试(
-Dlog4j.debug=true
),并在初始化log4j之前以某种方式连接到
System.setOut
,然后解析调试日志消息。但这可能比自己编写配置过程更脆弱

即使如此,在默认配置过程之后也可能应用了其他编程配置(例如Spring
Log4jConfigListener
)-不一定有一个这样的配置URL


可能值得加入一个log4j特性请求,将配置文件搜索代码分解成一个静态方法,您可以从其他地方调用该方法,但当您可能需要处理log4j的早期版本时,这不会有帮助。

如果您愿意使用AspectJ LTW(加载时编织),您可以看看Ian Roberts提到的
LogManager
的静态初始化。在log4j 1.2.14中,它如下所示:

静态{
// (...)
//如果没有默认的init覆盖,则获取资源
//由用户或默认配置文件指定。
if(override==null | |“false”。equalsIgnoreCase(override)){
// (...)
URL=null;
// (...)    
//如果我们有一个非空的url,那么委托其余的url
//配置至选项转换器。选择并配置方法。
如果(url!=null){
debug(“使用URL[“+URL+”]进行自动log4j配置”);
选项转换器。选择并配置(
url、configuratorClassName、LogManager.getLoggerRepository()
);
}否则{
调试(“找不到资源:[“+configurationOptionStr+”]);
}
}
}
显然,如果可以确定默认URL,那么将在静态块内的某个点调用
OptionConverter.selectAndConfigure(URL,…)
,以便使用该URL初始化log4j

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

import java.net.URL;
导入org.apache.log4j.helpers.OptionConverter;
导入org.apache.log4j.LogManager;
公共方面日志4JASPECT{
之前(URL默认URL):
内部(日志管理器)&&
cflow(静态初始化(日志管理器))&&
调用(*选项转换器。选择并配置(URL,…)&&
参数(默认URL,…)
{
System.out.println(“log4j default URL=“+defaultURL”);
}
}
在散文中,该代码意味着:

  • 如果我们是在类LogManager和
  • 在静态类初始化和
  • 选项转换器。选择并配置
    将被调用
  • 然后捕获第一个参数(URL)并
  • 将其打印到控制台(您也可以执行其他操作)
如果没有默认URL,则不会打印任何内容。您可以将URL分配给任何类或任何您喜欢的静态成员,而不是打印URL

这是一个解决你的问题的方法,我测试过了,效果很好。我会很高兴收到赏金来回答你的问题,即使这个解决方案可能使用了你没有想到的技术。但它解决了问题。:-)



编辑:在没有找到默认URL的情况下,也可以显式截取日志调用,即使我认为没有必要这样做。我只是想提一下。

在java调用中插入以下内容:

-Dlog4j.configDebug=true

仅此而已。

如果您可以设置自己的配置程序,您可以执行以下操作:

设置JAVA系统属性:-Dlog4j.configuratorClass=MyConfigurator 然后让您的configurator实例拦截doConfigure调用

public class MyConfigurator implements Configurator
{
    public static URL url;

    @Override
    public void doConfigure(URL url, LoggerRepository repository)
    {
        this.url = url;
        new PropertyConfigurator().doConfigure(url, repository);
    }
}

我正在为我的程序寻找一种找到这些信息的方法。这表明了另一个聪明的想法:通过在类路径的前面插入您自己的来覆盖配置程序……您的答案信息量惊人。非常感谢。这是一个很好的方法来处理一些显然无法完全按照我希望的方式完成的事情。>每天1000次。令人印象深刻:P