I want to turn off logging for 1 unit test (which doesn't fail), so a stacktrace doesn't show up in the log. That stacktrace should be there in production runs because it's a failure-testing test.
The production code looks like this:
boolean failed = false;
for (int i = 0; i < 10; i++) {
try {
// Possible submits on Executor to run on other thread (not that it matters)
runTask(i);
} catch (RuntimeException e) {
// In the unit test, this pollutes the test log // BAD, MY PROBLEM
// In production, it shows up in the log immediately, before other tasks run // GOOD
logger.warn("Task failed. Stacktrace:", e);
failed = true;
}
}
if (failed) {
// The unit test checks if this exception is thrown,
// (it doesn't pollute the test log)
throw new IllegalStateException("at least 1 failed");
// In the real implementation, this also chains the first exception, to avoid eating the stacktrace
}
I have a unit test which tests that an executor throws an exception if at least 1 out of 10 tasks submitted to it fails. Because the executor can't fail when an inner exception occurs, it first runs the other tasks before throwing the outer exception. So when it catches the inner exception, it logs it, giving a stacktrace in the log. For QA, this is misleading, as the test logs show a stacktrace, despite that all tests succeeded. I want to get rid of that stacktrace in the test log (jira).
I believe there is no solution for slf4j as the supported frameworks might not support this function.
If you are using slf4j with a log4j binding you could achieve it as.
// get the logger you want to suppress
Logger log4j = Logger.getLogger("sub.optimal.package");
// keep the current level
Level previousLogLevel = log4j.getLevel();
// set the level to suppress your stacktrace respectively
log4j.setLevel(Level.WARN);
Find below an example how to configure the logger on method level. You need to have a different logger configured for which you change the logging level in production and in testing environment.
assume following directory structure and files
./Main.java
./slf4j-api-1.7.10.jar
./slf4j-log4j12-1.7.10.jar
./log4j-1.2.17.jar
./prod/log4j.properties
./testing/log4j.properties
./bin/
Main.java
package sub.optimal;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
Logger logger;
Logger loggerSuppressible;
{
logger = LoggerFactory.getLogger(this.getClass());
loggerSuppressible = LoggerFactory.getLogger("loggerSuppressible");
}
public void doSomeFoo() {
logger.info("logging from doSomeFoo");
}
public void doSomeStacktrace() {
try {
new File("..").renameTo(null);
} catch (NullPointerException npe) {
loggerSuppressible.error("something went wrong", npe);
}
}
public static void main(String[] args) {
Main main = new Main();
main.doSomeFoo();
main.doSomeStacktrace();
}
}
./prod/log4j.properties
log4j.rootCategory=info, console
# production setting
log4j.category.loggerSuppressible=info, console
log4j.additivity.loggerSuppressible=false
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=info
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n
./testing/log4j.properties
log4j.rootCategory=info, console
# testing setting
log4j.category.loggerSuppressible=fatal, console
log4j.additivity.loggerSuppressible=false
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=info
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n
compile
javac -cp ${classpath_logger} -d bin/ Main.java
** run in production**
java -cp bin/:prod/:${classpath_logger} sub.optimal.Main
** run in testing**
java -cp bin/:testing/:${classpath_logger} sub.optimal.Main
output production
2015-03-05 14:09:50,707 [main] INFO sub.optimal.Main - logging from doSomeFoo
2015-03-05 14:09:50,707 [main] ERROR loggerSuppressible - something went wrong
java.lang.NullPointerException
at java.io.File.renameTo(File.java:1386)
at sub.optimal.Main.doSomeStacktrace(Main.java:22)
at sub.optimal.Main.main(Main.java:32)
output testing
2015-03-05 14:09:50,847 [main] INFO sub.optimal.Main - logging from doSomeFoo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With