diff --git a/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java b/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java index 7f366db8..0b98518b 100644 --- a/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java +++ b/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java @@ -146,6 +146,10 @@ protected void doPublish(final ExtLogRecord record) { // Copy the MDC over record.copyMdc(); } + if (Thread.currentThread() == thread) { + publishToNestedHandlers(record); + return; + } if (overflowAction == OverflowAction.DISCARD) { recordQueue.offer(record); } else { diff --git a/src/test/java/org/jboss/logmanager/handlers/AsyncHandlerTests.java b/src/test/java/org/jboss/logmanager/handlers/AsyncHandlerTests.java index 3d80b0af..1e5fd867 100644 --- a/src/test/java/org/jboss/logmanager/handlers/AsyncHandlerTests.java +++ b/src/test/java/org/jboss/logmanager/handlers/AsyncHandlerTests.java @@ -48,7 +48,7 @@ public void setup() { handler = new BlockingQueueHandler(); asyncHandler = new AsyncHandler(); - asyncHandler.setOverflowAction(OverflowAction.DISCARD); + asyncHandler.setOverflowAction(OverflowAction.BLOCK); asyncHandler.addHandler(handler); } @@ -99,6 +99,37 @@ public void testMdc() throws Exception { Assertions.assertEquals(mdcValue, handler.getFirst()); } + @Test + public void reentry() throws Exception { + final ExtHandler reLogHandler = new ExtHandler() { + private final ThreadLocal entered = ThreadLocal.withInitial(() -> false); + + @Override + protected void doPublish(final ExtLogRecord record) { + if (entered.get()) { + return; + } + try { + entered.set(true); + super.doPublish(record); + // Create a new record and act is if this was through a logger + asyncHandler.publish(createRecord()); + } finally { + entered.set(false); + } + } + }; + handler.addHandler(reLogHandler); + handler.setFormatter(new PatternFormatter("%s")); + asyncHandler.publish(createRecord()); + // We should end up with two messages and a third should not happen + Assertions.assertEquals("Test message", handler.getFirst()); + Assertions.assertEquals("Test message", handler.getFirst()); + // This should time out. Then we end up with a null value. We could instead sleep for a shorter time and check + // if the queue is empty. However, a 5 second delay does not seem too long. + Assertions.assertNull(handler.getFirst(), () -> "Expected no more entries, but found " + handler.queue); + } + static ExtLogRecord createRecord() { return new ExtLogRecord(Level.INFO, "Test message", AsyncHandlerTests.class.getName()); } @@ -107,13 +138,14 @@ static class BlockingQueueHandler extends ExtHandler { private final BlockingDeque queue; BlockingQueueHandler() { - queue = new LinkedBlockingDeque(); + queue = new LinkedBlockingDeque<>(); setErrorManager(AssertingErrorManager.of()); } @Override protected void doPublish(final ExtLogRecord record) { queue.addLast(getFormatter().format(record)); + publishToNestedHandlers(record); super.doPublish(record); }