add: make config log-level reloadable

Closes #5113.

Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
This commit is contained in:
Taimoor Zaeem
2026-07-28 11:33:33 +05:00
parent f6d34fd4fc
commit 022f0faa38
8 changed files with 107 additions and 56 deletions
+3
View File
@@ -3,3 +3,6 @@ db-schemas = "public"
app.settings.name_var = "John"
jwt-secret = "invalidinvalidinvalidinvalidinvalid"
# will be replaced in test
log-level = "error"
+37
View File
@@ -1931,3 +1931,40 @@ def test_use_legacy_target_names(enabled, defaultenv):
else:
assert response.status_code == 400
assert not has_warning_log and not has_hint_log
def test_config_log_level_is_reloadable(tmp_path, defaultenv):
"Config log-level should be reloadable on SIGUSR2"
config = (CONFIGSDIR / "sigusr2-settings.config").read_text()
configfile = tmp_path / "test.config"
configfile.write_text(config)
# Delete the env variable for "log-level" so the config file value isn't overridden
del defaultenv["PGRST_LOG_LEVEL"]
with run(configfile, env=defaultenv) as postgrest:
response = postgrest.session.get("/projects")
assert response.status_code == 200
output = postgrest.read_stdout(nlines=5)
# log-level = error, so this log line shouldn't be logged
assert not any(
"Trying to borrow a connection from pool" in line for line in output
)
# change setting
configfile.write_text(
config.replace('log-level = "error"', 'log-level = "debug"')
)
# reload
postgrest.process.send_signal(signal.SIGUSR2)
sleep_until_postgrest_config_reload()
response = postgrest.session.get("/projects")
assert response.status_code == 200
output = postgrest.read_stdout(nlines=5)
# log-level = debug now, so this log line must be logged
assert any("Trying to borrow a connection from pool" in line for line in output)
+4 -2
View File
@@ -5,6 +5,7 @@ import qualified Hasql.Pool.Config as P
import qualified Hasql.Transaction.Sessions as HT
import Data.Function (id)
import Data.IORef (newIORef, readIORef)
import PostgREST.App (postgrest)
import qualified PostgREST.AppState as AppState
@@ -48,14 +49,15 @@ main = do
-- cached schema cache so most tests run fast
baseSchemaCache <- loadSCache pool testCfg
loggerState <- Logger.init
let
initApp sCache config = do
-- duplicate poolChan as a starting point
confRef <- newIORef config
loggerState <- Logger.init (configLogLevel <$> readIORef confRef)
obsChan <- dupChan poolChan
stateObsChan <- newObsChan obsChan
appState <- AppState.initWithPool pool config loggerState metricsState (Metrics.observationMetrics metricsState <> writeChan obsChan) mempty
appState <- AppState.initWithPool pool confRef loggerState metricsState (Metrics.observationMetrics metricsState <> writeChan obsChan) mempty
AppState.putPgVersion appState actualPgVersion
AppState.putSchemaCache appState (Just sCache)
return (SpecState appState metricsState stateObsChan, postgrest appState (pure ()))
+4 -2
View File
@@ -5,6 +5,7 @@ import qualified Hasql.Pool.Config as P
import qualified Hasql.Transaction.Sessions as HT
import Data.Function (id)
import Data.IORef (newIORef, readIORef)
import Test.Hspec
@@ -88,12 +89,13 @@ main = do
-- cached schema cache so most tests run fast
baseSchemaCache <- loadSCache pool baseCfg
loggerState <- Logger.init
metricsState <- Metrics.init (configDbPoolSize baseCfg)
let
initApp sCache config = do
appState <- AppState.initWithPool pool config loggerState metricsState (Metrics.observationMetrics metricsState) mempty
confRef <- newIORef config
loggerState <- Logger.init (configLogLevel <$> readIORef confRef)
appState <- AppState.initWithPool pool confRef loggerState metricsState (Metrics.observationMetrics metricsState) mempty
AppState.putPgVersion appState actualPgVersion
AppState.putSchemaCache appState (Just sCache)
return ((), postgrest appState (pure ()))