From 219e29784dead71ed2c652057e131fe31ea7c354 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 30 Jun 2003 16:47:02 +0000
Subject: [PATCH] Add GUC option log_error_verbosity to control which fields of
 error reports get put into the postmaster log.  Options are TERSE, DEFAULT,
 VERBOSE, with the same behavior as implemented on the client side in libpq.

---
 doc/src/sgml/runtime.sgml                     | 65 +++++++++--------
 src/backend/utils/error/elog.c                | 70 +++++++++++++------
 src/backend/utils/misc/guc.c                  | 47 ++++++++++---
 src/backend/utils/misc/postgresql.conf.sample |  9 ++-
 src/bin/psql/tab-complete.c                   |  3 +-
 src/include/utils/elog.h                      | 11 ++-
 6 files changed, 141 insertions(+), 64 deletions(-)

diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 2cc2400a5c5..3f6a2b350db 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.188 2003/06/27 18:20:50 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.189 2003/06/30 16:47:01 tgl Exp $
 -->
 
 <Chapter Id="runtime">
@@ -1513,7 +1513,7 @@ SET ENABLE_SEQSCAN TO OFF;
      <title>When To Log</title>
 
        <para>
-        Here is a list of the various message types:
+        Here is a list of the various message severity levels:
         <variablelist>
          <varlistentry>
           <term><literal>DEBUG[1-5]</literal></term>
@@ -1596,12 +1596,29 @@ SET ENABLE_SEQSCAN TO OFF;
 
      <variablelist>
 
+     <varlistentry>
+      <term><varname>CLIENT_MIN_MESSAGES</varname> (<type>string</type>)</term>
+      <listitem>
+       <para>
+        Controls which message levels are sent to the client.
+        Valid values are <literal>DEBUG5</>,
+        <literal>DEBUG4</>, <literal>DEBUG3</>, <literal>DEBUG2</>,
+        <literal>DEBUG1</>, <literal>LOG</>, <literal>NOTICE</>,
+        <literal>WARNING</>, and <literal>ERROR</>.  Each level
+        includes all the levels that follow it.  The later the level,
+        the fewer messages are sent.  The default is
+        <literal>NOTICE</>.  Note that <literal>LOG</> has a different
+        rank here than in <literal>LOG_MIN_MESSAGES</>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><varname>LOG_MIN_MESSAGES</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-        This controls which message levels are written to the server
-        log.  Valid values are <literal>DEBUG5</>, <literal>DEBUG4</>,
+        Controls which message levels are written to the server log.
+	Valid values are <literal>DEBUG5</>, <literal>DEBUG4</>,
         <literal>DEBUG3</>, <literal>DEBUG2</>, <literal>DEBUG1</>,
         <literal>INFO</>, <literal>NOTICE</>, <literal>WARNING</>,
         <literal>ERROR</>, <literal>LOG</>, <literal>FATAL</>, and
@@ -1609,30 +1626,22 @@ SET ENABLE_SEQSCAN TO OFF;
         follow it.  The later the level, the fewer messages are sent
         to the log.  The default is <literal>NOTICE</>.  Note that
         <literal>LOG</> has a different rank here than in
-        <literal>CLIENT_MIN_MESSAGES</>.  Also see that section for an
-        explanation of the various values.
+        <literal>CLIENT_MIN_MESSAGES</>.
        </para>
-
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term><varname>CLIENT_MIN_MESSAGES</varname> (<type>string</type>)</term>
+      <term><varname>LOG_ERROR_VERBOSITY</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-        This controls which message levels are send to the client.
-        client.  Valid values are <literal>DEBUG5</>,
-        <literal>DEBUG4</>, <literal>DEBUG3</>, <literal>DEBUG2</>,
-        <literal>DEBUG1</>, <literal>LOG</>, <literal>NOTICE</>,
-        <literal>WARNING</>, and <literal>ERROR</>.  Each level
-        includes all the levels that follow it.  The later the level,
-        the fewer messages are sent.  The default is
-        <literal>NOTICE</>.  Note that <literal>LOG</> has a different
-        rank here than in <literal>LOG_MIN_MESSAGES</>.
+        Controls the amount of detail written in the server log for each
+	message that is logged.  Valid values are <literal>TERSE</>,
+	<literal>DEFAULT</>, and <literal>VERBOSE</>, each adding more
+	fields to displayed messages.
        </para>
       </listitem>
      </varlistentry>
