LCOV - code coverage report
Current view: top level - src/backend/utils/error - csvlog.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 124 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 2 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 70 0

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * csvlog.c
       4                 :             :  *        CSV logging
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/utils/error/csvlog.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : 
      16                 :             : #include "postgres.h"
      17                 :             : 
      18                 :             : #include "access/xact.h"
      19                 :             : #include "lib/stringinfo.h"
      20                 :             : #include "libpq/libpq-be.h"
      21                 :             : #include "miscadmin.h"
      22                 :             : #include "postmaster/syslogger.h"
      23                 :             : #include "storage/lock.h"
      24                 :             : #include "storage/proc.h"
      25                 :             : #include "tcop/tcopprot.h"
      26                 :             : #include "utils/backend_status.h"
      27                 :             : #include "utils/guc.h"
      28                 :             : #include "utils/ps_status.h"
      29                 :             : 
      30                 :             : 
      31                 :             : /*
      32                 :             :  * append a CSV'd version of a string to a StringInfo
      33                 :             :  * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"'
      34                 :             :  * If it's NULL, append nothing.
      35                 :             :  */
      36                 :             : static inline void
      37                 :           0 : appendCSVLiteral(StringInfo buf, const char *data)
      38                 :             : {
      39                 :           0 :         const char *p = data;
      40                 :           0 :         char            c;
      41                 :             : 
      42                 :             :         /* avoid confusing an empty string with NULL */
      43         [ #  # ]:           0 :         if (p == NULL)
      44                 :           0 :                 return;
      45                 :             : 
      46         [ #  # ]:           0 :         appendStringInfoCharMacro(buf, '"');
      47         [ #  # ]:           0 :         while ((c = *p++) != '\0')
      48                 :             :         {
      49         [ #  # ]:           0 :                 if (c == '"')
      50         [ #  # ]:           0 :                         appendStringInfoCharMacro(buf, '"');
      51         [ #  # ]:           0 :                 appendStringInfoCharMacro(buf, c);
      52                 :             :         }
      53         [ #  # ]:           0 :         appendStringInfoCharMacro(buf, '"');
      54         [ #  # ]:           0 : }
      55                 :             : 
      56                 :             : /*
      57                 :             :  * write_csvlog -- Generate and write CSV log entry
      58                 :             :  *
      59                 :             :  * Constructs the error message, depending on the Errordata it gets, in a CSV
      60                 :             :  * format which is described in doc/src/sgml/config.sgml.
      61                 :             :  */
      62                 :             : void
      63                 :           0 : write_csvlog(ErrorData *edata)
      64                 :             : {
      65                 :           0 :         StringInfoData buf;
      66                 :           0 :         bool            print_stmt = false;
      67                 :             : 
      68                 :             :         /* static counter for line numbers */
      69                 :             :         static long log_line_number = 0;
      70                 :             : 
      71                 :             :         /* has counter been reset in current process? */
      72                 :             :         static int      log_my_pid = 0;
      73                 :             : 
      74                 :             :         /*
      75                 :             :          * This is one of the few places where we'd rather not inherit a static
      76                 :             :          * variable's value from the postmaster.  But since we will, reset it when
      77                 :             :          * MyProcPid changes.
      78                 :             :          */
      79         [ #  # ]:           0 :         if (log_my_pid != MyProcPid)
      80                 :             :         {
      81                 :           0 :                 log_line_number = 0;
      82                 :           0 :                 log_my_pid = MyProcPid;
      83                 :           0 :                 reset_formatted_start_time();
      84                 :           0 :         }
      85                 :           0 :         log_line_number++;
      86                 :             : 
      87                 :           0 :         initStringInfo(&buf);
      88                 :             : 
      89                 :             :         /* timestamp with milliseconds */
      90                 :           0 :         appendStringInfoString(&buf, get_formatted_log_time());
      91                 :           0 :         appendStringInfoChar(&buf, ',');
      92                 :             : 
      93                 :             :         /* username */
      94         [ #  # ]:           0 :         if (MyProcPort)
      95                 :           0 :                 appendCSVLiteral(&buf, MyProcPort->user_name);
      96                 :           0 :         appendStringInfoChar(&buf, ',');
      97                 :             : 
      98                 :             :         /* database name */
      99         [ #  # ]:           0 :         if (MyProcPort)
     100                 :           0 :                 appendCSVLiteral(&buf, MyProcPort->database_name);
     101                 :           0 :         appendStringInfoChar(&buf, ',');
     102                 :             : 
     103                 :             :         /* Process id  */
     104         [ #  # ]:           0 :         if (MyProcPid != 0)
     105                 :           0 :                 appendStringInfo(&buf, "%d", MyProcPid);
     106                 :           0 :         appendStringInfoChar(&buf, ',');
     107                 :             : 
     108                 :             :         /* Remote host and port */
     109   [ #  #  #  # ]:           0 :         if (MyProcPort && MyProcPort->remote_host)
     110                 :             :         {
     111                 :           0 :                 appendStringInfoChar(&buf, '"');
     112                 :           0 :                 appendStringInfoString(&buf, MyProcPort->remote_host);
     113   [ #  #  #  # ]:           0 :                 if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
     114                 :             :                 {
     115                 :           0 :                         appendStringInfoChar(&buf, ':');
     116                 :           0 :                         appendStringInfoString(&buf, MyProcPort->remote_port);
     117                 :           0 :                 }
     118                 :           0 :                 appendStringInfoChar(&buf, '"');
     119                 :           0 :         }
     120                 :           0 :         appendStringInfoChar(&buf, ',');
     121                 :             : 
     122                 :             :         /* session id */
     123                 :           0 :         appendStringInfo(&buf, "%" PRIx64 ".%x", MyStartTime, MyProcPid);
     124                 :           0 :         appendStringInfoChar(&buf, ',');
     125                 :             : 
     126                 :             :         /* Line number */
     127                 :           0 :         appendStringInfo(&buf, "%ld", log_line_number);
     128                 :           0 :         appendStringInfoChar(&buf, ',');
     129                 :             : 
     130                 :             :         /* PS display */
     131         [ #  # ]:           0 :         if (MyProcPort)
     132                 :             :         {
     133                 :           0 :                 StringInfoData msgbuf;
     134                 :           0 :                 const char *psdisp;
     135                 :           0 :                 int                     displen;
     136                 :             : 
     137                 :           0 :                 initStringInfo(&msgbuf);
     138                 :             : 
     139                 :           0 :                 psdisp = get_ps_display(&displen);
     140                 :           0 :                 appendBinaryStringInfo(&msgbuf, psdisp, displen);
     141                 :           0 :                 appendCSVLiteral(&buf, msgbuf.data);
     142                 :             : 
     143                 :           0 :                 pfree(msgbuf.data);
     144                 :           0 :         }
     145                 :           0 :         appendStringInfoChar(&buf, ',');
     146                 :             : 
     147                 :             :         /* session start timestamp */
     148                 :           0 :         appendStringInfoString(&buf, get_formatted_start_time());
     149                 :           0 :         appendStringInfoChar(&buf, ',');
     150                 :             : 
     151                 :             :         /* Virtual transaction id */
     152                 :             :         /* keep VXID format in sync with lockfuncs.c */
     153   [ #  #  #  # ]:           0 :         if (MyProc != NULL && MyProc->vxid.procNumber != INVALID_PROC_NUMBER)
     154                 :           0 :                 appendStringInfo(&buf, "%d/%u", MyProc->vxid.procNumber, MyProc->vxid.lxid);
     155                 :           0 :         appendStringInfoChar(&buf, ',');
     156                 :             : 
     157                 :             :         /* Transaction id */
     158                 :           0 :         appendStringInfo(&buf, "%u", GetTopTransactionIdIfAny());
     159                 :           0 :         appendStringInfoChar(&buf, ',');
     160                 :             : 
     161                 :             :         /* Error severity */
     162                 :           0 :         appendStringInfoString(&buf, _(error_severity(edata->elevel)));
     163                 :           0 :         appendStringInfoChar(&buf, ',');
     164                 :             : 
     165                 :             :         /* SQL state code */
     166                 :           0 :         appendStringInfoString(&buf, unpack_sql_state(edata->sqlerrcode));
     167                 :           0 :         appendStringInfoChar(&buf, ',');
     168                 :             : 
     169                 :             :         /* errmessage */
     170                 :           0 :         appendCSVLiteral(&buf, edata->message);
     171                 :           0 :         appendStringInfoChar(&buf, ',');
     172                 :             : 
     173                 :             :         /* errdetail or errdetail_log */
     174         [ #  # ]:           0 :         if (edata->detail_log)
     175                 :           0 :                 appendCSVLiteral(&buf, edata->detail_log);
     176                 :             :         else
     177                 :           0 :                 appendCSVLiteral(&buf, edata->detail);
     178                 :           0 :         appendStringInfoChar(&buf, ',');
     179                 :             : 
     180                 :             :         /* errhint */
     181                 :           0 :         appendCSVLiteral(&buf, edata->hint);
     182                 :           0 :         appendStringInfoChar(&buf, ',');
     183                 :             : 
     184                 :             :         /* internal query */
     185                 :           0 :         appendCSVLiteral(&buf, edata->internalquery);
     186                 :           0 :         appendStringInfoChar(&buf, ',');
     187                 :             : 
     188                 :             :         /* if printed internal query, print internal pos too */
     189   [ #  #  #  # ]:           0 :         if (edata->internalpos > 0 && edata->internalquery != NULL)
     190                 :           0 :                 appendStringInfo(&buf, "%d", edata->internalpos);
     191                 :           0 :         appendStringInfoChar(&buf, ',');
     192                 :             : 
     193                 :             :         /* errcontext */
     194         [ #  # ]:           0 :         if (!edata->hide_ctx)
     195                 :           0 :                 appendCSVLiteral(&buf, edata->context);
     196                 :           0 :         appendStringInfoChar(&buf, ',');
     197                 :             : 
     198                 :             :         /* user query --- only reported if not disabled by the caller */
     199                 :           0 :         print_stmt = check_log_of_query(edata);
     200         [ #  # ]:           0 :         if (print_stmt)
     201                 :           0 :                 appendCSVLiteral(&buf, debug_query_string);
     202                 :           0 :         appendStringInfoChar(&buf, ',');
     203   [ #  #  #  # ]:           0 :         if (print_stmt && edata->cursorpos > 0)
     204                 :           0 :                 appendStringInfo(&buf, "%d", edata->cursorpos);
     205                 :           0 :         appendStringInfoChar(&buf, ',');
     206                 :             : 
     207                 :             :         /* file error location */
     208         [ #  # ]:           0 :         if (Log_error_verbosity >= PGERROR_VERBOSE)
     209                 :             :         {
     210                 :           0 :                 StringInfoData msgbuf;
     211                 :             : 
     212                 :           0 :                 initStringInfo(&msgbuf);
     213                 :             : 
     214   [ #  #  #  # ]:           0 :                 if (edata->funcname && edata->filename)
     215                 :           0 :                         appendStringInfo(&msgbuf, "%s, %s:%d",
     216                 :           0 :                                                          edata->funcname, edata->filename,
     217                 :           0 :                                                          edata->lineno);
     218         [ #  # ]:           0 :                 else if (edata->filename)
     219                 :           0 :                         appendStringInfo(&msgbuf, "%s:%d",
     220                 :           0 :                                                          edata->filename, edata->lineno);
     221                 :           0 :                 appendCSVLiteral(&buf, msgbuf.data);
     222                 :           0 :                 pfree(msgbuf.data);
     223                 :           0 :         }
     224                 :           0 :         appendStringInfoChar(&buf, ',');
     225                 :             : 
     226                 :             :         /* application name */
     227         [ #  # ]:           0 :         if (application_name)
     228                 :           0 :                 appendCSVLiteral(&buf, application_name);
     229                 :             : 
     230                 :           0 :         appendStringInfoChar(&buf, ',');
     231                 :             : 
     232                 :             :         /* backend type */
     233                 :           0 :         appendCSVLiteral(&buf, get_backend_type_for_log());
     234                 :           0 :         appendStringInfoChar(&buf, ',');
     235                 :             : 
     236                 :             :         /* leader PID */
     237         [ #  # ]:           0 :         if (MyProc)
     238                 :             :         {
     239                 :           0 :                 PGPROC     *leader = MyProc->lockGroupLeader;
     240                 :             : 
     241                 :             :                 /*
     242                 :             :                  * Show the leader only for active parallel workers.  This leaves out
     243                 :             :                  * the leader of a parallel group.
     244                 :             :                  */
     245   [ #  #  #  # ]:           0 :                 if (leader && leader->pid != MyProcPid)
     246                 :           0 :                         appendStringInfo(&buf, "%d", leader->pid);
     247                 :           0 :         }
     248                 :           0 :         appendStringInfoChar(&buf, ',');
     249                 :             : 
     250                 :             :         /* query id */
     251                 :           0 :         appendStringInfo(&buf, "%" PRId64, pgstat_get_my_query_id());
     252                 :             : 
     253                 :           0 :         appendStringInfoChar(&buf, '\n');
     254                 :             : 
     255                 :             :         /* If in the syslogger process, try to write messages direct to file */
     256         [ #  # ]:           0 :         if (MyBackendType == B_LOGGER)
     257                 :           0 :                 write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
     258                 :             :         else
     259                 :           0 :                 write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
     260                 :             : 
     261                 :           0 :         pfree(buf.data);
     262                 :           0 : }
        

Generated by: LCOV version 2.3.2-1