Can log4j inherit xml from a base/root element?

2019-04-20 12:40发布

I'm trying to reduce duplication in my log4j configuration and wanted to know if I could push similar config down to a root.xml file and inherit from it in each of the child log4j.xml files?

Thank you!

2条回答
一夜七次
2楼-- · 2019-04-20 12:43

I doubt that it is possible in log4j but the self named successor project logback at least provides a possibility to include configurations. It is not inheritence but also a strategy to reduce duplications. Maybe you can give it a try.

查看更多
Luminary・发光体
3楼-- · 2019-04-20 12:45

AFAIK there's no "native" inheritance mechanism, but you may achieve the same result using an entity to reference and include an external xml fragment (see this nabble thread). If you just want to modify certain properties, a similar solution is described here. An Example using external entities:

Main Config (log4j.xml):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" [
    <!ENTITY appender SYSTEM "appender.xml">
    <!ENTITY root SYSTEM "root.xml">
]>  
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" >
&appender;
&root;
</log4j:configuration>

appender.xml:

<?xml version="1.0" encoding="UTF-8"?>
<appender name="MyAppender" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="datePattern" value="'.'yyyy-MM-dd_HH-mm" />
    <param name="file" value="logs/MyLogFile.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %c: %m%n" />
    </layout>
</appender>

root.xml:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <priority value="INFO" />
    <appender-ref ref="MyAppender" />
</root>

It even works if both the root and the appender definition are placed into a single file, without the ?xml pi. So, the external content may even be an ill-formed xml fragment lacking a single root element. This allows for transferring the complete log4j config into an single external file:

log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"[
    <!ENTITY config SYSTEM "log4j-config.txt">
]>
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" >
&config;
</log4j:configuration>

log4j-config.txt:

<appender name="MyAppender" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="datePattern" value="'.'yyyy-MM-dd_HH-mm" />
    <param name="file" value="logs/MyLogFile.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %c: %m%n" />
    </layout>
</appender>
<root>
    <priority value="INFO" />
    <appender-ref ref="MyAppender" />
</root>

If you need to adapt the log4j config in an individual and flexible way, you could try and merge the root.xml with the child.xml using XSLT or XmlMerge (part of el4j) to create a config on the fly, and feed the org.apache.log4j.xml.DOMConfigurator with the resulting DOM.

查看更多
登录 后发表回答