-     
 
      <varlistentry>
       <term><varname>LOG_MIN_ERROR_STATEMENT</varname> (<type>string</type>)</term>
@@ -1643,7 +1652,7 @@ SET ENABLE_SEQSCAN TO OFF;
         statements that cause an error of the specified level, or a
         higher level, are logged.  The default is
         <literal>PANIC</literal> (effectively turning this feature
-        off). Valid values are <literal>DEBUG5</literal>,
+        off for normal use). Valid values are <literal>DEBUG5</literal>,
         <literal>DEBUG4</literal>, <literal>DEBUG3</literal>,
         <literal>DEBUG2</literal>, <literal>DEBUG1</literal>,
         <literal>INFO</literal>, <literal>NOTICE</literal>,
@@ -1654,12 +1663,6 @@ SET ENABLE_SEQSCAN TO OFF;
         logged. Enabling this option can be helpful in tracking down
         the source of any errors that appear in the server log.
        </para>
-
-       <para>
-        It is recommended you enable <varname>LOG_PID</varname> as well
-        so you can more easily match the error statement with the error
-        message.
-       </para>
       </listitem>
      </varlistentry>
      
@@ -1668,12 +1671,12 @@ SET ENABLE_SEQSCAN TO OFF;
        <listitem>
         <para>
          Sets a minimum statement execution time (in milliseconds)
-         above which a statement will be logged.  All SQL statements
+         above which a statement will be logged.  All SQL statements
          that run longer than the time specified will be logged together
-         with the duration, in seconds.  The default is <literal>0</literal>
-         (turning this feature off).  For example, if you set it
+         with their actual duration.  Setting this to zero (the default)
+	 disables time-based logging.  For example, if you set it
          to <literal>250</literal> then all SQL statements that run longer
-         than 250ms will be logged along with the duration.  Enabling this
+         than 250ms will be logged.  Enabling this
          option can be useful in tracking down unoptimized queries in
          your applications.
         </para>
@@ -1688,8 +1691,8 @@ SET ENABLE_SEQSCAN TO OFF;
         will automatically run in background and any controlling terminals
         are disassociated.  Thus, no messages are written to standard
         output or standard error (same effect as <command>postmaster</>'s <option>-S</option>
-        option). Unless some logging system such as
-        <application>syslog</> is enabled, using this option is
+        option). Unless
+        <application>syslog</> logging is enabled, using this option is
         discouraged since it makes it impossible to see error messages.
        </para>
       </listitem>
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 9d371a5a26d..0660aaab9a9 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.111 2003/05/28 18:19:09 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.112 2003/06/30 16:47:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,6 +68,7 @@
 ErrorContextCallback *error_context_stack = NULL;
 
 /* GUC parameters */
+PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
 bool		Log_timestamp;		/* show timestamps in stderr output */
 bool		Log_pid;			/* show PIDs in stderr output */
 
@@ -918,23 +919,52 @@ send_message_to_server_log(ErrorData *edata)
 
 	appendStringInfo(&buf, "%s:  ", error_severity(edata->elevel));
 
+	if (Log_error_verbosity >= PGERROR_VERBOSE)
+	{
+		/* unpack MAKE_SQLSTATE code */
+		char	tbuf[12];
+		int		ssval;
+		int		i;
+
+		ssval = edata->sqlerrcode;
+		for (i = 0; i < 5; i++)
+		{
+			tbuf[i] = PGUNSIXBIT(ssval);
+			ssval >>= 6;
+		}
+		tbuf[i] = '\0';
+		appendStringInfo(&buf, "%s: ", tbuf);
+	}
+
 	if (edata->message)
-		appendStringInfo(&buf, "%s\n", edata->message);
+		appendStringInfoString(&buf, edata->message);
 	else
