LCOV - differential code coverage report
Current view: top level - src/backend/utils/error - csvlog.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 88.0 % 108 95 13 95
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 2 2 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 88.0 % 108 95 13 95
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 2 2 2

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

Generated by: LCOV version v1.16-55-g56c0a2a