我们有时候需要在运行时,动态创建日志文件,特别是文件名根据某些参数决定。这种方式只能通过编程方式来实现。
1、JAVA代码样例
import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; import ch.qos.logback.core.util.FileSize; import ch.qos.logback.core.util.OptionHelper; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.slf4j.LoggerFactory; import org.slf4j.MDC; public class LoggerBuilder { private static final Map<String,Logger> container = new HashMap<>(); public static Logger getLogger(String name) { Logger logger = container.get(name); if(logger != null) { return logger; } synchronized (LoggerBuilder.class) { logger = container.get(name); if(logger != null) { return logger; } logger = build(name); container.put(name,logger); } return logger; } private static Logger build(String name) { LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); Logger logger = context.getLogger("FILE-" + name); logger.setAdditive(false); RollingFileAppender appender = new RollingFileAppender(); appender.setContext(context); appender.setName("FILE-" + name); appender.setFile(OptionHelper.substVars("${LOG_HOME}/web-log-" + name + ".log",context)); appender.setAppend(true); appender.setPrudent(false); SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy(); String fp = OptionHelper.substVars("${LOG_HOME}/web-log-" + name + ".log.%d{yyyy-MM-dd}.%i",context); policy.setMaxFileSize(FileSize.valueOf("128MB")); policy.setFileNamePattern(fp); policy.setMaxHistory(15); policy.setTotalSizeCap(FileSize.valueOf("32GB")); policy.setParent(appender); policy.setContext(context); policy.start(); PatternLayoutEncoder encoder = new PatternLayoutEncoder(); encoder.setContext(context); encoder.setPattern("%d{yyyy-MM-dd/HH:mm:ss.SSS}|%X{localIp}|[%t] %-5level %logger{50} %line - %m%n"); encoder.start(); appender.setRollingPolicy(policy); appender.setEncoder(encoder); appender.start(); logger.addAppender(appender); return logger; } }
2、配置
需要注意,我们通常在日志文件路径上使用使用一些系统变量(比如${catalina.base})、或者logback.xml配置的properties;此时我们可以使用OptionHelper辅助类来替换String中的变量占位符,此外LoggerContext中包含logback.xml配置的properties。不过这些properties默认上下文Scope为“local”,如果想让它们能够被LoggerContext访问,需要强制设置为“context”,这不会引入问题。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property scope="context" name="LOG_HOME" value="${catalina.base}/logs"/> ... </configuration>