我以前从未使用过日志,我想在应用程序中间再次初始化每个类的日志。我们使用log4j
,在each
类上,我们有
public class MyClass {
private static Logger logger = Logger.getLogger(MyClass.class);
public void method(){
logger.info("This is info");
}
因此,我想要在应用程序运行时的某个时间点重新初始化这个logger
对象。
private static Logger logger = Logger.getLogger(MyClass.class);
当我的应用程序正在运行并且用户执行某个操作时,
目的:
我的真实的目标是将这些日志文件存储在磁盘上。但我希望根据用户操作将日志文件存储在不同的文件夹中。因此,我们的应用程序中有两个siteIDs
,因此,我们在磁盘上创建了两个文件夹,我们希望在其中存储日志文件。因此,当站点被选中时,这些each class
上的logger
对象需要重新初始化。有什么建议吗?下面是我的log.properties文件:
logger.pattern=%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n
logger.base.dir=../logs
logger.archive.dir=/archive
logger.archived.file.pattern=_%d{dd-MM-yyyy}.%i
logger.file.ext=.log
logger.file.size=10 mb
logger.archived.size.cap=100 mb
logger.file.retention.days=7
logger.debug.file.retention.days=1
logger.level=TRACE
然后我们有一个名为LoggerConfig
的类
public class LoggerConfig {
private static LoggerConfig loggerConfig = null;
private Properties prop = new Properties();
private String pattern;
private String baseDir;
private String archiveDir;
private String archivedFilePattern;
private String fileExt;
private String fileSize;
private String archivedSizeCap;
private Integer fileRetentionDays;
private Integer debugFileRetentionDays;
private Level loggerLevel;
private LoggerConfig() {
loadProperties();
}
public static LoggerConfig getInstance() {
if (loggerConfig == null) {
loggerConfig = new LoggerConfig();
}
return loggerConfig;
}
private void loadProperties() {
try {
InputStream input = LoggerConfig.class.getClassLoader().getResourceAsStream("logger.properties");
prop.load(input);
this.pattern = prop.getProperty("logger.pattern");
this.baseDir = prop.getProperty("logger.base.dir");
this.archiveDir = prop.getProperty("logger.archive.dir");
this.archivedFilePattern = prop.getProperty("logger.archived.file.pattern");
this.fileExt = prop.getProperty("logger.file.ext");
this.fileSize = prop.getProperty("logger.file.size");
this.archivedSizeCap = prop.getProperty("logger.archived.size.cap");
this.fileRetentionDays = Integer.parseInt(prop.getProperty("logger.file.retention.days"));
this.debugFileRetentionDays = Integer.parseInt(prop.getProperty("logger.debug.file.retention.days"));
this.loggerLevel = Level.toLevel(prop.getProperty("logger.level"));
} catch (Exception ex) {
System.out.println("Exception occourred while loading the configration file " + ex);
}
}
/**
* Getters and setters
*/
最后是另一个Logger文件:
public class ApplicationLogger {
private static LoggerConfig config = LoggerConfig.getInstance();
private static Map<String, Logger> loggers = new HashMap<String, Logger>();
public static Logger getLogger(String orgID, Class<?> className) {
init(orgID, className);
return loggers.get(orgID);
}
private static void init(String orgID, Class<?> className) {
if (!loggers.containsKey(orgID)) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = loggerContext.getLogger(orgID + className);
logger.setAdditive(Boolean.FALSE);
logger.setLevel(config.getLoggerLevel());
logger.addAppender(getFileAppender(loggerContext, Level.TRACE, orgID));
logger.addAppender(getFileAppender(loggerContext, Level.DEBUG, orgID));
logger.addAppender(getFileAppender(loggerContext, Level.INFO, orgID));
logger.addAppender(getFileAppender(loggerContext, Level.WARN, orgID));
logger.addAppender(getFileAppender(loggerContext, Level.ERROR, orgID));
loggers.put(orgID, logger);
}
}
private static FileAppender<ILoggingEvent> getFileAppender(LoggerContext loggerContext, Level level, String orgID) {
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern(config.getPattern());
encoder.setImmediateFlush(Boolean.TRUE);
encoder.start();
LevelFilter filter = new LevelFilter();
filter.setContext(loggerContext);
filter.setLevel(level);
filter.setOnMismatch(FilterReply.DENY);
filter.start();
RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<ILoggingEvent>();
SizeAndTimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new SizeAndTimeBasedRollingPolicy<ILoggingEvent>();
rollingPolicy.setContext(loggerContext);
rollingPolicy.setFileNamePattern(config.getBaseDir() + config.getArchiveDir() + File.separator + orgID
+ File.separator + level.toString() + config.getArchivedFilePattern() + config.getFileExt());
rollingPolicy.setMaxFileSize(FileSize.valueOf(config.getFileSize()));
rollingPolicy.setMaxHistory(
Level.DEBUG.equals(level) ? config.getDebugFileRetentionDays() : config.getFileRetentionDays());
rollingPolicy.setTotalSizeCap(FileSize.valueOf(config.getArchivedSizeCap()));
rollingPolicy.setParent(fileAppender);
rollingPolicy.start();
fileAppender.setContext(loggerContext);
fileAppender.setAppend(true);
fileAppender.setEncoder(encoder);
fileAppender.addFilter(filter);
fileAppender.setFile(
config.getBaseDir() + File.separator + orgID + File.separator + level.toString() + config.getFileExt());
fileAppender.setRollingPolicy(rollingPolicy);
fileAppender.start();
return fileAppender;
}
}
请注意,orgID是由用户更改的站点ID,更改后,我希望重新初始化所有logger
对象
1条答案
按热度按时间2o7dmzc51#
在Log4j2中,一个标准的解决方案是使用一个日志记录器,即
ThreadContext
和RoutingAppender
。这几乎不需要编程配置:1.在开始处理请求时,您需要为
siteId
ThreadContext
键填写一个值:1.在您的
log4j2.xml
文件中,您需要配置一个路由追加器,它根据siteId
的值选择真实的的追加器:1.您的类可以使用从
LogManager.getLogger
获得的静态记录器,并且不需要知道选择追加器背后的逻辑。类似的配置可能可以在Logback中使用过滤器获得,但我对Logback的了解非常有限。