Skip to content

Instantly share code, notes, and snippets.

@olim7t
Created March 22, 2011 14:46
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olim7t/881318 to your computer and use it in GitHub Desktop.
Save olim7t/881318 to your computer and use it in GitHub Desktop.
Temporarily captures Logback output (mostly useful for tests).
import static ch.qos.logback.classic.Level.ALL;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.util.ContextSelectorStaticBinder;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.OutputStreamAppender;
import ch.qos.logback.core.encoder.Encoder;
/** Temporarily captures Logback output (mostly useful for tests). */
public class LogbackCapture {
/**
* Start capturing.
* @param loggerName if null, defaults to the root logger
* @param level if null, defaults to all levels
* @param layoutPattern if null, defaults to "[%p] %m%n"
*/
public static void start(String loggerName, Level level, String layoutPattern) {
if (INSTANCE.get() != null) throw new IllegalStateException("already started");
INSTANCE.set(new LogbackCapture(loggerName, level, layoutPattern));
}
/** Stop capturing and return the logs. */
public static String stop() {
LogbackCapture instance = INSTANCE.get();
if (instance == null) throw new IllegalStateException("was not running");
final String result = instance.stopInstance();
INSTANCE.remove();
return result;
}
private static final ThreadLocal<LogbackCapture> INSTANCE = new ThreadLocal<LogbackCapture>();
private final Logger logger;
private final OutputStreamAppender<ILoggingEvent> appender;
private final Encoder<ILoggingEvent> encoder;
private final ByteArrayOutputStream logs;
private LogbackCapture(String loggerName, Level level, String layoutPattern) {
logs = new ByteArrayOutputStream(4096);
encoder = buildEncoder(layoutPattern);
appender = buildAppender(encoder, logs);
logger = getLogbackLogger(loggerName, level);
logger.addAppender(appender);
}
private String stopInstance() {
appender.stop();
try {
return logs.toString("UTF-16");
} catch (final UnsupportedEncodingException cantHappen) {
return null;
}
}
private static Logger getLogbackLogger(String name, Level level) {
if (name == null || name.isEmpty()) name = ROOT_LOGGER_NAME;
if (level == null) level = ALL;
Logger logger = ContextSelectorStaticBinder.getSingleton()
.getContextSelector().getDefaultLoggerContext().getLogger(name);
logger.setLevel(level);
return logger;
}
private static Encoder<ILoggingEvent> buildEncoder(String layoutPattern) {
if (layoutPattern == null) layoutPattern = "[%p] %m%n";
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setPattern(layoutPattern);
encoder.setCharset(Charset.forName("UTF-16"));
encoder.setContext(ContextSelectorStaticBinder.getSingleton().getContextSelector().getDefaultLoggerContext());
encoder.start();
return encoder;
}
private static OutputStreamAppender<ILoggingEvent> buildAppender(final Encoder<ILoggingEvent> encoder,
final OutputStream outputStream) {
OutputStreamAppender<ILoggingEvent> appender = new OutputStreamAppender<ILoggingEvent>();
appender.setName("logcapture");
appender.setContext(ContextSelectorStaticBinder.getSingleton().getContextSelector().getDefaultLoggerContext());
appender.setEncoder(encoder);
appender.setOutputStream(outputStream);
appender.start();
return appender;
}
}
@jinahya
Copy link

jinahya commented Jan 8, 2015

Thank you for sharing. Inspired and implemented. source, javadoc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment