From 9ea5d891cf063d651ee8188997272106478232fc Mon Sep 17 00:00:00 2001
From: houxiaoyu <houxiaoyu@apache.org>
Date: Sat, 27 Jul 2024 23:56:09 +0800
Subject: [PATCH] Shutdown log before bookie exit to flush async log

---
 bookkeeper-common/pom.xml                                   | 4 ++++
 .../bookkeeper/common/component/ComponentStarter.java       | 6 ++++--
 .../org/apache/bookkeeper/replication/AutoRecoveryMain.java | 2 ++
 .../src/main/java/org/apache/bookkeeper/server/Main.java    | 2 ++
 .../org/apache/bookkeeper/stream/server/StorageServer.java  | 2 ++
 5 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/bookkeeper-common/pom.xml b/bookkeeper-common/pom.xml
index aa733d20ff9..0a3ef64b938 100644
--- a/bookkeeper-common/pom.xml
+++ b/bookkeeper-common/pom.xml
@@ -25,6 +25,10 @@
   <artifactId>bookkeeper-common</artifactId>
   <name>Apache BookKeeper :: Common</name>
   <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.bookkeeper.stats</groupId>
       <artifactId>bookkeeper-stats-api</artifactId>
diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/ComponentStarter.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/ComponentStarter.java
index 3b44d67edb4..140d917024f 100644
--- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/ComponentStarter.java
+++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/ComponentStarter.java
@@ -21,6 +21,7 @@
 import java.util.concurrent.CompletableFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.common.concurrent.FutureUtils;
+import org.apache.logging.log4j.LogManager;
 
 /**
  * Utils to start components.
@@ -50,6 +51,8 @@ public void run() {
                 log.error("Failed to close component {} in shutdown hook gracefully, Exiting anyway",
                     component.getName(), e);
                 future.completeExceptionally(e);
+            } finally {
+                LogManager.shutdown();
             }
         }
 
@@ -74,8 +77,7 @@ public static CompletableFuture<Void> startComponent(LifecycleComponent componen
         component.setExceptionHandler((t, e) -> {
             log.error("Triggered exceptionHandler of Component: {} because of Exception in Thread: {}",
                     component.getName(), t, e);
-            // start the shutdown hook when an uncaught exception happen in the lifecycle component.
-            shutdownHookThread.start();
+            FutureUtils.complete(future, null);
         });
 
         component.publishInfo(new ComponentInfoPublisher());
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/AutoRecoveryMain.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/AutoRecoveryMain.java
index ab074933fff..cdc0f830f99 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/AutoRecoveryMain.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/AutoRecoveryMain.java
@@ -56,6 +56,7 @@
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.logging.log4j.LogManager;
 import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -339,6 +340,7 @@ static int doMain(String[] args) {
             server = buildAutoRecoveryServer(new BookieConfiguration(conf));
         } catch (Exception e) {
             LOG.error("Failed to build AutoRecovery Server", e);
+            LogManager.shutdown();
             return ExitCode.SERVER_EXCEPTION;
         }
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/Main.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/Main.java
index 3eff455a840..c97f1e3e1a2 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/Main.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/Main.java
@@ -41,6 +41,7 @@
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.logging.log4j.LogManager;
 
 /**
  * A bookie server is a server that run bookie and serving rpc requests.
@@ -222,6 +223,7 @@ static int doMain(String[] args) {
             server = buildBookieServer(new BookieConfiguration(conf));
         } catch (Exception e) {
             log.error("Failed to build bookie server", e);
+            LogManager.shutdown();
             return ExitCode.SERVER_EXCEPTION;
         }
 
diff --git a/stream/server/src/main/java/org/apache/bookkeeper/stream/server/StorageServer.java b/stream/server/src/main/java/org/apache/bookkeeper/stream/server/StorageServer.java
index 99e70188a6d..6c3596c77e2 100644
--- a/stream/server/src/main/java/org/apache/bookkeeper/stream/server/StorageServer.java
+++ b/stream/server/src/main/java/org/apache/bookkeeper/stream/server/StorageServer.java
@@ -78,6 +78,7 @@
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.distributedlog.DistributedLogConfiguration;
+import org.apache.logging.log4j.LogManager;
 
 /**
  * A storage server is a server that run storage service and serving rpc requests.
@@ -170,6 +171,7 @@ static int doMain(String[] args) {
                 grpcUseHostname);
         } catch (Exception e) {
             log.error("Invalid storage configuration", e);
+            LogManager.shutdown();
             return ExitCode.INVALID_CONF.code();
         }