fix: not logging termination unix signals

Under container environments like ECS, it's hard to know when PostgREST
is being terminated.
This commit is contained in:
steve-chavez
2026-03-20 13:09:10 -05:00
committed by Steve Chavez
parent 12ef63370b
commit 622c6d3f19
6 changed files with 36 additions and 11 deletions
+4
View File
@@ -15,6 +15,10 @@ All notable changes to this project will be documented in this file. From versio
- Add config `client_error_verbosity` to customize error verbosity by @taimoorzaeem in #4088, #3980, #3824
- Add `Vary` header to responses by @develop7 in #4609
### Fixed
- Fix not logging SIGTERM and SIGINT by @steve-chavez in #4728
### Changed
- All responses now include a `Vary` header by @develop7 in #4609
+1 -2
View File
@@ -80,7 +80,7 @@ run appState = do
AppState.schemaCacheLoader appState -- Loads the initial SchemaCache
(mainSocket, adminSocket) <- initSockets conf
Unix.installSignalHandlers (AppState.getMainThreadId appState) (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
Unix.installSignalHandlers observer (AppState.getMainThreadId appState) (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
Listener.runListener appState
@@ -283,4 +283,3 @@ initSockets AppConfig{..} = do
Nothing -> pure Nothing
pure (sock, adminSock)
+2
View File
@@ -228,6 +228,8 @@ observationMessages = \case
pure "Looked up a JWT in JWT cache"
JwtCacheEviction ->
pure "Evicted entry from JWT cache"
TerminationUnixSignalObs signal ->
pure $ "Received termination unix signal " <> signal
WarpErrorObs txt ->
pure $ "Warp server error: " <> txt
where
+1
View File
@@ -54,6 +54,7 @@ data Observation
| PoolRequestFullfilled
| JwtCacheLookup Bool
| JwtCacheEviction
| TerminationUnixSignalObs Text
| WarpErrorObs Text
data ObsFatalError = ServerAuthError | ServerPgrstBug | ServerError42P05 | ServerError08P01
+10 -9
View File
@@ -11,26 +11,27 @@ import qualified System.Posix.Signals as Signals
import System.Posix.Types (FileMode)
import System.PosixCompat.Files (setFileMode)
import Data.String (String)
import qualified Network.Socket as NS
import Data.String (String)
import qualified Network.Socket as NS
import qualified PostgREST.Observation as Observation
import Protolude
import System.Directory (removeFile)
import System.IO.Error (isDoesNotExistError)
import System.Directory (removeFile)
import System.IO.Error (isDoesNotExistError)
-- | Set signal handlers, only for systems with signals
installSignalHandlers :: ThreadId -> IO () -> IO () -> IO ()
installSignalHandlers :: Observation.ObservationHandler -> ThreadId -> IO () -> IO () -> IO ()
#ifndef mingw32_HOST_OS
installSignalHandlers tid usr1 usr2 = do
installSignalHandlers observer tid usr1 usr2 = do
let interrupt = throwTo tid UserInterrupt
install Signals.sigINT interrupt
install Signals.sigTERM interrupt
install Signals.sigINT $ observer (Observation.TerminationUnixSignalObs "SIGINT") >> interrupt
install Signals.sigTERM $ observer (Observation.TerminationUnixSignalObs "SIGTERM") >> interrupt
install Signals.sigUSR1 usr1
install Signals.sigUSR2 usr2
where
install signal handler =
void $ Signals.installHandler signal (Signals.Catch handler) Nothing
#else
installSignalHandlers _ _ _ = pass
installSignalHandlers _ _ _ _ = pass
#endif
-- | Create a unix domain socket and bind it to the given path.
+18
View File
@@ -127,6 +127,24 @@ def test_graceful_shutdown_waits_for_in_flight_request(defaultenv):
t.join()
def test_termination_unix_signal_logging(defaultenv):
"Server logs when handling termination unix signals."
with run(env=defaultenv) as postgrest:
postgrest.process.send_signal(signal.SIGTERM)
lines = postgrest.read_stdout(nlines=1)
wait_until_exit(postgrest)
assert any("SIGTERM" in line for line in lines)
with run(env=defaultenv) as postgrest:
postgrest.process.send_signal(signal.SIGINT)
lines = postgrest.read_stdout(nlines=1)
wait_until_exit(postgrest)
assert any("SIGINT" in line for line in lines)
def test_random_port_bound(defaultenv):
"PostgREST should bind to a random port when PGRST_SERVER_PORT is 0."