【问题标题】:Log4j: from where it initializes itselfLog4j:从哪里初始化自己
【发布时间】:2010-07-30 18:35:55
【问题描述】:

我们将 Log4j 1.2.15 与我们的普通 Swing 应用程序捆绑在一起,并在启动时从文件系统加载我们自己的属性文件:

import org.apache.log4j.*;

...
System.setProperty("log4j.defaultInitOverride", "true");
...
File log4jPropertiesFile = ...
PropertyConfigurator.configure(log4jPropertiesFile.getAbsolutePath());
...

在我们从客户那里获得的日志中,输出看起来不像我们在属性文件中定义的那样,我们确信只有极少数人自己编辑了文件。

如果用户机器上的某个地方有另一个可用的配置文件,Log4j 会以某种方式覆盖我们的设置吗?我们如何防止使用它?

【问题讨论】:

  • 你确定有一个 PropertyConfigurator.configure(File file) 方法吗? Log4j 1.2.16 API 中没有 ...
  • @PeterMmm:在注意到您的评论之前,我也偶然发现了这种差异。我查看的文档是针对 1.2.16 的,所以它离 OP 不远,不应该看到如此剧烈的 API 更改。有什么不对劲;我向 OP 寻求解释。
  • 你们俩都是对的,我上面的代码示例是错误的。我们使用的是绝对文件路径,而不是文件实例。我已经更正了。

标签: java log4j


【解决方案1】:

有一整段in the docs详细说明了Log4j如何初始化自己:

确切的默认初始化算法定义如下:

  1. 将 log4j.defaultInitOverride 系统属性设置为任何其他值然后“false”将导致 log4j 跳过默认初始化过程(此过程)。
  2. 将资源字符串变量设置为 log4j.configuration 系统属性的值。指定默认初始化文件的首选方法是通过 log4j.configuration 系统属性。如果未定义系统属性 log4j.configuration,则将字符串变量资源设置为其默认值“log4j.properties”。
  3. 尝试将资源变量转换为 URL。
  4. 如果资源变量无法转换为 URL,例如由于 MalformedURLException,则通过调用 org.apache.log4j.helpers.Loader.getResource(resource, Logger.class) 从类路径中搜索资源返回一个 URL。请注意,字符串“log4j.properties”构成格式错误的 URL。有关搜索位置的列表,请参阅 Loader.getResource(java.lang.String)。
  5. 如果找不到 URL,则中止默认初始化。否则,从 URL 配置 log4j。 PropertyConfigurator 将用于解析 URL 以配置 log4j,除非 URL 以“.xml”扩展名结尾,在这种情况下将使用 DOMConfigurator。您可以选择指定自定义配置器。 log4j.configuratorClass 系统属性的值被视为自定义配置器的完全限定类名。您指定的自定义配置器必须实现配置器接口。

诚然,这让人难以理解。基本上,你能做的最简单的事情就是把log4j.properties放在你应用的类路径上,它就会被找到。其他一切都是……技巧。就个人而言,我有时会在我的main 中明确调用BasicConfigurator 类,有时会配置(硬编码)一些可能出现在文件中的东西......无论我的情况需要什么。您可以完全以编程方式初始化 log4j,这会使配置文件的问题变得毫无意义。虽然它也会使您的配置完全不灵活。

【讨论】:

  • 感谢您的回答,卡尔。我们不会将log4j.properties 添加到类路径中,因为安装位置通常是只读的,而且我不喜欢将应用程序的设置目录(log4j.properties 所在的位置)添加到类路径中。
  • 我注意到您的代码摘录和 log4j 文档之间存在差异:PropertyConfigurator 似乎没有 configure(File) 方法!你能解释一下吗,也许能提供更多细节?
  • 您能接受您的客户根本无法处理log4j.properties 文件吗?然后把它放到你的.jar 文件的根目录下!这既在类路径上,又很难访问。
  • 这不行,因为有时我们必须告诉客户在文件中添加一行或另一行以增加日志记录详细信息。
  • @mklhmnn 那么为什么不为客户端创建一个 API,它会在运行时改变 log4j 配置呢?或者将使用您的应用程序将定义的命令行参数覆盖 jar 中的 log4j.xml 中的默认值?
猜你喜欢
  • 1970-01-01
  • 2014-04-27
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
相关资源
最近更新 更多