Re: Proposed GUC Variable - Mailing list pgsql-hackers

From Bruce Momjian
Subject Re: Proposed GUC Variable
Date
Msg-id 200209020541.g825fRe13793@candle.pha.pa.us
Whole thread Raw
In response to Re: Proposed GUC Variable  (Gavin Sherry <swm@linuxworld.com.au>)
List pgsql-hackers
OK, attached patch applied.  I made a few changes.  I added a mention
they may want to enable LOG_PID because there is no guarantee that the
statement and error will appear next to each other in the log file.  I
also renamed 'query' to 'statement' to be more precise.

Also, is there any way to disable this feature?   I can't see how.

Also, you added this line:

    + extern bool Debug_print_error_query;

I assume it was a mistake.

---------------------------------------------------------------------------

Gavin Sherry wrote:
> On Thu, 29 Aug 2002, Tom Lane wrote:
>
> > Gavin Sherry <swm@linuxworld.com.au> writes:
> > > That's a pretty good idea. Now, what format will the argument take: text
> > > (NOTICE, ERROR, DEBUG, etc) or integer? The increasing severity is clear
> > > with numbers but the correlation to NOTICE, ERROR etc is undocumented
> > > IIRC. On the other hand, the textual form is clear but INFO < NOTICE <
> > > WARNING < ERROR < FATAL, etc, is note necessarily obvious.
> >
> > The variable should take the same values as SERVER_MIN_MESSAGES and
> > impose the same priority order as it does.  I would assume you could
> > share code, or at worst copy-and-paste a few dozen lines.
>
> A patch implementing this is attached. Instead of copy-and-pasting the
> code, I abstracted out of the lookup and converted the existing functions
> to use it.
>
> I was careful in elog() to ignore elog(LOG) calls when
> log_min_error_query >= LOG.
>
> Gavin

Content-Description:

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/runtime.sgml,v
retrieving revision 1.132
diff -c -c -r1.132 runtime.sgml
*** doc/src/sgml/runtime.sgml    1 Sep 2002 23:26:06 -0000    1.132
--- doc/src/sgml/runtime.sgml    2 Sep 2002 05:35:45 -0000
***************
*** 942,948 ****
         </para>
        </listitem>
       </varlistentry>
-
       <varlistentry>
        <term><varname>EXPLAIN_PRETTY_PRINT</varname> (<type>boolean</type>)</term>
        <listitem>
--- 942,947 ----
***************
*** 979,984 ****
--- 978,1005 ----
       </varlistentry>

       <varlistentry>
+       <term><varname>LOG_MIN_ERROR_STATEMENT</varname> (<type>string</type>)</term>
+       <listitem>
+        <para>
+         This controls which log messages are accompanied by the original
+         query which generated the message. All queries matching the setting
+         or which are of a higher severity than the setting are logged. The
+         default is <literal>ERROR</literal>. Valid values are
+         <literal>DEBUG5</literal>, <literal>DEBUG4</literal>,
+         <literal>DEBUG3</literal>, <literal>DEBUG2</literal>,
+         <literal>DEBUG1</literal>, <literal>INFO</literal>,
+         <literal>NOTICE</literal>, <literal>WARNING</literal>
+         and <literal>ERROR</literal>.
+        </para>
+        <para>
+         It is recommended you enable <literal>LOG_PID</literal> as well
+         so you can more easily match the error statement with the error
+         message.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
        <term><varname>LOG_PID</varname> (<type>boolean</type>)</term>
        <listitem>
         <para>
***************
*** 1005,1012 ****
        <listitem>
         <para>
          Prints the duration of every completed query.  To use this option,
!         enable LOG_STATEMENT and LOG_PID so you can link the original query
!         to the duration using the process id.
         </para>
        </listitem>
       </varlistentry>
--- 1026,1033 ----
        <listitem>
         <para>
          Prints the duration of every completed query.  To use this option,
!         enable <literal>LOG_STATEMENT</> and <literal>LOG_PID</> so you
!         can link the original query to the duration using the process id.
         </para>
        </listitem>
       </varlistentry>
