PostgreSQL Source Code git master
csvlog.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * csvlog.c
4 * CSV logging
5 *
6 * Portions Copyright (c) 1996-2025, 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"
23#include "storage/lock.h"
24#include "storage/proc.h"
25#include "tcop/tcopprot.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 */
36static inline void
38{
39 const char *p = data;
40 char c;
41
42 /* avoid confusing an empty string with NULL */
43 if (p == NULL)
44 return;
45
47 while ((c = *p++) != '\0')
48 {
49 if (c == '"')
52 }
54}
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 */
62void
64{
66 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 if (log_my_pid != MyProcPid)
80 {
81 log_line_number = 0;
82 log_my_pid = MyProcPid;
84 }
85 log_line_number++;
86
88
89 /* timestamp with milliseconds */
92
93 /* username */
94 if (MyProcPort)
97
98 /* database name */
99 if (MyProcPort)
102
103 /* Process id */
104 if (MyProcPid != 0)
107
108 /* Remote host and port */
110 {
113 if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
114 {
117 }
119 }
121
122 /* session id */
125
126 /* Line number */
127 appendStringInfo(&buf, "%ld", log_line_number);
129
130 /* PS display */
131 if (MyProcPort)
132 {
133 StringInfoData msgbuf;
134 const char *psdisp;
135 int displen;
136
137 initStringInfo(&msgbuf);
138
139 psdisp = get_ps_display(&displen);
140 appendBinaryStringInfo(&msgbuf, psdisp, displen);
141 appendCSVLiteral(&buf, msgbuf.data);
142
143 pfree(msgbuf.data);
144 }
146
147 /* session start timestamp */
150
151 /* Virtual transaction id */
152 /* keep VXID format in sync with lockfuncs.c */
156
157 /* Transaction id */
160
161 /* Error severity */
164
165 /* SQL state code */
168
169 /* errmessage */
170 appendCSVLiteral(&buf, edata->message);
172
173 /* errdetail or errdetail_log */
174 if (edata->detail_log)
176 else
177 appendCSVLiteral(&buf, edata->detail);
179
180 /* errhint */
181 appendCSVLiteral(&buf, edata->hint);
183
184 /* internal query */
187
188 /* if printed internal query, print internal pos too */
189 if (edata->internalpos > 0 && edata->internalquery != NULL)
190 appendStringInfo(&buf, "%d", edata->internalpos);
192
193 /* errcontext */
194 if (!edata->hide_ctx)
195 appendCSVLiteral(&buf, edata->context);
197
198 /* user query --- only reported if not disabled by the caller */
199 print_stmt = check_log_of_query(edata);
200 if (print_stmt)
203 if (print_stmt && edata->cursorpos > 0)
204 appendStringInfo(&buf, "%d", edata->cursorpos);
206
207 /* file error location */
209 {
210 StringInfoData msgbuf;
211
212 initStringInfo(&msgbuf);
213
214 if (edata->funcname && edata->filename)
215 appendStringInfo(&msgbuf, "%s, %s:%d",
216 edata->funcname, edata->filename,
217 edata->lineno);
218 else if (edata->filename)
219 appendStringInfo(&msgbuf, "%s:%d",
220 edata->filename, edata->lineno);
221 appendCSVLiteral(&buf, msgbuf.data);
222 pfree(msgbuf.data);
223 }
225
226 /* application name */
229
231
232 /* backend type */
235
236 /* leader PID */
237 if (MyProc)
238 {
239 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 if (leader && leader->pid != MyProcPid)
246 appendStringInfo(&buf, "%d", leader->pid);
247 }
249
250 /* query id */
251 appendStringInfo(&buf, "%lld", (long long) pgstat_get_my_query_id());
252
254
255 /* If in the syslogger process, try to write messages direct to file */
256 if (MyBackendType == B_LOGGER)
258 else
260
261 pfree(buf.data);
262}
uint64 pgstat_get_my_query_id(void)
#define INT64_HEX_FORMAT
Definition: c.h:522
static void appendCSVLiteral(StringInfo buf, const char *data)
Definition: csvlog.c:37
void write_csvlog(ErrorData *edata)
Definition: csvlog.c:63
bool check_log_of_query(ErrorData *edata)
Definition: elog.c:2731
const char * error_severity(int elevel)
Definition: elog.c:3670
int Log_error_verbosity
Definition: elog.c:108
char * get_formatted_start_time(void)
Definition: elog.c:2707
void write_pipe_chunks(char *data, int len, int dest)
Definition: elog.c:3429
const char * get_backend_type_for_log(void)
Definition: elog.c:2754
char * get_formatted_log_time(void)
Definition: elog.c:2657
char * unpack_sql_state(int sql_state)
Definition: elog.c:3169
#define _(x)
Definition: elog.c:90
void reset_formatted_start_time(void)
Definition: elog.c:2695
@ PGERROR_VERBOSE
Definition: elog.h:473
#define LOG_DESTINATION_CSVLOG
Definition: elog.h:487
int MyProcPid
Definition: globals.c:46
struct Port * MyProcPort
Definition: globals.c:50
pg_time_t MyStartTime
Definition: globals.c:47
char * application_name
Definition: guc_tables.c:548
void pfree(void *pointer)
Definition: mcxt.c:1524
@ B_LOGGER
Definition: miscadmin.h:373
BackendType MyBackendType
Definition: miscinit.c:64
const void * data
static char * buf
Definition: pg_test_fsync.c:72
const char * debug_query_string
Definition: postgres.c:88
char * c
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
const char * get_ps_display(int *displen)
Definition: ps_status.c:532
PGPROC * MyProc
Definition: proc.c:66
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:231
int internalpos
Definition: elog.h:444
char * context
Definition: elog.h:435
char * internalquery
Definition: elog.h:445
int sqlerrcode
Definition: elog.h:430
const char * filename
Definition: elog.h:425
int elevel
Definition: elog.h:420
char * detail
Definition: elog.h:432
const char * funcname
Definition: elog.h:427
char * message
Definition: elog.h:431
char * detail_log
Definition: elog.h:433
int lineno
Definition: elog.h:426
char * hint
Definition: elog.h:434
bool hide_ctx
Definition: elog.h:424
int cursorpos
Definition: elog.h:443
Definition: proc.h:163
struct PGPROC::@127 vxid
LocalTransactionId lxid
Definition: proc.h:201
ProcNumber procNumber
Definition: proc.h:196
int pid
Definition: proc.h:183
PGPROC * lockGroupLeader
Definition: proc.h:305
char * user_name
Definition: libpq-be.h:154
char * remote_port
Definition: libpq-be.h:146
char * database_name
Definition: libpq-be.h:153
char * remote_host
Definition: libpq-be.h:141
void write_syslogger_file(const char *buffer, int count, int destination)
Definition: syslogger.c:1093
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:441