Move any code specific to log_destination=csvlog to its own file
authorMichael Paquier <michael@paquier.xyz>
Wed, 12 Jan 2022 06:03:48 +0000 (15:03 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 12 Jan 2022 06:03:48 +0000 (15:03 +0900)
The recent refactoring done in ac7c807 makes this move possible and
simple, as this just moves some code around.  This reduces the size of
elog.c by 7%.

Author: Michael Paquier, Sehrope Sarkuni
Reviewed-by: Nathan Bossart
Discussion: https://postgr.es/m/CAH7T-aqswBM6JWe4pDehi1uOiufqe06DJWaU5=X7dDLyqUExHg@mail.gmail.com

simply moves the routines related to csvlog into their own file

src/backend/utils/error/Makefile
src/backend/utils/error/csvlog.c [new file with mode: 0644]
src/backend/utils/error/elog.c

index 612da215d042072bd452a521ee2a90869dfbd40f..ef770dd2f2a09e9c819ae3b14bc2a37190853789 100644 (file)
@@ -14,6 +14,7 @@ include $(top_builddir)/src/Makefile.global
 
 OBJS = \
    assert.o \
+   csvlog.o \
    elog.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/utils/error/csvlog.c b/src/backend/utils/error/csvlog.c
new file mode 100644 (file)
index 0000000..89f78b4
--- /dev/null
@@ -0,0 +1,264 @@
+/*-------------------------------------------------------------------------
+ *
+ * csvlog.c
+ *   CSV logging
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of Californi
+ *
+ *
+ * IDENTIFICATION
+ *   src/backend/utils/error/csvlog.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "access/xact.h"
+#include "libpq/libpq.h"
+#include "lib/stringinfo.h"
+#include "miscadmin.h"
+#include "postmaster/bgworker.h"
+#include "postmaster/syslogger.h"
+#include "storage/lock.h"
+#include "storage/proc.h"
+#include "tcop/tcopprot.h"
+#include "utils/backend_status.h"
+#include "utils/elog.h"
+#include "utils/guc.h"
+#include "utils/ps_status.h"
+
+
+/*
+ * append a CSV'd version of a string to a StringInfo
+ * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"'
+ * If it's NULL, append nothing.
+ */
+static inline void
+appendCSVLiteral(StringInfo buf, const char *data)
+{
+   const char *p = data;
+   char        c;
+
+   /* avoid confusing an empty string with NULL */
+   if (p == NULL)
+       return;
+
+   appendStringInfoCharMacro(buf, '"');
+   while ((c = *p++) != '\0')
+   {
+       if (c == '"')
+           appendStringInfoCharMacro(buf, '"');
+       appendStringInfoCharMacro(buf, c);
+   }
+   appendStringInfoCharMacro(buf, '"');
+}
+
+/*
+ * write_csvlog -- Generate and write CSV log entry
+ *
+ * Constructs the error message, depending on the Errordata it gets, in a CSV
+ * format which is described in doc/src/sgml/config.sgml.
+ */
+void
+write_csvlog(ErrorData *edata)
+{
+   StringInfoData buf;
+   bool        print_stmt = false;
+
+   /* static counter for line numbers */
+   static long log_line_number = 0;
+
+   /* has counter been reset in current process? */
+   static int  log_my_pid = 0;
+
+   /*
+    * This is one of the few places where we'd rather not inherit a static
+    * variable's value from the postmaster.  But since we will, reset it when
+    * MyProcPid changes.
+    */
+   if (log_my_pid != MyProcPid)
+   {
+       log_line_number = 0;
+       log_my_pid = MyProcPid;
+       reset_formatted_start_time();
+   }
+   log_line_number++;
+
+   initStringInfo(&buf);
+
+   /* timestamp with milliseconds */
+   appendStringInfoString(&buf, get_formatted_log_time());
+   appendStringInfoChar(&buf, ',');
+
+   /* username */
+   if (MyProcPort)
+       appendCSVLiteral(&buf, MyProcPort->user_name);
+   appendStringInfoChar(&buf, ',');
+
+   /* database name */
+   if (MyProcPort)
+       appendCSVLiteral(&buf, MyProcPort->database_name);
+   appendStringInfoChar(&buf, ',');
+
+   /* Process id  */
+   if (MyProcPid != 0)
+       appendStringInfo(&buf, "%d", MyProcPid);
+   appendStringInfoChar(&buf, ',');
+
+   /* Remote host and port */
+   if (MyProcPort && MyProcPort->remote_host)
+   {
+       appendStringInfoChar(&buf, '"');
+       appendStringInfoString(&buf, MyProcPort->remote_host);
+       if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
+       {
+           appendStringInfoChar(&buf, ':');
+           appendStringInfoString(&buf, MyProcPort->remote_port);
+       }
+       appendStringInfoChar(&buf, '"');
+   }
+   appendStringInfoChar(&buf, ',');
+
+   /* session id */
+   appendStringInfo(&buf, "%lx.%x", (long) MyStartTime, MyProcPid);
+   appendStringInfoChar(&buf, ',');
+
+   /* Line number */
+   appendStringInfo(&buf, "%ld", log_line_number);
+   appendStringInfoChar(&buf, ',');
+
+   /* PS display */
+   if (MyProcPort)
+   {
+       StringInfoData msgbuf;
+       const char *psdisp;
+       int         displen;
+
+       initStringInfo(&msgbuf);
+
+       psdisp = get_ps_display(&displen);
+       appendBinaryStringInfo(&msgbuf, psdisp, displen);
+       appendCSVLiteral(&buf, msgbuf.data);
+
+       pfree(msgbuf.data);
+   }
+   appendStringInfoChar(&buf, ',');
+
+   /* session start timestamp */
+   appendStringInfoString(&buf, get_formatted_start_time());
+   appendStringInfoChar(&buf, ',');
+
+   /* Virtual transaction id */
+   /* keep VXID format in sync with lockfuncs.c */
+   if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
+       appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);
+   appendStringInfoChar(&buf, ',');
+
+   /* Transaction id */
+   appendStringInfo(&buf, "%u", GetTopTransactionIdIfAny());
+   appendStringInfoChar(&buf, ',');
+
+   /* Error severity */
+   appendStringInfoString(&buf, _(error_severity(edata->elevel)));
+   appendStringInfoChar(&buf, ',');
+
+   /* SQL state code */
+   appendStringInfoString(&buf, unpack_sql_state(edata->sqlerrcode));
+   appendStringInfoChar(&buf, ',');
+
+   /* errmessage */
+   appendCSVLiteral(&buf, edata->message);
+   appendStringInfoChar(&buf, ',');
+
+   /* errdetail or errdetail_log */
+   if (edata->detail_log)
+       appendCSVLiteral(&buf, edata->detail_log);
+   else
+       appendCSVLiteral(&buf, edata->detail);
+   appendStringInfoChar(&buf, ',');
+
+   /* errhint */
+   appendCSVLiteral(&buf, edata->hint);
+   appendStringInfoChar(&buf, ',');
+
+   /* internal query */
+   appendCSVLiteral(&buf, edata->internalquery);
+   appendStringInfoChar(&buf, ',');
+
+   /* if printed internal query, print internal pos too */
+   if (edata->internalpos > 0 && edata->internalquery != NULL)
+       appendStringInfo(&buf, "%d", edata->internalpos);
+   appendStringInfoChar(&buf, ',');
+
+   /* errcontext */
+   if (!edata->hide_ctx)
+       appendCSVLiteral(&buf, edata->context);
+   appendStringInfoChar(&buf, ',');
+
+   /* user query --- only reported if not disabled by the caller */
+   print_stmt = check_log_of_query(edata);
+   if (print_stmt)
+       appendCSVLiteral(&buf, debug_query_string);
+   appendStringInfoChar(&buf, ',');
+   if (print_stmt && edata->cursorpos > 0)
+       appendStringInfo(&buf, "%d", edata->cursorpos);
+   appendStringInfoChar(&buf, ',');
+
+   /* file error location */
+   if (Log_error_verbosity >= PGERROR_VERBOSE)
+   {
+       StringInfoData msgbuf;
+
+       initStringInfo(&msgbuf);
+
+       if (edata->funcname && edata->filename)
+           appendStringInfo(&msgbuf, "%s, %s:%d",
+                            edata->funcname, edata->filename,
+                            edata->lineno);
+       else if (edata->filename)
+           appendStringInfo(&msgbuf, "%s:%d",
+                            edata->filename, edata->lineno);
+       appendCSVLiteral(&buf, msgbuf.data);
+       pfree(msgbuf.data);
+   }
+   appendStringInfoChar(&buf, ',');
+
+   /* application name */
+   if (application_name)
+       appendCSVLiteral(&buf, application_name);
+
+   appendStringInfoChar(&buf, ',');
+
+   /* backend type */
+   appendCSVLiteral(&buf, get_backend_type_for_log());
+   appendStringInfoChar(&buf, ',');
+
+   /* leader PID */
+   if (MyProc)
+   {
+       PGPROC     *leader = MyProc->lockGroupLeader;
+
+       /*
+        * Show the leader only for active parallel workers.  This leaves out
+        * the leader of a parallel group.
+        */
+       if (leader && leader->pid != MyProcPid)
+           appendStringInfo(&buf, "%d", leader->pid);
+   }
+   appendStringInfoChar(&buf, ',');
+
+   /* query id */
+   appendStringInfo(&buf, "%lld", (long long) pgstat_get_my_query_id());
+
+   appendStringInfoChar(&buf, '\n');
+
+   /* If in the syslogger process, try to write messages direct to file */
+   if (MyBackendType == B_LOGGER)
+       write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
+   else
+       write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
+
+   pfree(buf.data);
+}
index 0e29cb4ff3e24bb93a70437a1c19711ef381581d..4db41ba564c8aa688a1fad72369ed24895169a96 100644 (file)
@@ -2792,237 +2792,6 @@ log_line_prefix(StringInfo buf, ErrorData *edata)
    }
 }
 
