LogQueue extends ConcurrentLinkedQueue<LogEvent> implements LoggerTail { private List<LogEvent> getLogEvents(LogLevel level, int offset, int limit, boolean exact) { List<LogEvent> levelLogs = limit > 0 ? new ArrayList<>(limit) : new ArrayList<>(); int actualIndex = offset >= 0 ? offset : 0; int i = 0; for (LogEvent log : this) { if (i >= actualIndex && (level == null || (exact ? log.getLevel() == level : log.getLevel().compareTo(level) <= 0))) { levelLogs.add(log); if (limit > 0 && levelLogs.size() == limit) { break; } } ++i; } return levelLogs; }  @Override void log(org.slf4j.Logger targetLogger); LogEvent addLogEvent(LogLevel level, String format, Object[] arguments); LogEvent addLogEvent(Marker marker, LogLevel level, String format, Object[] arguments); LogEvent addLogEvent(LogLevel level, String format, Object[] arguments, Throwable throwable); LogEvent addLogEvent(Marker marker, LogLevel level, String format, Object[] arguments, Throwable throwable); @Override void log(LogEvent logEvent); @Override LogEvent getLogEvent(int index); @Override LogEvent getFirstLogEvent(LogLevel from); @Override LogEvent getLastLogEvent(LogLevel from); @Override LogTailResult getLogEvents(LogLevel from, int offset, int limit); @Override boolean hasLogLevel(LogLevel from); List<LogEvent> getLogs(LogLevel level); List<LogEvent> getLogsFrom(LogLevel level); boolean containLogsFrom(LogLevel level); @Override String getName(); @Override boolean isTraceEnabled(); @Override void trace(String msg); @Override void trace(String format, Object arg); @Override void trace(String format, Object arg1, Object arg2); @Override void trace(String format, Object... arguments); @Override void trace(String msg, Throwable t); @Override boolean isTraceEnabled(Marker marker); @Override void trace(Marker marker, String msg); @Override void trace(Marker marker, String format, Object arg); @Override void trace(Marker marker, String format, Object arg1, Object arg2); @Override void trace(Marker marker, String format, Object... arguments); @Override void trace(Marker marker, String msg, Throwable t); @Override boolean isDebugEnabled(); @Override void debug(String msg); @Override void debug(String format, Object arg); @Override void debug(String format, Object arg1, Object arg2); @Override void debug(String format, Object... arguments); @Override void debug(String msg, Throwable t); @Override boolean isDebugEnabled(Marker marker); @Override void debug(Marker marker, String msg); @Override void debug(Marker marker, String format, Object arg); @Override void debug(Marker marker, String format, Object arg1, Object arg2); @Override void debug(Marker marker, String format, Object... arguments); @Override void debug(Marker marker, String msg, Throwable t); @Override boolean isInfoEnabled(); @Override void info(String msg); @Override void info(String format, Object arg); @Override void info(String format, Object arg1, Object arg2); @Override void info(String format, Object... arguments); @Override void info(String msg, Throwable t); @Override boolean isInfoEnabled(Marker marker); @Override void info(Marker marker, String msg); @Override void info(Marker marker, String format, Object arg); @Override void info(Marker marker, String format, Object arg1, Object arg2); @Override void info(Marker marker, String format, Object... arguments); @Override void info(Marker marker, String msg, Throwable t); @Override boolean isWarnEnabled(); @Override void warn(String msg); @Override void warn(String format, Object arg); @Override void warn(String format, Object arg1, Object arg2); @Override void warn(String format, Object... arguments); @Override void warn(String msg, Throwable t); @Override boolean isWarnEnabled(Marker marker); @Override void warn(Marker marker, String msg); @Override void warn(Marker marker, String format, Object arg); @Override void warn(Marker marker, String format, Object arg1, Object arg2); @Override void warn(Marker marker, String format, Object... arguments); @Override void warn(Marker marker, String msg, Throwable t); @Override boolean isErrorEnabled(); @Override void error(String msg); @Override void error(String format, Object arg); @Override void error(String format, Object arg1, Object arg2); @Override void error(String format, Object... arguments); @Override void error(String msg, Throwable t); @Override boolean isErrorEnabled(Marker marker); @Override void error(Marker marker, String msg); @Override void error(Marker marker, String format, Object arg); @Override void error(Marker marker, String format, Object arg1, Object arg2); @Override void error(Marker marker, String format, Object... arguments); @Override void error(Marker marker, String msg, Throwable t); @Override void flush(); @Override void close();  }
@Test void getLogEvents() throws IOException { LogQueue queue = new LogQueue(); assertEquals(0, queue.getLogEvents(LogLevel.TRACE).stream().count()); assertEquals(0, queue.getLogEvents(LogLevel.DEBUG).stream().count()); assertEquals(0, queue.getLogEvents(LogLevel.INFO).stream().count()); assertEquals(0, queue.getLogEvents(LogLevel.WARN).stream().count()); assertEquals(0, queue.getLogEvents(LogLevel.ERROR).stream().count()); queue.warn(""); assertEquals(1, queue.getLogEvents(LogLevel.TRACE).stream().count()); assertTrue(queue.hasLogLevel(LogLevel.TRACE)); assertEquals(1, queue.getLogEvents(LogLevel.DEBUG).stream().count()); assertTrue(queue.hasLogLevel(LogLevel.DEBUG)); assertEquals(1, queue.getLogEvents(LogLevel.INFO).stream().count()); assertTrue(queue.hasLogLevel(LogLevel.INFO)); assertEquals(1, queue.getLogEvents(LogLevel.WARN).stream().count()); assertTrue(queue.hasLogLevel(LogLevel.WARN)); assertEquals(0, queue.getLogEvents(LogLevel.ERROR).stream().count()); assertFalse(queue.hasLogLevel(LogLevel.ERROR)); assertEquals(1, queue.getLogEvents(null).stream().count()); }