Skip to content

Commit 7356c04

Browse files
committed
[server] Register signal handlers to log termination due to SIGTERM, SIGHUP and SIGINT
1 parent ae84521 commit 7356c04

File tree

4 files changed

+256
-1
lines changed

4 files changed

+256
-1
lines changed

fluss-server/src/main/java/org/apache/fluss/server/ServerBase.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.fluss.server.utils.ConfigurationParserUtils;
3333
import org.apache.fluss.server.utils.FatalErrorHandler;
3434
import org.apache.fluss.server.utils.ShutdownHookUtil;
35+
import org.apache.fluss.server.utils.SignalHandler;
3536
import org.apache.fluss.utils.AutoCloseableAsync;
3637
import org.apache.fluss.utils.ExceptionUtils;
3738
import org.apache.fluss.utils.concurrent.FutureUtils;
@@ -113,6 +114,7 @@ protected static void startServer(ServerBase server) {
113114
}
114115

115116
public void start() throws Exception {
117+
SignalHandler.register(LOG);
116118
try {
117119
addShutDownHook();
118120

fluss-server/src/main/java/org/apache/fluss/server/tablet/TabletServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ protected void startServices() throws Exception {
284284
@Override
285285
protected CompletableFuture<Result> closeAsync(Result result) {
286286
if (isShutDown.compareAndSet(false, true)) {
287-
287+
LOG.info("Shutting down Tablet server ({}).", result);
288288
controlledShutDown();
289289

290290
CompletableFuture<Void> serviceShutdownFuture = stopServices();
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.fluss.server.utils;
19+
20+
import org.apache.fluss.annotation.Internal;
21+
22+
/* This file is based on source code of Apache Flink Project (https://flink.apache.org/), licensed by the Apache
23+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
24+
* additional information regarding copyright ownership. */
25+
26+
/** An enumeration indicating the operating system that the JVM runs on. */
27+
@Internal
28+
public enum OperatingSystem {
29+
LINUX,
30+
WINDOWS,
31+
MAC_OS,
32+
FREE_BSD,
33+
SOLARIS,
34+
UNKNOWN;
35+
36+
// ------------------------------------------------------------------------
37+
38+
/**
39+
* Gets the operating system that the JVM runs on from the java system properties. this method
40+
* returns <tt>UNKNOWN</tt>, if the operating system was not successfully determined.
41+
*
42+
* @return The enum constant for the operating system, or <tt>UNKNOWN</tt>, if it was not
43+
* possible to determine.
44+
*/
45+
public static OperatingSystem getCurrentOperatingSystem() {
46+
return os;
47+
}
48+
49+
/**
50+
* Checks whether the operating system this JVM runs on is Windows.
51+
*
52+
* @return <code>true</code> if the operating system this JVM runs on is Windows, <code>false
53+
* </code> otherwise
54+
*/
55+
public static boolean isWindows() {
56+
return getCurrentOperatingSystem() == WINDOWS;
57+
}
58+
59+
/**
60+
* Checks whether the operating system this JVM runs on is Linux.
61+
*
62+
* @return <code>true</code> if the operating system this JVM runs on is Linux, <code>false
63+
* </code> otherwise
64+
*/
65+
public static boolean isLinux() {
66+
return getCurrentOperatingSystem() == LINUX;
67+
}
68+
69+
/**
70+
* Checks whether the operating system this JVM runs on is Windows.
71+
*
72+
* @return <code>true</code> if the operating system this JVM runs on is Windows, <code>false
73+
* </code> otherwise
74+
*/
75+
public static boolean isMac() {
76+
return getCurrentOperatingSystem() == MAC_OS;
77+
}
78+
79+
/**
80+
* Checks whether the operating system this JVM runs on is FreeBSD.
81+
*
82+
* @return <code>true</code> if the operating system this JVM runs on is FreeBSD, <code>false
83+
* </code> otherwise
84+
*/
85+
public static boolean isFreeBSD() {
86+
return getCurrentOperatingSystem() == FREE_BSD;
87+
}
88+
89+
/**
90+
* Checks whether the operating system this JVM runs on is Solaris.
91+
*
92+
* @return <code>true</code> if the operating system this JVM runs on is Solaris, <code>false
93+
* </code> otherwise
94+
*/
95+
public static boolean isSolaris() {
96+
return getCurrentOperatingSystem() == SOLARIS;
97+
}
98+
99+
/** The enum constant for the operating system. */
100+
private static final OperatingSystem os = readOSFromSystemProperties();
101+
102+
/**
103+
* Parses the operating system that the JVM runs on from the java system properties. If the
104+
* operating system was not successfully determined, this method returns {@code UNKNOWN}.
105+
*
106+
* @return The enum constant for the operating system, or {@code UNKNOWN}, if it was not
107+
* possible to determine.
108+
*/
109+
private static OperatingSystem readOSFromSystemProperties() {
110+
String osName = System.getProperty(OS_KEY);
111+
112+
if (osName.startsWith(LINUX_OS_PREFIX)) {
113+
return LINUX;
114+
}
115+
if (osName.startsWith(WINDOWS_OS_PREFIX)) {
116+
return WINDOWS;
117+
}
118+
if (osName.startsWith(MAC_OS_PREFIX)) {
119+
return MAC_OS;
120+
}
121+
if (osName.startsWith(FREEBSD_OS_PREFIX)) {
122+
return FREE_BSD;
123+
}
124+
String osNameLowerCase = osName.toLowerCase();
125+
if (osNameLowerCase.contains(SOLARIS_OS_INFIX_1)
126+
|| osNameLowerCase.contains(SOLARIS_OS_INFIX_2)) {
127+
return SOLARIS;
128+
}
129+
130+
return UNKNOWN;
131+
}
132+
133+
// --------------------------------------------------------------------------------------------
134+
// Constants to extract the OS type from the java environment
135+
// --------------------------------------------------------------------------------------------
136+
137+
/** The key to extract the operating system name from the system properties. */
138+
private static final String OS_KEY = "os.name";
139+
140+
/** The expected prefix for Linux operating systems. */
141+
private static final String LINUX_OS_PREFIX = "Linux";
142+
143+
/** The expected prefix for Windows operating systems. */
144+
private static final String WINDOWS_OS_PREFIX = "Windows";
145+
146+
/** The expected prefix for Mac OS operating systems. */
147+
private static final String MAC_OS_PREFIX = "Mac";
148+
149+
/** The expected prefix for FreeBSD. */
150+
private static final String FREEBSD_OS_PREFIX = "FreeBSD";
151+
152+
/** One expected infix for Solaris. */
153+
private static final String SOLARIS_OS_INFIX_1 = "sunos";
154+
155+
/** One expected infix for Solaris. */
156+
private static final String SOLARIS_OS_INFIX_2 = "solaris";
157+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.fluss.server.utils;
19+
20+
import org.slf4j.Logger;
21+
import sun.misc.Signal;
22+
23+
/* This file is based on source code of Apache Flink Project (https://flink.apache.org/), licensed by the Apache
24+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
25+
* additional information regarding copyright ownership. */
26+
27+
/**
28+
* This signal handler / signal logger is based on Apache Hadoop's
29+
* org.apache.hadoop.util.SignalLogger.
30+
*/
31+
public class SignalHandler {
32+
33+
private static boolean registered = false;
34+
35+
/** Our signal handler. */
36+
private static class Handler implements sun.misc.SignalHandler {
37+
38+
private final Logger log;
39+
private final sun.misc.SignalHandler prevHandler;
40+
41+
Handler(String name, Logger log) {
42+
this.log = log;
43+
prevHandler = Signal.handle(new Signal(name), this);
44+
}
45+
46+
/**
47+
* Handle an incoming signal.
48+
*
49+
* @param signal The incoming signal
50+
*/
51+
@Override
52+
public void handle(Signal signal) {
53+
log.warn(
54+
"RECEIVED SIGNAL {}: SIG{}. Shutting down as requested.",
55+
signal.getNumber(),
56+
signal.getName());
57+
prevHandler.handle(signal);
58+
}
59+
}
60+
61+
/**
62+
* Register some signal handlers.
63+
*
64+
* @param log The slf4j logger
65+
*/
66+
public static void register(final Logger log) {
67+
synchronized (SignalHandler.class) {
68+
if (registered) {
69+
return;
70+
}
71+
registered = true;
72+
73+
final String[] signals =
74+
OperatingSystem.isWindows()
75+
? new String[] {"TERM", "INT"}
76+
: new String[] {"TERM", "HUP", "INT"};
77+
78+
StringBuilder bld = new StringBuilder();
79+
bld.append("Registered UNIX signal handlers for [");
80+
81+
String separator = "";
82+
for (String signalName : signals) {
83+
try {
84+
new Handler(signalName, log);
85+
bld.append(separator);
86+
bld.append(signalName);
87+
separator = ", ";
88+
} catch (Exception e) {
89+
log.info("Error while registering signal handler", e);
90+
}
91+
}
92+
bld.append("]");
93+
log.info(bld.toString());
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)