Index: src/backend/utils/error/elog.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/error/elog.c,v
retrieving revision 1.101
diff -c -c -r1.101 elog.c
*** src/backend/utils/error/elog.c    2 Sep 2002 02:47:05 -0000    1.101
--- src/backend/utils/error/elog.c    2 Sep 2002 05:35:51 -0000
***************
*** 33,49 ****
  #include "storage/proc.h"
  #include "tcop/tcopprot.h"
  #include "utils/memutils.h"

  #include "mb/pg_wchar.h"

- int            server_min_messages;
- char       *server_min_messages_str = NULL;
- const char    server_min_messages_str_default[] = "notice";
-
- int            client_min_messages;
- char       *client_min_messages_str = NULL;
- const char    client_min_messages_str_default[] = "notice";
-
  #ifdef HAVE_SYSLOG
  /*
   * 0 = only stdout/stderr
--- 33,42 ----
  #include "storage/proc.h"
  #include "tcop/tcopprot.h"
  #include "utils/memutils.h"
+ #include "utils/guc.h"

  #include "mb/pg_wchar.h"

  #ifdef HAVE_SYSLOG
  /*
   * 0 = only stdout/stderr
***************
*** 345,350 ****
--- 338,344 ----
          }
      }

+
      /*
       * Message prepared; send it where it should go
       */
***************
*** 433,438 ****
--- 427,440 ----
      if (msg_buf != msg_fixedbuf)
          free(msg_buf);

+     /* If the user wants this elog() generating query logged,
+      * do so. We only want to log if the query has been
+      * written to debug_query_string. Also, avoid infinite loops.
+      */
+
+     if(lev != LOG && lev >= log_min_error_statement && debug_query_string)
+         elog(LOG,"statement: %s",debug_query_string);
+
      /*
       * Perform error recovery action as specified by lev.
       */
***************
*** 835,905 ****
  }


- /*
-  * GUC support routines
-  */
- const char *
- assign_server_min_messages(const char *newval,
-                            bool doit, bool interactive)
- {
-     if (strcasecmp(newval, "debug") == 0)
-         { if (doit) server_min_messages = DEBUG1; }
-     else if (strcasecmp(newval, "debug5") == 0)
-         { if (doit) server_min_messages = DEBUG5; }
-     else if (strcasecmp(newval, "debug4") == 0)
-         { if (doit) server_min_messages = DEBUG4; }
-     else if (strcasecmp(newval, "debug3") == 0)
-         { if (doit) server_min_messages = DEBUG3; }
-     else if (strcasecmp(newval, "debug2") == 0)
-         { if (doit) server_min_messages = DEBUG2; }
-     else if (strcasecmp(newval, "debug1") == 0)
-         { if (doit) server_min_messages = DEBUG1; }
-     else if (strcasecmp(newval, "info") == 0)
-         { if (doit) server_min_messages = INFO; }
-     else if (strcasecmp(newval, "notice") == 0)
-         { if (doit) server_min_messages = NOTICE; }
-     else if (strcasecmp(newval, "warning") == 0)
-         { if (doit) server_min_messages = WARNING; }
-     else if (strcasecmp(newval, "error") == 0)
-         { if (doit) server_min_messages = ERROR; }
-     else if (strcasecmp(newval, "log") == 0)
-         { if (doit) server_min_messages = LOG; }
-     else if (strcasecmp(newval, "fatal") == 0)
-         { if (doit) server_min_messages = FATAL; }
-     else if (strcasecmp(newval, "panic") == 0)
-         { if (doit) server_min_messages = PANIC; }
-     else
-         return NULL;            /* fail */
-     return newval;                /* OK */
- }

