diff --git a/CHANGELOG.md b/CHANGELOG.md index 283e9e8fa..6442b9c57 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 +### Added + +- Log the actual host and port of listener database connection by @mkleczek in #4617 + ## [14.8] - 2026-04-03 ### Added diff --git a/src/PostgREST/Listener.hs b/src/PostgREST/Listener.hs index a5d12aa1a..2872cdc1d 100644 --- a/src/PostgREST/Listener.hs +++ b/src/PostgREST/Listener.hs @@ -17,8 +17,11 @@ import PostgREST.Version (prettyVersion) import qualified PostgREST.AppState as AppState import qualified PostgREST.Config as Config -import Data.Either.Combinators (whenRight) -import Protolude +import Control.Arrow ((&&&)) +import Data.Bitraversable (bisequence) +import Data.Either.Combinators (whenRight) +import qualified Database.PostgreSQL.LibPQ as LibPQ +import Protolude -- | Starts the Listener in a thread runListener :: AppState -> IO () @@ -72,8 +75,8 @@ retryingListen appState = do -- reset the delay AppState.putNextListenerDelay appState 1 - observer $ DBListenStart dbChannel - + (pqHost, pqPort) <- SQL.withLibPQConnection db $ bisequence . (LibPQ.host &&& LibPQ.port) + observer $ DBListenStart pqHost pqPort dbChannel -- wait for notifications -- this will never return, in case of an error it will throw and be caught by onError forever $ SQL.waitForNotifications handleNotification db diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index 8c033f176..1169897d6 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -45,7 +45,7 @@ data Observation | SchemaCacheSummaryObs Text | SchemaCacheLoadedObs Double | ConnectionRetryObs Int - | DBListenStart Text + | DBListenStart (Maybe ByteString) (Maybe ByteString) Text -- host, port, channel | DBListenFail Text (Either SQL.ConnectionError SomeException) | DBListenRetry Int | DBListenBugHint -- https://github.com/PostgREST/postgrest/issues/3147 @@ -114,8 +114,8 @@ observationMessage = \case "Attempting to reconnect to the database in " <> (show delay::Text) <> " seconds..." QueryPgVersionError usageErr -> "Failed to query the PostgreSQL version. " <> jsonMessage usageErr - DBListenStart channel -> do - "Listening for database notifications on the " <> show channel <> " channel" + DBListenStart host port channel -> do + "Listener connected to " <> show (fold $ host <> fmap (":" <>) port) <> " and listening for database notifications on the " <> show channel <> " channel" DBListenFail channel listenErr -> "Failed listening for database notifications on the " <> show channel <> " channel. " <> either showListenerConnError showListenerException listenErr diff --git a/test/io/test_io.py b/test/io/test_io.py index 1a2327df5..641476283 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -1658,6 +1658,23 @@ def test_log_listener_connection_errors(defaultenv): ) +def test_log_listener_connection_start(defaultenv): + "The logs should show the listener connection start message in a single line" + + env = { + **defaultenv, + "PGRST_DB_CHANNEL_ENABLED": "true", + } + + with run(env=env, no_startup_stdout=False, wait_for_readiness=True) as postgrest: + output = postgrest.read_stdout(nlines=5) + assert any( + f'Listener connected to "{defaultenv["PGHOST"]}:5432" and listening for database notifications on the "pgrst" channel' + in line + for line in output + ) + + def test_db_pre_config_with_pg_reserved_words(defaultenv): "The db-pre-config should not fail unexpectedly when function name is a postgres reserved word" diff --git a/test/observability/ObsHelper.hs b/test/observability/ObsHelper.hs index d53cc81d8..e1ff88bc0 100644 --- a/test/observability/ObsHelper.hs +++ b/test/observability/ObsHelper.hs @@ -206,5 +206,5 @@ waitForObs (ObsChan orig copy) t msg f = obsDiagMessage :: Observation -> Text obsDiagMessage = \case (HasqlPoolObs o) -> show o - o@(DBListenStart channel) -> constrName o <> show channel + o@(DBListenStart host port channel) -> constrName o <> show (host, port, channel) o -> constrName o