PostgreSQL Source Code  git master
jsonlog.c File Reference
#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/json.h"
#include "utils/ps_status.h"
Include dependency graph for jsonlog.c:

Go to the source code of this file.

Functions

static void appendJSONKeyValueFmt (StringInfo buf, const char *key, bool escape_key, const char *fmt,...) pg_attribute_printf(4
 
static void static void appendJSONKeyValue (StringInfo buf, const char *key, const char *value, bool escape_value)
 
void write_jsonlog (ErrorData *edata)
 

Function Documentation

◆ appendJSONKeyValue()

static void static void appendJSONKeyValue ( StringInfo  buf,
const char *  key,
const char *  value,
bool  escape_value 
)
static

Definition at line 45 of file jsonlog.c.

47 {
48  Assert(key != NULL);
49 
50  if (value == NULL)
51  return;
52 
56 
57  if (escape_value)
59  else
61 }
static struct @144 value
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1271
Assert(fmt[strlen(fmt) - 1] !='\n')
static char * buf
Definition: pg_test_fsync.c:67
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188

References appendStringInfoChar(), appendStringInfoString(), Assert(), buf, escape_json(), sort-test::key, and value.

Referenced by appendJSONKeyValueFmt(), and write_jsonlog().

◆ appendJSONKeyValueFmt()

static void appendJSONKeyValueFmt ( StringInfo  buf,
const char *  key,
bool  escape_key,
const char *  fmt,
  ... 
)
static

Definition at line 72 of file jsonlog.c.

74 {
75  int save_errno = errno;
76  size_t len = 128; /* initial assumption about buffer size */
77  char *value;
78 
79  for (;;)
80  {
81  va_list args;
82  size_t newlen;
83 
84  /* Allocate result buffer */
85  value = (char *) palloc(len);
86 
87  /* Try to format the data. */
88  errno = save_errno;
89  va_start(args, fmt);
90  newlen = pvsnprintf(value, len, fmt, args);
91  va_end(args);
92 
93  if (newlen < len)
94  break; /* success */
95 
96  /* Release buffer and loop around to try again with larger len. */
97  pfree(value);
98  len = newlen;
99  }
100 
101  appendJSONKeyValue(buf, key, value, escape_key);
102 
103  /* Clean up */
104  pfree(value);
105 }
static void static void appendJSONKeyValue(StringInfo buf, const char *key, const char *value, bool escape_value)
Definition: jsonlog.c:45
static void const char * fmt
va_end(args)
va_start(args, fmt)
void pfree(void *pointer)
Definition: mcxt.c:1252
void * palloc(Size size)
Definition: mcxt.c:1145
const void size_t len
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:106

References appendJSONKeyValue(), generate_unaccent_rules::args, buf, fmt, sort-test::key, len, palloc(), pfree(), pvsnprintf(), va_end(), va_start(), and value.

Referenced by write_jsonlog().

◆ write_jsonlog()

void write_jsonlog ( ErrorData edata)

Definition at line 111 of file jsonlog.c.

112 {
114  char *start_time;
115  char *log_time;
116 
117  /* static counter for line numbers */
118  static long log_line_number = 0;
119 
120  /* Has the counter been reset in the current process? */
121  static int log_my_pid = 0;
122 
123  /*
124  * This is one of the few places where we'd rather not inherit a static
125  * variable's value from the postmaster. But since we will, reset it when
126  * MyProcPid changes.
127  */
128  if (log_my_pid != MyProcPid)
129  {
130  log_line_number = 0;
131  log_my_pid = MyProcPid;
133  }
134  log_line_number++;
135 
137 
138  /* Initialize string */
139  appendStringInfoChar(&buf, '{');
140 
141  /* timestamp with milliseconds */
142  log_time = get_formatted_log_time();
143 
144  /*
145  * First property does not use appendJSONKeyValue as it does not have
146  * comma prefix.
147  */
148  escape_json(&buf, "timestamp");
149  appendStringInfoChar(&buf, ':');
150  escape_json(&buf, log_time);
151 
152  /* username */
153  if (MyProcPort)
154  appendJSONKeyValue(&buf, "user", MyProcPort->user_name, true);
155 
156  /* database name */
157  if (MyProcPort)
158  appendJSONKeyValue(&buf, "dbname", MyProcPort->database_name, true);
159 
160  /* Process ID */
161  if (MyProcPid != 0)
162  appendJSONKeyValueFmt(&buf, "pid", false, "%d", MyProcPid);
163 
164  /* Remote host and port */
166  {
167  appendJSONKeyValue(&buf, "remote_host", MyProcPort->remote_host, true);
168  if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
169  appendJSONKeyValue(&buf, "remote_port", MyProcPort->remote_port, false);
170  }
171 
172  /* Session id */
173  appendJSONKeyValueFmt(&buf, "session_id", true, "%lx.%x",
174  (long) MyStartTime, MyProcPid);
175 
176  /* Line number */
177  appendJSONKeyValueFmt(&buf, "line_num", false, "%ld", log_line_number);
178 
179  /* PS display */
180  if (MyProcPort)
181  {
182  StringInfoData msgbuf;
183  const char *psdisp;
184  int displen;
185 
186  initStringInfo(&msgbuf);
187  psdisp = get_ps_display(&displen);
188  appendBinaryStringInfo(&msgbuf, psdisp, displen);
189  appendJSONKeyValue(&buf, "ps", msgbuf.data, true);
190 
191  pfree(msgbuf.data);
192  }
193 
194  /* session start timestamp */
196  appendJSONKeyValue(&buf, "session_start", start_time, true);
197 
198  /* Virtual transaction id */
199  /* keep VXID format in sync with lockfuncs.c */
200  if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
201  appendJSONKeyValueFmt(&buf, "vxid", true, "%d/%u", MyProc->backendId,
202  MyProc->lxid);
203 
204  /* Transaction id */
205  appendJSONKeyValueFmt(&buf, "txid", false, "%u",
207 
208  /* Error severity */
209  if (edata->elevel)
210  appendJSONKeyValue(&buf, "error_severity",
211  (char *) error_severity(edata->elevel), true);
212 
213  /* SQL state code */
214  if (edata->sqlerrcode)
215  appendJSONKeyValue(&buf, "state_code",
216  unpack_sql_state(edata->sqlerrcode), true);
217 
218  /* errmessage */
219  appendJSONKeyValue(&buf, "message", edata->message, true);
220 
221  /* errdetail or error_detail log */
222  if (edata->detail_log)
223  appendJSONKeyValue(&buf, "detail", edata->detail_log, true);
224  else
225  appendJSONKeyValue(&buf, "detail", edata->detail, true);
226 
227  /* errhint */
228  if (edata->hint)
229  appendJSONKeyValue(&buf, "hint", edata->hint, true);
230 
231  /* internal query */
232  if (edata->internalquery)
233  appendJSONKeyValue(&buf, "internal_query", edata->internalquery,
234  true);
235 
236  /* if printed internal query, print internal pos too */
237  if (edata->internalpos > 0 && edata->internalquery != NULL)
238  appendJSONKeyValueFmt(&buf, "internal_position", false, "%d",
239  edata->internalpos);
240 
241  /* errcontext */
242  if (edata->context && !edata->hide_ctx)
243  appendJSONKeyValue(&buf, "context", edata->context, true);
244 
245  /* user query --- only reported if not disabled by the caller */
246  if (check_log_of_query(edata))
247  {
248  appendJSONKeyValue(&buf, "statement", debug_query_string, true);
249  if (edata->cursorpos > 0)
250  appendJSONKeyValueFmt(&buf, "cursor_position", false, "%d",
251  edata->cursorpos);
252  }
253 
254  /* file error location */
256  {
257  if (edata->funcname)
258  appendJSONKeyValue(&buf, "func_name", edata->funcname, true);
259  if (edata->filename)
260  {
261  appendJSONKeyValue(&buf, "file_name", edata->filename, true);
262  appendJSONKeyValueFmt(&buf, "file_line_num", false, "%d",
263  edata->lineno);
264  }
265  }
266 
267  /* Application name */
268  if (application_name && application_name[0] != '\0')
269  appendJSONKeyValue(&buf, "application_name", application_name, true);
270 
271  /* backend type */
272  appendJSONKeyValue(&buf, "backend_type", get_backend_type_for_log(), true);
273 
274  /* leader PID */
275  if (MyProc)
276  {
277  PGPROC *leader = MyProc->lockGroupLeader;
278 
279  /*
280  * Show the leader only for active parallel workers. This leaves out
281  * the leader of a parallel group.
282  */
283  if (leader && leader->pid != MyProcPid)
284  appendJSONKeyValueFmt(&buf, "leader_pid", false, "%d",
285  leader->pid);
286  }
287 
288  /* query id */
289  appendJSONKeyValueFmt(&buf, "query_id", false, "%lld",
290  (long long) pgstat_get_my_query_id());
291 
292  /* Finish string */
293  appendStringInfoChar(&buf, '}');
294  appendStringInfoChar(&buf, '\n');
295 
296  /* If in the syslogger process, try to write messages direct to file */
297  if (MyBackendType == B_LOGGER)
299  else
301 
302  pfree(buf.data);
303 }
uint64 pgstat_get_my_query_id(void)
#define InvalidBackendId
Definition: backendid.h:23
bool check_log_of_query(ErrorData *edata)
Definition: elog.c:2539
char * get_formatted_log_time(void)
Definition: elog.c:2465
int Log_error_verbosity
Definition: elog.c:110
const char * error_severity(int elevel)
Definition: elog.c:3478
const char * get_backend_type_for_log(void)
Definition: elog.c:2562
void write_pipe_chunks(char *data, int len, int dest)
Definition: elog.c:3240
char * unpack_sql_state(int sql_state)
Definition: elog.c:2977
char * get_formatted_start_time(void)
Definition: elog.c:2515
void reset_formatted_start_time(void)
Definition: elog.c:2503
@ PGERROR_VERBOSE
Definition: elog.h:412
#define LOG_DESTINATION_JSONLOG
Definition: elog.h:427
int MyProcPid
Definition: globals.c:44
struct Port * MyProcPort
Definition: globals.c:47
pg_time_t MyStartTime
Definition: globals.c:45
char * application_name
Definition: guc_tables.c:510
static void appendJSONKeyValueFmt(StringInfo buf, const char *key, bool escape_key, const char *fmt,...) pg_attribute_printf(4
Definition: jsonlog.c:72
@ B_LOGGER
Definition: miscadmin.h:326
BackendType MyBackendType
Definition: miscinit.c:63
static time_t start_time
Definition: pg_ctl.c:97
const char * debug_query_string
Definition: postgres.c:82
const char * get_ps_display(int *displen)
Definition: ps_status.c:413
PGPROC * MyProc
Definition: proc.c:68
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int internalpos
Definition: elog.h:383
char * context
Definition: elog.h:374
char * internalquery
Definition: elog.h:384
int sqlerrcode
Definition: elog.h:369
const char * filename
Definition: elog.h:364
int elevel
Definition: elog.h:359
char * detail
Definition: elog.h:371
const char * funcname
Definition: elog.h:366
char * message
Definition: elog.h:370
char * detail_log
Definition: elog.h:372
int lineno
Definition: elog.h:365
char * hint
Definition: elog.h:373
bool hide_ctx
Definition: elog.h:363
int cursorpos
Definition: elog.h:382
Definition: proc.h:162
LocalTransactionId lxid
Definition: proc.h:183
BackendId backendId
Definition: proc.h:193
int pid
Definition: proc.h:186
PGPROC * lockGroupLeader
Definition: proc.h:291
char * user_name
Definition: libpq-be.h:166
char * remote_port
Definition: libpq-be.h:157
char * database_name
Definition: libpq-be.h:165
char * remote_host
Definition: libpq-be.h:152
void write_syslogger_file(const char *buffer, int count, int destination)
Definition: syslogger.c:1143
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:428

References appendBinaryStringInfo(), appendJSONKeyValue(), appendJSONKeyValueFmt(), appendStringInfoChar(), application_name, B_LOGGER, PGPROC::backendId, buf, check_log_of_query(), ErrorData::context, ErrorData::cursorpos, StringInfoData::data, Port::database_name, debug_query_string, ErrorData::detail, ErrorData::detail_log, ErrorData::elevel, error_severity(), escape_json(), ErrorData::filename, ErrorData::funcname, get_backend_type_for_log(), get_formatted_log_time(), get_formatted_start_time(), get_ps_display(), GetTopTransactionIdIfAny(), ErrorData::hide_ctx, ErrorData::hint, initStringInfo(), ErrorData::internalpos, ErrorData::internalquery, InvalidBackendId, ErrorData::lineno, PGPROC::lockGroupLeader, LOG_DESTINATION_JSONLOG, Log_error_verbosity, PGPROC::lxid, ErrorData::message, MyBackendType, MyProc, MyProcPid, MyProcPort, MyStartTime, pfree(), PGERROR_VERBOSE, pgstat_get_my_query_id(), PGPROC::pid, Port::remote_host, Port::remote_port, reset_formatted_start_time(), ErrorData::sqlerrcode, start_time, unpack_sql_state(), Port::user_name, write_pipe_chunks(), and write_syslogger_file().

Referenced by send_message_to_server_log().