Skip to content

Commit

Permalink
#21 Use synchronizedList to capture log events (#22)
Browse files Browse the repository at this point in the history
* #21 Use synchronizedList to capture log events

This makes LogCaptor suitable for using in multi-threaded 'integration' tests

* Return unmodifiable list

Co-authored-by: Andrey Nudko <andrey.nudko>
  • Loading branch information
AndreyNudko committed Nov 17, 2021
1 parent 8461b71 commit 37b37a1
Showing 1 changed file with 34 additions and 19 deletions.
53 changes: 34 additions & 19 deletions src/main/java/nl/altindag/log/LogCaptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.read.ListAppender;
import nl.altindag.log.model.LogEvent;
import nl.altindag.log.util.JavaUtilLoggingLoggerUtils;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -44,7 +46,8 @@ public final class LogCaptor implements AutoCloseable {
private static final Map<String, Level> LOG_LEVEL_CONTAINER = new HashMap<>();

private final Logger logger;
private final ListAppender<ILoggingEvent> listAppender;
private final Appender<ILoggingEvent> appender;
private final List<ILoggingEvent> eventList = Collections.synchronizedList(new ArrayList<>());

private LogCaptor(String loggerName) {
org.slf4j.Logger slf4jLogger = LoggerFactory.getLogger(loggerName);
Expand All @@ -59,15 +62,21 @@ private LogCaptor(String loggerName) {
}

logger = (Logger) slf4jLogger;
listAppender = new ListAppender<>();
listAppender.setName("log-captor");
listAppender.start();
logger.addAppender(listAppender);
appender = createAppender(eventList);
appender.start();
logger.addAppender(appender);

JavaUtilLoggingLoggerUtils.redirectToSlf4j(loggerName);
LOG_LEVEL_CONTAINER.putIfAbsent(logger.getName(), logger.getEffectiveLevel());
}

private static ListAppender<ILoggingEvent> createAppender(List<ILoggingEvent> dst) {
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.setName("log-captor");
listAppender.list = dst;
return listAppender;
}

/**
* Captures all log messages
*
Expand Down Expand Up @@ -98,9 +107,11 @@ public static LogCaptor forName(String name) {
}

public List<String> getLogs() {
return listAppender.list.stream()
.map(ILoggingEvent::getFormattedMessage)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
synchronized (eventList) {
return eventList.stream()
.map(ILoggingEvent::getFormattedMessage)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
}

public List<String> getInfoLogs() {
Expand All @@ -124,20 +135,24 @@ public List<String> getTraceLogs() {
}

private List<String> getLogs(Level level) {
return listAppender.list.stream()
.filter(logEvent -> logEvent.getLevel() == level)
.map(ILoggingEvent::getFormattedMessage)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
synchronized (eventList) {
return eventList.stream()
.filter(logEvent -> logEvent.getLevel() == level)
.map(ILoggingEvent::getFormattedMessage)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
}

public List<LogEvent> getLogEvents() {
return listAppender.list.stream()
.map(toLogEvent())
.collect(toList());
synchronized (eventList) {
return eventList.stream()
.map(toLogEvent())
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
}

public void addFilter(Filter<ILoggingEvent> filter) {
listAppender.addFilter(filter);
appender.addFilter(filter);
filter.start();
}

Expand Down Expand Up @@ -193,13 +208,13 @@ public void resetLogLevel() {
}

public void clearLogs() {
listAppender.list.clear();
eventList.clear();
}

@Override
public void close() {
listAppender.stop();
logger.detachAppender(listAppender);
logger.detachAppender(appender);
appender.stop();
}

}

0 comments on commit 37b37a1

Please sign in to comment.