Reputation: 24411
I've written up a small console utility. Throughout the application, I have used slf4j/log4j to log debug, trace, info statements to the console as I was developing it. Now that I am done development and want to release it, I would like to disable all output to the console except for a couple of specific loggers and send all the remaining loggers to a text file.
In theory, this should be fairly easy. I have created 2 appenders (one ConsoleAppender and one FileAppender). I have assocaited the ConsoleAppender with the specific loggers want on the Console and the FileAppender at the Root level. This works fine.
My issue now, is if I want to completely disable the FileAppender, I cannot figure out how to do it. If I add a DenyAllFilter to the FileAppender, it will prevent anything from being written to the file, but the file is still created. If I remove the FileAppender from the ROOT logger, I get Log4J writting to StdErr:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
If I set the ROOT level to OFF, the individual loggers that I have set custom debug levels to still output.
If I set the LoggerRepository Level to OFF, then all loggers (those I want to go to STDOUT and the File) are all shut off.
Is there any way to do this easily? Ideally, I want to be able to disable the file appender altogether, however provide a command line switch to enable it if desired.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "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{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
<!-- <param name="ConversionPattern" value="%m%n" /> -->
</layout>
</appender>
<appender name="LOGTXT" class="org.apache.log4j.FileAppender">
<param name="file" value="lss-client.log" />
<param name="append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
</layout>
<!-- <filter class="org.apache.log4j.varia.DenyAllFilter"/> -->
</appender>
<!-- Spring Loggers -->
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.sent">
<level value="TRACE" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.received">
<level value="TRACE" />
</logger>
<logger name="com.cws.cs.Client" >
<level value="INFO" />
<appender-ref ref="STDOUT" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="LOGTXT" />
</root>
</log4j:configuration>
Thanks!
Eric
Upvotes: 0
Views: 13709
Reputation: 15310
Pretty sure Slf4J/Log4J creates the log file immediately when you configure a FileAppender
.
I think your best bet here is to have 2 different and complete Log4J configurations and pick which one you load at startup based on your command line parameter.
In PseudoCode:
public static void main(String[] args){
//if log to file arg = true
DOMConfigurator.configure("logToFile.log4j.xml");
//else
DOMConfigurator.configure("logToConsoleOnly.log4j.xml");
}
Edit
Furthermore, if you don't like the idea of maintaining two configuration files. You could create one configuration with the common components (probably the spring stuff and w/e else) and then based on your parameter, programatically configure the FileAppender
:
public static void main(String[] args){
DOMConfigurator.configure("log4j.xml");
//if log to file arg = true{
// Define layout
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n");
// Create appender
FileAppender appender = new FileAppender();
appender.setFile("lss-client.log");
appender.setLayout(layout);
appender.activateOptions();
// Get root logger and add appender.
log = Logger.getRootLogger();
log.setLevel(Level.INFO);
log.addAppender(appender);
}
}
Upvotes: 2