遇到需要执行很多计算任务的场景时,如果所有日志内容都输出到一个文件中,查看和排查时十分不友好,因此根据实际需要将不同的日志内容输出到不同日志文件中非常有用。实现这一目的其实主要分为以下两步:
log4j配置
下面的log4j2配置实现了默认的日志文件输出为log_file_name.log和log_file_name.error,任务日志输出文件为${LOG_HOME}/${ctx:ROUTINGKEY}.info和${LOG_HOME}/${ctx:ROUTINGKEY}.error
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<Configuration status="WARN" monitorInterval="30">
<Properties>
<!-- <Property name="PID">????</Property>-->
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
<Property name="CONSOLE_LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%-5p] - %m%n</Property>
<Property name="FILE_LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%-5p] - %m%n</Property>
<Property name="DEBUG_ROLLOVER_SIZE">64 MB</Property>
<Property name="APP_NAME">ProjectName</Property>
<Property name="LOG_HOME">log/</Property>
</Properties>
<!--先定义所有的appender-->
<Appenders>
<Routing name="InfoRouting">
<Routes pattern="$${ctx:ROUTINGKEY}">
<!-- if ThreadContext has no value for key ROUTINGKEY. log in default route-->
<Route key="$${ctx:ROUTINGKEY}">
<RollingFile name="RollingFile-default" fileName="${LOG_HOME}/log_file_name.info"
filePattern="${LOG_HOME}/umbrella_center_logBackup/log_file_name.info-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%-5p] - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${DEBUG_ROLLOVER_SIZE}"/>
<OnStartupTriggeringPolicy/>
</Policies>
</RollingFile>
</Route>
<!-- This route is chosen if ThreadContext has a value for ROUTINGKEY . !! notice:ROUTINGKEY is prikey
The value dynamically determines the name of the log file. -->
<Route>
<File name="File-${ctx:ROUTINGKEY}" fileName="${LOG_HOME}/${ctx:ROUTINGKEY}.info">
<PatternLayout>
<pattern>[%t][%d{yyyy-MM-dd HH:mm:ss,SSS}][%C:%L][%-5p] - %m%n</pattern>
</PatternLayout>
</File>
</Route>
</Routes>
</Routing>
<Routing name="ErrorRouting">
<Routes pattern="$${ctx:ROUTINGKEY}">
<Route key="$${ctx:ROUTINGKEY}">
<RollingFile name="RollingFile-default" fileName="${LOG_HOME}/log_file_name.error"
filePattern="${LOG_HOME}/umbrella_center_logBackup/log_file_name.error-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%-5p] - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${DEBUG_ROLLOVER_SIZE}"/>
<OnStartupTriggeringPolicy/>
</Policies>
</RollingFile>
</Route>
<Route>
<File name="File-${ctx:ROUTINGKEY}" fileName="${LOG_HOME}/${ctx:ROUTINGKEY}.error">
<PatternLayout>
<pattern>[%t][%d{yyyy-MM-dd HH:mm:ss,SSS}][%C:%L][%-5p] - %m%n</pattern>
</PatternLayout>
</File>
</Route>
</Routes>
</Routing>
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</console>
</Appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<Loggers>
<Logger name="com.unionpay.cloudatlas.ac" level="info"/>
<Logger name="com.unionpay.cloudatlas.ueyes" level="info"/>
<Logger name="com.unionpay.cloudatlas.ac.docker.ACDocker" level="warn"/>
<Logger name="com.unionpay.cloudatlas.ac.common.ACConfig" level="error"/>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="InfoRouting"/>
<AppenderRef ref="ErrorRouting" level="error"/>
</Root>
</Loggers>
</Configuration>
代码中实现日志内容的重定向
ThreadContext.put("ROUTINGKEY", log_file_path);
这里的设置会替换log4j2中的${ctx:ROUTINGKEY}变量。
注意这里是线程级别的设定,因此使用多线程的地方如果想重定向日志内容,一定要执行上述代码,否则会打印到默认日志文件中。