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
+6 -5
View File
@@ -13,24 +13,25 @@ import System.PosixCompat.Files (setFileMode)
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)
-- | 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."