diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c3b5896f..d2217ad29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. From versio ## Unreleased +### Fixed + +- Fix not logging SIGTERM and SIGINT by @steve-chavez in #4728 + ## [14.6] - 2026-03-06 ### Fixed diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 64e31b194..a75a3fce6 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -72,7 +72,7 @@ run appState = do conf@AppConfig{..} <- AppState.getConfig appState AppState.schemaCacheLoader appState -- Loads the initial SchemaCache - 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 diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index b93d67e59..6560cda6f 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -63,6 +63,7 @@ data Observation | PoolRequestFullfilled | JwtCacheLookup Bool | JwtCacheEviction + | TerminationUnixSignalObs Text | WarpErrorObs Text data ObsFatalError = ServerAuthError | ServerPgrstBug | ServerError42P05 | ServerError08P01 @@ -158,6 +159,8 @@ observationMessage = \case "Looked up a JWT in JWT cache" JwtCacheEviction -> "Evicted entry from JWT cache" + TerminationUnixSignalObs signal -> + "Received termination unix signal " <> signal WarpErrorObs txt -> "Warp server error: " <> txt where diff --git a/src/PostgREST/Unix.hs b/src/PostgREST/Unix.hs index 2027cac02..2128c6cb9 100644 --- a/src/PostgREST/Unix.hs +++ b/src/PostgREST/Unix.hs @@ -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. diff --git a/test/io/test_io.py b/test/io/test_io.py index df284f345..1a2327df5 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -105,6 +105,24 @@ def test_flush_pool_no_interrupt(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."