-/*
- * append a CSV'd version of a string to a StringInfo
- * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"'
- * If it's NULL, append nothing.
- */
-static inline void
-appendCSVLiteral(StringInfo buf, const char *data)
-{
-   const char *p = data;
-   char        c;
-
-   /* avoid confusing an empty string with NULL */
-   if (p == NULL)
-       return;
-
-   appendStringInfoCharMacro(buf, '"');
-   while ((c = *p++) != '\0')
-   {
-       if (c == '"')
-           appendStringInfoCharMacro(buf, '"');
-       appendStringInfoCharMacro(buf, c);
-   }
-   appendStringInfoCharMacro(buf, '"');
-}
-
-/*
- * Constructs the error message, depending on the Errordata it gets, in a CSV
- * format which is described in doc/src/sgml/config.sgml.
- */
-void
-write_csvlog(ErrorData *edata)
-{
-   StringInfoData buf;
-   bool        print_stmt = false;
-
-   /* static counter for line numbers */
-   static long log_line_number = 0;
-
-   /* has counter been reset in current process? */
-   static int  log_my_pid = 0;
-
-   /*
-    * This is one of the few places where we'd rather not inherit a static
-    * variable's value from the postmaster.  But since we will, reset it when
-    * MyProcPid changes.
-    */
-   if (log_my_pid != MyProcPid)
-   {
-       log_line_number = 0;
-       log_my_pid = MyProcPid;
-       reset_formatted_start_time();
-   }
-   log_line_number++;
-
-   initStringInfo(&buf);
-
-   /* timestamp with milliseconds */
-   appendStringInfoString(&buf, get_formatted_log_time());
-   appendStringInfoChar(&buf, ',');
-
-   /* username */
-   if (MyProcPort)
-       appendCSVLiteral(&buf, MyProcPort->user_name);
-   appendStringInfoChar(&buf, ',');
-
-   /* database name */
-   if (MyProcPort)
-       appendCSVLiteral(&buf, MyProcPort->database_name);
-   appendStringInfoChar(&buf, ',');
-
-   /* Process id  */
-   if (MyProcPid != 0)
-       appendStringInfo(&buf, "%d", MyProcPid);
-   appendStringInfoChar(&buf, ',');
-
-   /* Remote host and port */
-   if (MyProcPort && MyProcPort->remote_host)
-   {
-       appendStringInfoChar(&buf, '"');
-       appendStringInfoString(&buf, MyProcPort->remote_host);
-       if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
-       {
-           appendStringInfoChar(&buf, ':');
-           appendStringInfoString(&buf, MyProcPort->remote_port);
-       }
-       appendStringInfoChar(&buf, '"');
-   }
-   appendStringInfoChar(&buf, ',');
-
-   /* session id */
-   appendStringInfo(&buf, "%lx.%x", (long) MyStartTime, MyProcPid);
-   appendStringInfoChar(&buf, ',');
-
-   /* Line number */
-   appendStringInfo(&buf, "%ld", log_line_number);
-   appendStringInfoChar(&buf, ',');
-
-   /* PS display */
-   if (MyProcPort)
-   {
-       StringInfoData msgbuf;
-       const char *psdisp;
-       int         displen;
-
-       initStringInfo(&msgbuf);
-
-       psdisp = get_ps_display(&displen);
-       appendBinaryStringInfo(&msgbuf, psdisp, displen);
-       appendCSVLiteral(&buf, msgbuf.data);
-
-       pfree(msgbuf.data);
-   }
-   appendStringInfoChar(&buf, ',');
-
-   /* session start timestamp */
-   appendStringInfoString(&buf, get_formatted_start_time());
-   appendStringInfoChar(&buf, ',');
-
-   /* Virtual transaction id */
-   /* keep VXID format in sync with lockfuncs.c */
-   if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
-       appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);
-   appendStringInfoChar(&buf, ',');
-
-   /* Transaction id */
-   appendStringInfo(&buf, "%u", GetTopTransactionIdIfAny());
-   appendStringInfoChar(&buf, ',');
-
-   /* Error severity */
-   appendStringInfoString(&buf, _(error_severity(edata->elevel)));
-   appendStringInfoChar(&buf, ',');
-
-   /* SQL state code */
-   appendStringInfoString(&buf, unpack_sql_state(edata->sqlerrcode));
-   appendStringInfoChar(&buf, ',');
-
-   /* errmessage */
-   appendCSVLiteral(&buf, edata->message);
-   appendStringInfoChar(&buf, ',');
-
-   /* errdetail or errdetail_log */
-   if (edata->detail_log)
-       appendCSVLiteral(&buf, edata->detail_log);
-   else
-       appendCSVLiteral(&buf, edata->detail);
-   appendStringInfoChar(&buf, ',');
-
-   /* errhint */
-   appendCSVLiteral(&buf, edata->hint);
-   appendStringInfoChar(&buf, ',');
-
-   /* internal query */
-   appendCSVLiteral(&buf, edata->internalquery);
-   appendStringInfoChar(&buf, ',');
-
-   /* if printed internal query, print internal pos too */
-   if (edata->internalpos > 0 && edata->internalquery != NULL)
-       appendStringInfo(&buf, "%d", edata->internalpos);
-   appendStringInfoChar(&buf, ',');
-
-   /* errcontext */
-   if (!edata->hide_ctx)
-       appendCSVLiteral(&buf, edata->context);
-   appendStringInfoChar(&buf, ',');
-
-   /* user query --- only reported if not disabled by the caller */
-   print_stmt = check_log_of_query(edata);
-   if (print_stmt)
-       appendCSVLiteral(&buf, debug_query_string);
-   appendStringInfoChar(&buf, ',');
-   if (print_stmt && edata->cursorpos > 0)
-       appendStringInfo(&buf, "%d", edata->cursorpos);
-   appendStringInfoChar(&buf, ',');
-
-   /* file error location */
-   if (Log_error_verbosity >= PGERROR_VERBOSE)
-   {
-       StringInfoData msgbuf;
-
-       initStringInfo(&msgbuf);
-
-       if (edata->funcname && edata->filename)
-           appendStringInfo(&msgbuf, "%s, %s:%d",
-                            edata->funcname, edata->filename,
-                            edata->lineno);
-       else if (edata->filename)
-           appendStringInfo(&msgbuf, "%s:%d",
-                            edata->filename, edata->lineno);
-       appendCSVLiteral(&buf, msgbuf.data);
-       pfree(msgbuf.data);
-   }
-   appendStringInfoChar(&buf, ',');
-
-   /* application name */
-   if (application_name)
-       appendCSVLiteral(&buf, application_name);
-
-   appendStringInfoChar(&buf, ',');
-
-   /* backend type */
-   appendCSVLiteral(&buf, get_backend_type_for_log());
-   appendStringInfoChar(&buf, ',');
-
-   /* leader PID */
-   if (MyProc)
-   {
-       PGPROC     *leader = MyProc->lockGroupLeader;
-
-       /*
-        * Show the leader only for active parallel workers.  This leaves out
-        * the leader of a parallel group.
-        */
-       if (leader && leader->pid != MyProcPid)
-           appendStringInfo(&buf, "%d", leader->pid);
-   }
-   appendStringInfoChar(&buf, ',');
-
-   /* query id */
-   appendStringInfo(&buf, "%lld", (long long) pgstat_get_my_query_id());
-
-   appendStringInfoChar(&buf, '\n');
-
-   /* If in the syslogger process, try to write messages direct to file */
-   if (MyBackendType == B_LOGGER)
-       write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
-   else
-       write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
-
-   pfree(buf.data);
-}
-
 /*
  * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a
  * static buffer.