-		appendStringInfoString(&buf, "missing error text\n");
+		appendStringInfoString(&buf, gettext("missing error text"));
 
-	/* XXX showing of additional info should perhaps be optional */
-	/* XXX ought to localize the label strings, probably */
+	if (edata->cursorpos > 0)
+		appendStringInfo(&buf, gettext(" at character %d"), edata->cursorpos);
 
-	if (edata->detail)
-		appendStringInfo(&buf, "DETAIL:  %s\n", edata->detail);
-	if (edata->hint)
-		appendStringInfo(&buf, "HINT:  %s\n", edata->hint);
-	if (edata->context)
-		appendStringInfo(&buf, "CONTEXT:  %s\n", edata->context);
-	if (edata->funcname && edata->filename)
-		appendStringInfo(&buf, "IN:  %s (%s:%d)\n",
-						 edata->funcname, edata->filename, edata->lineno);
+	appendStringInfoChar(&buf, '\n');
+
+	if (Log_error_verbosity >= PGERROR_DEFAULT)
+	{
+		if (edata->detail)
+			appendStringInfo(&buf, gettext("DETAIL:  %s\n"), edata->detail);
+		if (edata->hint)
+			appendStringInfo(&buf, gettext("HINT:  %s\n"), edata->hint);
+		if (edata->context)
+			appendStringInfo(&buf, gettext("CONTEXT:  %s\n"), edata->context);
+		if (Log_error_verbosity >= PGERROR_VERBOSE)
+		{
+			if (edata->funcname && edata->filename)
+				appendStringInfo(&buf, gettext("LOCATION:  %s, %s:%d\n"),
+								 edata->funcname, edata->filename,
+								 edata->lineno);
+			else if (edata->filename)
+				appendStringInfo(&buf, gettext("LOCATION:  %s:%d\n"),
+								 edata->filename, edata->lineno);
+		}
+	}
 
 	/*
 	 * If the user wants the query that generated this error logged, do so.
@@ -942,7 +972,8 @@ send_message_to_server_log(ErrorData *edata)
 	 * for queries triggered by extended query protocol; how to improve?
 	 */
 	if (edata->elevel >= log_min_error_statement && debug_query_string != NULL)
-		appendStringInfo(&buf, "STATEMENT:  %s\n", debug_query_string);
+		appendStringInfo(&buf, gettext("STATEMENT:  %s\n"),
+						 debug_query_string);
 
 
 #ifdef HAVE_SYSLOG
@@ -992,11 +1023,10 @@ send_message_to_server_log(ErrorData *edata)
 		 * Timestamp and PID are only used for stderr output --- we assume
 		 * the syslog daemon will supply them for us in the other case.
 		 */
-		if (Log_timestamp)
-			fprintf(stderr, "%s", print_timestamp());
-		if (Log_pid)
-			fprintf(stderr, "%s", print_pid());
-		fprintf(stderr, "%s", buf.data);
+		fprintf(stderr, "%s%s%s",
+				Log_timestamp ? print_timestamp() : "",
+				Log_pid ? print_pid() : "",
+				buf.data);
 	}
 
 	pfree(buf.data);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index dfdc4f82e7f..6e0da5bbaab 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.132 2003/06/27 19:08:38 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.133 2003/06/30 16:47:01 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -94,6 +94,8 @@ static const char *assign_min_error_statement(const char *newval, bool doit,
 						   bool interactive);
 static const char *assign_msglvl(int *var, const char *newval,
 			  bool doit, bool interactive);
+static const char *assign_log_error_verbosity(const char *newval, bool doit,
+											  bool interactive);
 static bool assign_phony_autocommit(bool newval, bool doit, bool interactive);
 
 
@@ -134,9 +136,10 @@ int			client_min_messages = NOTICE;
  * cases provide the value for SHOW to display.  The real state is elsewhere
  * and is kept in sync by assign_hooks.
  */
-static char *log_min_error_statement_str;
-static char *log_min_messages_str;
 static char *client_min_messages_str;
+static char *log_min_messages_str;
+static char *log_error_verbosity_str;
+static char *log_min_error_statement_str;
 static bool phony_autocommit;
 static bool session_auth_is_superuser;
 static double phony_random_seed;
