在读取和解析多个文件的批处理应用程序中,规范要求我分别输出每个文件的日志。
我该怎么做?
示例:
for(File f : allFiles) {
//TODO after this line all log should be output to "<f.getName()>.log"
LOGGER.debug('Start processing '+f.getName());
// process the file by calling librairies (JPA, spring, whatever ...)
LOGGER.debug('End processing '+f.getName());
}
所以,如果我要处理3个文件,最后我想要3个日志文件。
到目前为止我所做的是以下课程。
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public final class LoggerHelper {
/**
* Functional logger
*/
private static final Logger LOGGER = Logger.getLogger("BATCH_LOGGER");
/**
* Pattern for the layout of the logger
*/
private static final String PATTERN_LAYOUT = "%d{yyyy-MM-dd [HH:mm:ss]} %m%n";
/**
* Constructor
*/
private LoggerHelper() {
}
/**
* Initialize the loggers
*
* @param filename
* the name of the file where the logs will be written
* @throws IOException
* if a problem occur when instantiate a file appender
*/
public static void initLoggers(String filename) throws IOException {
// change functional appender
LOGGER.removeAllAppenders();
LOGGER.addAppender(new FileAppender(new PatternLayout(PATTERN_LAYOUT), filename));
LOGGER.setLevel(Level.DEBUG);
}
/**
* Get the batch logger
*
* @return the batch Logger
*/
public static Logger getLogger() {
return LOGGER;
}
}
但我必须用LoggerHelper.getLogger().debug(...)
替换所有LOGGER调用。
使用此解决方案,我无法记录框架日志。
for(File f : allFiles) {
//TODO after this line all log should be output to "<f.getName()>.log"
LoggerHelper.initLoggers(f.getName());
LoggerHelper.getLogger().debug('Start processing '+f.getName());
// process the file by calling librairies (JPA, spring, whatever ...)
LoggerHelper.getLogger().debug('End processing '+f.getName());
}
我该怎么做?
答案 0 :(得分:1)
你已经走上了良好的轨道。我想你的错误是创造新的记录器。解决方案可能是向同一记录器添加不同的appender。因此,您的记录器助手只需要替换appender(就像您在代码中所做的那样):
private static final class LoggerHelper {
private static final String PATTERN_LAYOUT = "%d{yyyy-MM-dd [HH:mm:ss]} %m%n";
private static final Layout LAYOUT = new PatternLayout(PATTERN_LAYOUT);
public static final void setFileOutputOfLogger(Logger log, String fileName) throws IOException {
log.removeAllAppenders();
log.addAppender(new FileAppender(LAYOUT, fileName));
}
}
这是你可以在循环中调用的东西。
Logger log = Logger.getLogger(FileStuff.class);
for(File f : allFiles) {
LoggerHelper.setFileOutputOfLogger(log, f.getName());
不会触及所有框架输出。
答案 1 :(得分:1)
这是我最终实施的解决方案。 我在这里分享,如果这可以帮助别人......
首先,重新加载log4j配置的帮助程序类 请注意,它(重新)设置了一些系统属性。这些属性将直接用在log4j文件中。
import org.apache.log4j.xml.DOMConfigurator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
public final class LogHelper {
private final static String LOG4J_XML_FILENAME = "log4j.xml";
private final static String LOG_APPLI_DIRECTORY = "LOG_APPLI_DIRECTORY";
private final static String FILENAME = "FILENAME";
public static void initLogsForCurrentFile(String currentFile, String logDir) {
Assert.hasLength(currentFile);
Assert.doesNotContain(currentFile, File.pathSeparator);
ClassPathResource log4jxml = new ClassPathResource(LOG4J_XML_FILENAME);
if (!log4jxml.exists()) {
throw new IllegalArgumentException(
"The [log4j.xml] configuration file has not been found on the classpath.");
}
// TODO Define variables that could be used inside the log4j
// configuration file
System.setProperty(FILENAME, FileUtils.removeExtension(currentFile));
System.setProperty(LOG_APPLI_DIRECTORY, logDir);
// Reload the log4j configuration
try {
DOMConfigurator.configure(log4jxml.getURL());
} catch (Exception e) {
throw new IllegalArgumentException(
"A problem occured while loading the log4j configuration.",
e);
}
}
}
和相应的log4j文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- This log4j file will be reloaded multiple times -->
<!-- so that each files processed by the applicatin will have their own log file -->
<!-- ${LOG_APPLI_DIRECTORY} = the log directory -->
<!-- ${FILENAME} = the basename of the current file processed by the batch -->
<appender name="batch-appender" class="org.apache.log4j.RollingFileAppender">
<param name="file"
value="${LOG_APPLI_DIRECTORY}/batch-${FILENAME}.log" />
<param name="MaxFileSize" value="1MB" />
<param name="MaxBackupIndex" value="3" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %-40.40c{1} - %m%n" />
</layout>
</appender>
<!-- ================ -->
<!-- Root logger -->
<!-- ================ -->
<root>
<priority value="info" />
<appender-ref ref="batch-appender" />
</root>
</log4j:configuration>
使用这样的解决方案,我们尽可能地保持我们通常用来配置log4j的程度。 此外,此解决方案将配置保留在log4j文件中,而不在java源代码中进行配置。