从Log4j2 XML配置中以编程方式获取属性

8
在我的Log4j2配置文件中,我有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" strict="true" name="XMLConfig" packages="org.apache.logging.log4j.test">
    <Properties>
        <Property name="baseDir">log-dir/</Property>
        <Property name="defaultLogfileName">default-log-file</Property>
    </Properties>

现在,在我的一些代码中,我创建自定义记录器。我需要访问"baseDir"的值并更改它。我尝试使用上下文中的getProperties来实现:

LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration();
configuration.getProperties();

但是返回的地图有“主机名”和“上下文名称”键。而不是我正在寻找的属性地图。 我想我可能可以从rootLogger获取它:
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration configuration = context.getConfiguration()
for (Property p : configuration.getRootLogger().getPropertyList())
{
    ...
}

但是这会导致 NullPointerException,因为 getPropertyList 返回 null。
那么,我该如何访问名为“baseDir”的属性,以便可以编程方式创建一个新的记录器,但使用不同的基目录?

它对我不起作用。https://stackoverflow.com/questions/46581587/log4j2-xml-define-jdbc-appender-and-pass-property-from-xml-configuration - AleMar
1个回答

7

Configuration类是由context.getConfiguration()返回的,它不是一种PropertyConfiguration类。它不能用于访问log4j2.xml值,因为它是针对日志设置量身定制的非常不同的Configuration类。

可以将baseDir定义提取到单独的属性文件中。这为编程和非编程log4j配置提供了共同的源:在编程上,它可以被视为一个常规的属性配置文件;log4j2配置可以将其作为属性查找来访问。

具体操作如下:

  1. The external property file logsCommons.properties is located in the same folder with log4j2.xml and has the property:

    baseDir=log-dir
    
  2. The log4j2xml is defined as following:

    <Properties>
        <Property name="baseDir">${bundle:logsCommons:baseDir}/</Property>
        <Property name="defaultLogfileName">default-log-file</Property>
    </Properties>
    

来自OP的问题:

除了将 baseDir 的值移动到一个属性文件中,并像上面描述的那样引用它,即${bundle:logsCommon:baseDir},我还做了以下工作以找到我的解决方案:

获取 StrSubstitutor:

String baseDirVar = configuration.getStrSubstitutor().getVariableResolver().look‌​up("baseDir"); 

然后我需要进行替换:

String baseDir = configuration.getStrSubstitutor().replace(baseDirVar);

现在我可以可靠地获取(必要时进行修改)来自属性文件的日志基目录。


这是否意味着我的代码需要通过加载属性文件来访问baseDir?还是我可以通过log4j2 API访问它? - FrustratedWithFormsDesigner
1
我想通了!首先,我需要获取StrSubstitutor:String baseDirVar = configuration.getStrSubstitutor().getVariableResolver().lookup("baseDir"); 然后我需要进行替换:String baseDir = configuration.getStrSubstitutor().replace(baseDirVar); 现在我可以可靠地获取(并在必要时修改)来自属性文件的日志基目录。 - FrustratedWithFormsDesigner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接