- const char *
- assign_client_min_messages(const char *newval,
-                            bool doit, bool interactive)
- {
-     if (strcasecmp(newval, "debug") == 0)
-         { if (doit) client_min_messages = DEBUG1; }
-     else if (strcasecmp(newval, "debug5") == 0)
-         { if (doit) client_min_messages = DEBUG5; }
-     else if (strcasecmp(newval, "debug4") == 0)
-         { if (doit) client_min_messages = DEBUG4; }
-     else if (strcasecmp(newval, "debug3") == 0)
-         { if (doit) client_min_messages = DEBUG3; }
-     else if (strcasecmp(newval, "debug2") == 0)
-         { if (doit) client_min_messages = DEBUG2; }
-     else if (strcasecmp(newval, "debug1") == 0)
-         { if (doit) client_min_messages = DEBUG1; }
-     else if (strcasecmp(newval, "log") == 0)
-         { if (doit) client_min_messages = LOG; }
-     else if (strcasecmp(newval, "info") == 0)
-         { if (doit) client_min_messages = INFO; }
-     else if (strcasecmp(newval, "notice") == 0)
-         { if (doit) client_min_messages = NOTICE; }
-     else if (strcasecmp(newval, "warning") == 0)
-         { if (doit) client_min_messages = WARNING; }
-     else if (strcasecmp(newval, "error") == 0)
-         { if (doit) client_min_messages = ERROR; }
-     else
-         return NULL;            /* fail */
-     return newval;                /* OK */
- }
--- 837,840 ----
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v
retrieving revision 1.91
diff -c -c -r1.91 guc.c
*** src/backend/utils/misc/guc.c    2 Sep 2002 01:05:06 -0000    1.91
--- src/backend/utils/misc/guc.c    2 Sep 2002 05:35:59 -0000
***************
*** 71,76 ****
--- 71,79 ----
                                     bool doit, bool interactive);
  #endif

+ static const char *assign_msglvl(int *var, const char *newval,
+                                     bool doit, bool interactive);
+
  /*
   * Debugging options
   */
***************
*** 99,104 ****
--- 102,120 ----

  bool        Password_encryption = true;

+ int            log_min_error_statement;
+ char        *log_min_error_statement_str = NULL;
+ const char    log_min_error_statement_str_default[] = "error";
+
+ int         server_min_messages;
+ char       *server_min_messages_str = NULL;
+ const char  server_min_messages_str_default[] = "notice";
+
+ int         client_min_messages;
+ char       *client_min_messages_str = NULL;
+ const char  client_min_messages_str_default[] = "notice";
+
+
  #ifndef PG_KRB_SRVTAB
  #define PG_KRB_SRVTAB ""
  #endif
***************
*** 727,732 ****
--- 743,753 ----
      },

      {
+         { "log_min_error_statement", PGC_USERSET }, &log_min_error_statement_str,
+         log_min_error_statement_str_default, assign_min_error_statement, NULL
+     },
+
+     {
          { "DateStyle", PGC_USERSET, GUC_LIST_INPUT }, &datestyle_string,
          "ISO, US", assign_datestyle, show_datestyle
      },
***************
*** 2877,2879 ****
--- 2898,2951 ----

      return newarray;
  }
+
+ const char *
+ assign_server_min_messages(const char *newval,
+                            bool doit, bool interactive)
+ {
+     return(assign_msglvl(&server_min_messages,newval,doit,interactive));
+ }
+
+ const char *
+ assign_client_min_messages(const char *newval,
+                            bool doit, bool interactive)
+ {
+     return(assign_msglvl(&client_min_messages,newval,doit,interactive));
+ }
+
+ const char *
+ assign_min_error_statement(const char *newval, bool doit, bool interactive)
+ {
+     return(assign_msglvl(&log_min_error_statement,newval,doit,interactive));
+ }
+
+ static const char *
+ assign_msglvl(int *var, const char *newval, bool doit, bool interactive)
+ {
+     if (strcasecmp(newval, "debug") == 0)
+         { if (doit) (*var) = DEBUG1; }
+     else if (strcasecmp(newval, "debug5") == 0)
+         { if (doit) (*var) = DEBUG5; }
+     else if (strcasecmp(newval, "debug4") == 0)
+         { if (doit) (*var) = DEBUG4; }
+     else if (strcasecmp(newval, "debug3") == 0)
+         { if (doit) (*var) = DEBUG3; }
+     else if (strcasecmp(newval, "debug2") == 0)
+         { if (doit) (*var) = DEBUG2; }
+     else if (strcasecmp(newval, "debug1") == 0)
+         { if (doit) (*var) = DEBUG1; }
+     else if (strcasecmp(newval, "log") == 0)
+         { if (doit) (*var) = LOG; }
+     else if (strcasecmp(newval, "info") == 0)
+         { if (doit) (*var) = INFO; }
+     else if (strcasecmp(newval, "notice") == 0)
+         { if (doit) (*var) = NOTICE; }
+     else if (strcasecmp(newval, "warning") == 0)
+         { if (doit) (*var) = WARNING; }
+     else if (strcasecmp(newval, "error") == 0)
+         { if (doit) (*var) = ERROR; }
+     else
+         return NULL;            /* fail */
+     return newval;                /* OK */
+ }
+
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.51
diff -c -c -r1.51 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample    1 Sep 2002 23:26:06 -0000    1.51
--- src/backend/utils/misc/postgresql.conf.sample    2 Sep 2002 05:36:00 -0000
***************
*** 127,132 ****
--- 127,135 ----
  #log_duration = false
  #log_timestamp = false

