Skip to content

Commit

Permalink
Ensure that async console logging does not prevent failed startup errors
Browse files Browse the repository at this point in the history
Fixes: #20660
  • Loading branch information
geoand committed Oct 13, 2021
1 parent fbccba9 commit 35fee1a
Showing 1 changed file with 37 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.concurrent.locks.Lock;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.Any;
Expand All @@ -19,8 +21,10 @@
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.graalvm.nativeimage.ImageInfo;
import org.jboss.logging.Logger;
import org.jboss.logmanager.handlers.AsyncHandler;
import org.wildfly.common.lock.Locks;

import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.bootstrap.runner.RunnerClassLoader;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.runtime.configuration.ProfileManager;
Expand Down Expand Up @@ -205,6 +209,7 @@ public static void run(Application application, Class<? extends QuarkusApplicati
} else {
applicationLogger.errorv(rootCause, "Failed to start application (with profile {0})",
ProfileManager.getActiveProfile());
ensureConsoleLogsDrained();
}
}
stateLock.lock();
Expand Down Expand Up @@ -234,6 +239,38 @@ public static void run(Application application, Class<? extends QuarkusApplicati
(exitCodeHandler == null ? defaultExitCodeHandler : exitCodeHandler).accept(getExitCode(), null); //this may not be called if shutdown was initiated by a signal
}

// this is needed only when async console logging is enabled
private static void ensureConsoleLogsDrained() {
AsyncHandler asyncHandler = null;
for (Handler handler : InitialConfigurator.DELAYED_HANDLER.getHandlers()) {
if (handler instanceof AsyncHandler) {
asyncHandler = (AsyncHandler) handler;
Handler[] nestedHandlers = asyncHandler.getHandlers();
boolean foundNestedConsoleHandler = false;
for (Handler nestedHandler : nestedHandlers) {
if (nestedHandler instanceof ConsoleHandler) {
foundNestedConsoleHandler = true;
break;
}
}
if (!foundNestedConsoleHandler) {
asyncHandler = null;
}
}
if (asyncHandler != null) {
break;
}
}
if (asyncHandler != null) {
try {
// all we can do is wait because the thread that takes records off the queue is a daemon thread and there is no way to interact with its lifecycle
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

/**
* Run some background cleanup once after the application has booted.
* This will not be invoked for command mode, as it's not worth it for a short lived process.
Expand Down

0 comments on commit 35fee1a

Please sign in to comment.