从Log4j 1.x迁移
使用Log4j 1.x桥接
可能转换为使用Log4j 2的最简单的方法就是用Log4j 2的log4j-1.2-api.jar
文件替换log4j 1.x的jar文件。然而要成功的话,应用程序必须满足以下要求:
- 不能使用Log4j 1.x中与具体实现相关的类,例如
Appender
、LoggerRepository
或Category
中的callAppenders
方法。 - 不能以程序的方式配置Log4j。
- 不能通过调用
DOMConfigurator
或PropertyConfigurator
类来进行配置。
转到Log4j 2 API
大多数情况下,从Log4j 1.x API转换到Log4j 2相当简单。很多日志声明都不需要修改。然而,以下这些变更是必要的:
- 版本1中的主要包是
org.apache.log4j
,而版本2中是org.apache.logging.log4j
。 - 对
org.apache.log4j.Logger.getLogger()
的调用必须修改为org.apache.logging.log4j.LogManager.getLogger()
。 - 对
org.apache.log4j.Logger.getRootLogger()
或org.apache.log4j.LogManager.getRootLogger()
的调用必须用org.apache.logging.log4j.LogManager.getRootLogger()
进行替换。 - 对
org.apache.log4j.Logger.getLogger
的调用所接收的LoggerFactory
必须删除org.apache.log4j.spi.LoggerFactory
并使用Log4j 2中其他扩展的机制之一。 - 用
org.apache.logging.log4j.Logger.getLevel()
来替换org.apache.log4j.Logger.getEffectiveLevel()
。 - 删除对
org.apache.log4j.LogManager.shutdown()
的调用,它们在版本2中不需要,因为Log4j Core现在会在启动时自动加入JVM shutdown hook以进行Core的清理。- 从Log4j 2.1开始,你可以自定义一个具体的ShutdownCallbackRegistry来覆盖默认JVM shutdown hook的策略。
- 从Log4j 2.6开始,你可以使用
org.apache.logging.log4j.LogManager.shutdown()
来手动添加shutdown。
- API不支持类似于
org.apache.log4j.Logger.setLevel()
的方法调用,应用程序应该移除它们。在Log4j 2中提供同等功能的实现类,见org.apache.logging.log4j.core.config.Configurator.setLevel()
,但这可能会使应用程序受到Log4j 2变化的影响。 - 在合适的地方,应用程序应该转而使用参数化的消息来替代字符串拼接。
org.apache.log4j.MDC
和org.apache.log4j.NDC
已经被Thread Context替换。
配置Log4j 2
尽管Log4j 2的配置语法与Log4j 1.x不同,但绝大多数相同的功能都是可用的。
注意通过${foo}
来插入系统属性的语法已经扩展为可以通过很多不同来源进行属性查找。查看Lookup文档了解更多细节。例如,使用一个系统属性catalina.base
的lookup,在Log4j 1.x中的语法为${catalina.base}
。在Log4j 2中,语法是${sys:catalina.base}
。
下面是一些Log4j 1.x的配置和对应的Log4j 2.x的配置示例。
示例1 - 控制台Appender的简单配置
Log4j 1.x的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="info" />
</category>
<Root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>
Log4j 2的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="info"/>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
示例2 - 文件Appender的简单配置
Log4j 1的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.FileAppender">
<param name="File" value="A1.log" />
<param name="Append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
</layout>
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug" />
<appender-ref ref="A1" />
</category>
<root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>
Log4j 2的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="A1" fileName="A1.log" append="false">
<PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
示例3 - SocketAppender
Log4j 1.x的XML配置。这个Log4j 1.x的例子是一个误导,SocketAppender并不真的使用Layout,配置一个也是不会生效的。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.net.SocketAppender">
<param name="RemoteHost" value="localhost"/>
<param name="Port" value="5000"/>
<param name="LocationInfo" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
</layout>
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug"/>
<appender-ref ref="A1"/>
</category>
<root>
<priority value="debug"/>
<appender-ref ref="STDOUT"/>
</Root>
</log4j:configuration>
Log4j 2的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Socket name="A1" host="localHost" port="5000">
<SerializedLayout/>
</Socket>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
示例4 - AsyncAppender
Log4j 1.x使用AsyncAppender的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>
Log4j 2的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>
示例5 - 控制台和文件的AsyncAppender
Log4j 1.x使用AsyncAppender的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
<appender-ref ref="CONSOLE"/>
</appender>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>
Log4j 2的XML配置。注意AsyncAppender应该在它引用Appender的后面被配置,这会让它正确地关闭。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
<AppenderRef ref="CONSOLE"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>