+ #log_min_error_statement = error        # Values in order of increasing severity:
+                                     # debug5, debug4, debug3, debug2, debug1,
+                                     # info, notice, warning, error
  #debug_print_parse = false
  #debug_print_rewritten = false
  #debug_print_plan = false
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/tab-complete.c,v
retrieving revision 1.61
diff -c -c -r1.61 tab-complete.c
*** src/bin/psql/tab-complete.c    1 Sep 2002 23:26:06 -0000    1.61
--- src/bin/psql/tab-complete.c    2 Sep 2002 05:36:05 -0000
***************
*** 271,277 ****
          "default_transaction_isolation",
          "search_path",
          "statement_timeout",
!
          NULL
      };

--- 271,277 ----
          "default_transaction_isolation",
          "search_path",
          "statement_timeout",
!         "log_min_error_statement",
          NULL
      };

Index: src/include/utils/elog.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/utils/elog.h,v
retrieving revision 1.38
diff -c -c -r1.38 elog.h
*** src/include/utils/elog.h    20 Jun 2002 20:29:52 -0000    1.38
--- src/include/utils/elog.h    2 Sep 2002 05:36:06 -0000
***************
*** 47,68 ****
  extern bool Log_timestamp;
  extern bool Log_pid;

- extern char       *server_min_messages_str;
- extern char       *client_min_messages_str;
- extern const char server_min_messages_str_default[];
- extern const char client_min_messages_str_default[];
-
  extern void
  elog(int lev, const char *fmt,...)
  /* This extension allows gcc to check the format string for consistency with
     the supplied arguments. */
  __attribute__((format(printf, 2, 3)));

! extern int    DebugFileOpen(void);
!
! extern const char *assign_server_min_messages(const char *newval,
!                                               bool doit, bool interactive);
! extern const char *assign_client_min_messages(const char *newval,
!                                               bool doit, bool interactive);

  #endif   /* ELOG_H */
--- 47,58 ----
  extern bool Log_timestamp;
  extern bool Log_pid;

  extern void
  elog(int lev, const char *fmt,...)
  /* This extension allows gcc to check the format string for consistency with
     the supplied arguments. */
  __attribute__((format(printf, 2, 3)));

! extern int  DebugFileOpen(void);

  #endif   /* ELOG_H */
Index: src/include/utils/guc.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/utils/guc.h,v
retrieving revision 1.21
diff -c -c -r1.21 guc.h
*** src/include/utils/guc.h    1 Sep 2002 23:26:06 -0000    1.21
--- src/include/utils/guc.h    2 Sep 2002 05:36:07 -0000
***************
*** 100,105 ****
--- 100,112 ----
  extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
  extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);

+ extern const char *assign_min_error_statement(const char *newval, bool doit,
+             bool interactive);
+
+ extern const char *assign_server_min_messages(const char *newval,
+                                               bool doit, bool interactive);
+ extern const char *assign_client_min_messages(const char *newval,
+                                               bool doit, bool interactive);
  extern bool Log_statement;
  extern bool Log_duration;
  extern bool Debug_print_plan;
***************
*** 117,121 ****
--- 124,143 ----

  extern bool SQL_inheritance;
  extern bool Australian_timezones;
+
+ extern char *debug_query_string;
+
+ extern int    log_min_error_statement;
+ extern char *log_min_error_statement_str;
+ extern const char log_min_error_statement_str_default[];
+
+ extern int    server_min_messages;
+ extern char    *server_min_messages_str;
+ extern const char server_min_messages_str_default[];
+
+ extern int client_min_messages;
+ extern char    *client_min_messages_str;
+
+ extern const char client_min_messages_str_default[];

  #endif   /* GUC_H */

pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: AutoCommit GUC breaks CLI tools...
Next
From: Joe Conway
Date:
Subject: Re: Think I see a btree vacuuming bug