package net.gini.dropwizard.gelf.testing;
import net.gini.dropwizard.gelf.filters.GelfLoggingFilter;
import org.junit.rules.ExternalResource;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import static org.junit.Assert.fail;
/**
* A {@link org.junit.rules.TestRule} for expected log entries.
*/
public class ExpectedLogEntry extends ExternalResource {
/**
* How long to wait for log entries to be logged before timing out
*/
private static final long LOG_TIMEOUT_IN_MS = TimeUnit.SECONDS.toMillis(1);
private LogAppender appender;
private String key;
private String expectedValue;
private ILoggingEvent entry;
private final CountDownLatch entryFound = new CountDownLatch(1);
public ExpectedLogEntry() {
this(null, null);
}
public ExpectedLogEntry(final String key, final String expectedValue) {
this.key = key;
this.expectedValue = expectedValue;
}
public void mdcKeyAndValue(final String key, final String expectedValue) {
this.key = key;
this.expectedValue = expectedValue;
}
@Override
protected void before() throws Throwable {
super.before();
appender = new LogAppender();
final Logger logger = (Logger) LoggerFactory.getLogger(GelfLoggingFilter.class);
logger.addAppender(appender);
appender.start();
}
@Override
protected void after() {
super.after();
final Logger logger = (Logger) LoggerFactory.getLogger(GelfLoggingFilter.class);
logger.detachAppender(appender);
appender.stop();
}
public ILoggingEvent getEntry() throws InterruptedException {
if (!entryFound.await(LOG_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS)) {
fail("Expected log entry with MDC value " + key + "=" + expectedValue + ", but got none");
}
return entry;
}
private class LogAppender extends AppenderBase<ILoggingEvent> {
@Override
protected void append(final ILoggingEvent eventObject) {
if (key != null) {
final String value = eventObject.getMDCPropertyMap().get(key);
if (expectedValue.equals(value)) {
entry = eventObject;
entryFound.countDown();
}
}
}
}
}