Currently log messages generated by pgaudit can be made visible to the client simply by altering client_min_messages. While this has not been a showstopper for anyone it's ideal, either.

The client authentication code sets the global variable ClientAuthInProgress which causes ereport() to filter client output < ERROR while forcing client output >= ERROR. This functionality would also work well for pgaudit.

The patch creates a new counter to separate the log filtering from the authentication functionality. This makes it possible to get the same filtering in other parts of the code (or extensions) without abusing the ClientAuthInProgress variable or using the log hook.

I also considered a new function for ereport (like errhidecontext()) but this mechanism would not have worked for authentication and so would not have been used anywhere in core.

If there are no objections I'll submit it to the next commitfest.

--
-David
da...@pgmasters.net
diff --git a/src/backend/postmaster/postmaster.c 
b/src/backend/postmaster/postmaster.c
index 3cba0e5..6a8399d 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4013,8 +4013,16 @@ BackendInitialize(Port *port)
        if (PreAuthDelay > 0)
                pg_usleep(PreAuthDelay * 1000000L);
 
-       /* This flag will remain set until InitPostgres finishes authentication 
*/
-       ClientAuthInProgress = true;    /* limit visibility of log messages */
+       /*
+        * ClientAuthInProgress is a flag which is set from this point until
+        * InitPostgres finishes with authentication to let
+        * StatementTimeoutHandler() and quickdie() know that we are performing
+        * authentication and to act accordingly.
+        */
+       ClientAuthInProgress = true;
+
+       /* Hide non-ERROR messages from the client */
+       LimitClientLogOutput(true);
 
        /* save process start time */
        port->SessionStartTime = GetCurrentTimestamp();
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 8b5b6c5..db1ecbb 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -69,7 +69,6 @@
 #include "libpq/pqformat.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
-#include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
 #include "storage/ipc.h"
 #include "storage/proc.h"
@@ -93,6 +92,13 @@ sigjmp_buf *PG_exception_stack = NULL;
 extern bool redirection_done;
 
 /*
+ * When LimitClientLogOutputCounter > 0, client output < ERROR will be
+ * suppressed and >= ERROR will be output without regard for
+ * client_min_messages. See LimitClientLogOutput() and errstart().
+ */
+int LimitClientLogOutputCounter = 0;
+
+/*
  * Hook for intercepting messages before they are sent to the server log.
  * Note that the hook will not get called for messages that are suppressed
  * by log_min_messages.  Also note that logging hooks implemented in preload
@@ -299,7 +305,7 @@ errstart(int elevel, const char *filename, int lineno,
                 * reasons and because many clients can't handle NOTICE messages
                 * during authentication.
                 */
-               if (ClientAuthInProgress)
+               if (LimitClientLogOutputCounter > 0)
                        output_to_client = (elevel >= ERROR);
                else
                        output_to_client = (elevel >= client_min_messages ||
@@ -1738,7 +1744,7 @@ pg_re_throw(void)
                        edata->output_to_server = (FATAL >= log_min_messages);
                if (whereToSendOutput == DestRemote)
                {
-                       if (ClientAuthInProgress)
+                       if (LimitClientLogOutputCounter > 0)
                                edata->output_to_client = true;
                        else
                                edata->output_to_client = (FATAL >= 
client_min_messages);
@@ -1836,6 +1842,27 @@ GetErrorContextStack(void)
 
 
 /*
+ * LimitClientLogOutput - Limit client log output to >= ERROR
+ *
+ * When LimitClientLogOutputCounter > 0, client output < ERROR will be
+ * suppressed and >= ERROR will be output without regard for
+ * client_min_messages. See LimitClientLogOutputCounter and errstart().
+ */
+void
+LimitClientLogOutput(bool state)
+{
+       if (state)
+               LimitClientLogOutputCounter++;
+       else
+       {
+               Assert(LimitClientLogOutputCounter > 0);
+
+               LimitClientLogOutputCounter--;
+       }
+}
+
+
+/*
  * Initialization of error output file
  */
 void
diff --git a/src/backend/utils/init/postinit.c 
b/src/backend/utils/init/postinit.c
index 7b19714..5471758 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -181,8 +181,8 @@ GetDatabaseTupleByOid(Oid dboid)
 static void
 PerformAuthentication(Port *port)
 {
-       /* This should be set already, but let's make sure */
-       ClientAuthInProgress = true;    /* limit visibility of log messages */
+       /* Client authentication must be in progress.  See BackendInitialize(). 
*/
+       Assert(ClientAuthInProgress);
 
        /*
         * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
@@ -275,7 +275,8 @@ PerformAuthentication(Port *port)
 
        set_ps_display("startup", false);
 
-       ClientAuthInProgress = false;           /* client_min_messages is 
active now */
+       ClientAuthInProgress = false;   /* Client authentication has finished */
+       LimitClientLogOutput(false);    /* No longer need to hide non-ERROR 
messages */
 }
 
 
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 7715719..a0671c1 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -376,6 +376,8 @@ extern void ReThrowError(ErrorData *edata) 
pg_attribute_noreturn();
 extern void ThrowErrorData(ErrorData *edata);
 extern void pg_re_throw(void) pg_attribute_noreturn();
 
+extern void LimitClientLogOutput(bool state);
+
 extern char *GetErrorContextStack(void);
 
 /* Hook for intercepting messages before they are sent to the server log */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to