### Question:
SpectatorAppender extends AppenderSkeleton { @Override protected void append(LoggingEvent event) { final LevelTag level = LevelTag.get(event.getLevel()); registry.counter(numMessages[level.ordinal()]).increment(); ThrowableInformation info = event.getThrowableInformation(); if (info != null) { LocationInfo loc = event.getLocationInformation(); final String file = (loc == null) ? "unknown" : loc.getFileName(); Id stackTraceId = numStackTraces[level.ordinal()] .withTag("exception", info.getThrowable().getClass().getSimpleName()) .withTag("file", file); registry.counter(stackTraceId).increment(); } } SpectatorAppender();  SpectatorAppender(Registry registry); @Override void close(); @Override boolean requiresLayout();  }### Answer:
@Test public void numMessagesERROR() { Counter c = registry.counter("log4j.numMessages", "loglevel", "2_ERROR"); Assertions.assertEquals(0, c.count()); appender.append(newEvent(Level.ERROR, null)); Assertions.assertEquals(1, c.count()); }
@Test public void numMessagesDEBUG() { Counter c = registry.counter("log4j.numMessages", "loglevel", "5_DEBUG"); Assertions.assertEquals(0, c.count()); appender.append(newEvent(Level.DEBUG, null)); Assertions.assertEquals(1, c.count()); }
@Test public void numStackTraces() { Counter c = registry.counter("log4j.numStackTraces", "loglevel", "5_DEBUG", "exception", "IllegalArgumentException", "file", "?"); Assertions.assertEquals(0, c.count()); Exception e = new IllegalArgumentException("foo"); e.fillInStackTrace(); appender.append(newEvent(Level.DEBUG, e)); Assertions.assertEquals(1, c.count()); }