@@ -820,6 +823,16 @@ static struct config_string
 		"notice", assign_client_min_messages, NULL
 	},
 
+	{
+		{"log_min_messages", PGC_SUSET}, &log_min_messages_str,
+		"notice", assign_log_min_messages, NULL
+	},
+
+	{
+		{"log_error_verbosity", PGC_SUSET}, &log_error_verbosity_str,
+		"default", assign_log_error_verbosity, NULL
+	},
+
 	{
 		{"log_min_error_statement", PGC_SUSET}, &log_min_error_statement_str,
 		"panic", assign_min_error_statement, NULL
@@ -909,11 +922,6 @@ static struct config_string
 		PG_VERSION, NULL, NULL
 	},
 
-	{
-		{"log_min_messages", PGC_SUSET}, &log_min_messages_str,
-		"notice", assign_log_min_messages, NULL
-	},
-
 	/* Not for general use --- used by SET SESSION AUTHORIZATION */
 	{
 		{"session_authorization", PGC_USERSET, GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL},
@@ -3468,6 +3476,29 @@ assign_msglvl(int *var, const char *newval, bool doit, bool interactive)
 	return newval;				/* OK */
 }
 
+static const char *
+assign_log_error_verbosity(const char *newval, bool doit, bool interactive)
+{
+	if (strcasecmp(newval, "terse") == 0)
+	{
+		if (doit)
+			Log_error_verbosity = PGERROR_TERSE;
+	}
+	else if (strcasecmp(newval, "default") == 0)
+	{
+		if (doit)
+			Log_error_verbosity = PGERROR_DEFAULT;
+	}
+	else if (strcasecmp(newval, "verbose") == 0)
+	{
+		if (doit)
+			Log_error_verbosity = PGERROR_VERBOSE;
+	}
+	else
+		return NULL;			/* fail */
+	return newval;				/* OK */
+}
+
 static bool
 assign_phony_autocommit(bool newval, bool doit, bool interactive)
 {
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 594c230a769..57c6e55cb22 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -119,13 +119,16 @@
 #
 #	Message display
 #
+#client_min_messages = notice	# Values, in order of decreasing detail:
+				#   debug5, debug4, debug3, debug2, debug1,
+				#   log, info, notice, warning, error
 #log_min_messages = notice	# Values, in order of decreasing detail:
 				#   debug5, debug4, debug3, debug2, debug1,
 				#   info, notice, warning, error, log, fatal,
 				#   panic
-#client_min_messages = notice	# Values, in order of decreasing detail:
-				#   debug5, debug4, debug3, debug2, debug1,
-				#   log, info, notice, warning, error
+
+#log_error_verbosity = default	# terse, default, or verbose messages
+
 #silent_mode = false
 
 #log_connections = false
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index f0de8f6c0e6..8f70c25e761 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
  *
  * Copyright 2000-2002 by PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.80 2003/06/12 01:38:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.81 2003/06/30 16:47:01 tgl Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -543,6 +543,7 @@ psql_completion(char *text, int start, int end)
 		"lc_numeric",
 		"lc_time",
 		"log_duration",
+		"log_error_verbosity",
 		"log_executor_stats",
 		"log_min_duration_statement",
 		"log_min_error_statement",
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index f10a15db65b..b92bc839337 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: elog.h,v 1.44 2003/05/27 17:49:46 momjian Exp $
+ * $Id: elog.h,v 1.45 2003/06/30 16:47:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -268,6 +268,15 @@ extern DLLIMPORT ErrorContextCallback *error_context_stack;
 
 
 /* GUC-configurable parameters */
+
+typedef enum
+{
+	PGERROR_TERSE,				/* single-line error messages */
+	PGERROR_DEFAULT,			/* recommended style */
+	PGERROR_VERBOSE				/* all the facts, ma'am */
+} PGErrorVerbosity;
+
+extern PGErrorVerbosity Log_error_verbosity;
 extern bool Log_timestamp;
 extern bool Log_pid;
 #ifdef HAVE_SYSLOG
-- 
GitLab