]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Log remote NOTICE, WARNING, and similar messages using ereport().
authorFujii Masao <fujii@postgresql.org>
Tue, 22 Jul 2025 05:16:45 +0000 (14:16 +0900)
committerFujii Masao <fujii@postgresql.org>
Tue, 22 Jul 2025 05:16:45 +0000 (14:16 +0900)
Previously, NOTICE, WARNING, and similar messages received from remote
servers over replication, postgres_fdw, or dblink connections were printed
directly to stderr on the local server (e.g., the subscriber). As a result,
these messages lacked log prefixes (e.g., timestamp), making them harder
to trace and correlate with other log entries.

This commit addresses the issue by introducing a custom notice receiver
for replication, postgres_fdw, and dblink connections. These messages
are now logged via ereport(), ensuring they appear in the logs with proper
formatting and context, which improves clarity and aids in debugging.

Author: Vignesh C <vignesh21@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CALDaNm2xsHpWRtLm-VL_HJCsaE3+1Y_n-jDEAr3-suxVqc3xoQ@mail.gmail.com

contrib/dblink/dblink.c
contrib/postgres_fdw/connection.c
src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
src/include/libpq/libpq-be-fe-helpers.h

index 8a0b112a7ff294db0bfc9e1c0d3d056e381b1f11..c459a842fa95e69e7e76f1f4f38d874046784157 100644 (file)
@@ -240,6 +240,10 @@ dblink_get_conn(char *conname_or_str,
                                         errmsg("could not establish connection"),
                                         errdetail_internal("%s", msg)));
                }
+
+               PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+                                                       gettext_noop("received message via remote connection"));
+
                dblink_security_check(conn, NULL, connstr);
                if (PQclientEncoding(conn) != GetDatabaseEncoding())
                        PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +342,9 @@ dblink_connect(PG_FUNCTION_ARGS)
                                 errdetail_internal("%s", msg)));
        }
 
+       PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+                                               gettext_noop("received message via remote connection"));
+
        /* check password actually used if not superuser */
        dblink_security_check(conn, connname, connstr);
 
index 304f3c20f835697d352dbfb91b1b11d54e6afc0a..e41d47c3bbd1ab3e07bc7319fb82cfbcbca3cdb3 100644 (file)
@@ -625,6 +625,9 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
                                                        server->servername),
                                         errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
 
+               PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+                                                       gettext_noop("received message via remote connection"));
+
                /* Perform post-connection security checks. */
                pgfdw_security_check(keywords, values, user, conn);
 
index f7b5d093681a2cfde0a610828e1f94ffe6b634bc..0c75fe064d5ec973ff6621359d7a97170e626d3c 100644 (file)
@@ -232,6 +232,9 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical,
                                 errhint("Target server's authentication method must be changed, or set password_required=false in the subscription parameters.")));
        }
 
+       PQsetNoticeReceiver(conn->streamConn, libpqsrv_notice_receiver,
+                                               gettext_noop("received message via replication"));
+
        /*
         * Set always-secure search path for the cases where the connection is
         * used to run SQL queries, so malicious users can't get control.
index 16205b824fa55de8c55a4b8de495817b32a0fb10..49137a0a5706aeb80846423bc54d6a59a0b5dbcd 100644 (file)
@@ -454,4 +454,34 @@ exit:      ;
        return error;
 }
 
+/*
+ * libpqsrv_notice_receiver
+ *
+ * Custom notice receiver for libpq connections.
+ *
+ * This function is intended to be set via PQsetNoticeReceiver() so that
+ * NOTICE, WARNING, and similar messages from the connection are reported via
+ * ereport(), instead of being printed to stderr.
+ */
+static inline void
+libpqsrv_notice_receiver(void *arg, const PGresult *res)
+{
+       char       *message;
+       int                     len;
+       char       *prefix = (char *) arg;
+
+       /*
+        * Trim the trailing newline from the message text returned from
+        * PQresultErrorMessage(), as it always includes one, to produce cleaner
+        * log output.
+        */
+       message = PQresultErrorMessage(res);
+       len = strlen(message);
+       if (len > 0 && message[len - 1] == '\n')
+               len--;
+
+       ereport(LOG,
+                       errmsg_internal("%s: %.*s", _(prefix), len, message));
+}
+
 #endif                                                 /* LIBPQ_BE_FE_HELPERS_H */