/* * write_jsonlog * Write logs in json format. */ static void write_jsonlog(ErrorData *edata) { StringInfoData buf; TransactionId txid = GetTopTransactionIdIfAny(); initStringInfo(&buf); /* Initialize string */ appendStringInfoChar(&buf, '{'); /* Timestamp */ if (log_time[0] == '\0') setup_formatted_log_time(); appendJSONLiteral(&buf, "timestamp", log_time, true); /* Username */ if (MyProcPort) appendJSONLiteral(&buf, "user", MyProcPort->user_name, true); /* Database name */ if (MyProcPort) appendJSONLiteral(&buf, "dbname", MyProcPort->database_name, true); /* Process ID */ if (MyProcPid != 0) appendStringInfo(&buf, "\"pid\":%d,", MyProcPid); /* Remote host and port */ if (MyProcPort && MyProcPort->remote_host) { appendJSONLiteral(&buf, "remote_host", MyProcPort->remote_host, true); if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0') appendJSONLiteral(&buf, "remote_port", MyProcPort->remote_port, true); } /* Session id */ if (MyProcPid != 0) appendStringInfo(&buf, "\"session_id\":\"%lx.%x\",", (long) MyStartTime, MyProcPid); /* Virtual transaction id */ /* keep VXID format in sync with lockfuncs.c */ if (MyProc != NULL && MyProc->backendId != InvalidBackendId) appendStringInfo(&buf, "\"vxid\":\"%d/%u\",", MyProc->backendId, MyProc->lxid); /* Transaction id */ if (txid != InvalidTransactionId) appendStringInfo(&buf, "\"txid\":%u,", GetTopTransactionIdIfAny()); /* Error severity */ appendJSONLiteral(&buf, "error_severity", (char *) error_severity(edata->elevel), true); /* SQL state code */ if (edata->sqlerrcode != ERRCODE_SUCCESSFUL_COMPLETION) appendJSONLiteral(&buf, "state_code", unpack_sql_state(edata->sqlerrcode), true); /* Error detail or Error detail log */ if (edata->detail_log) appendJSONLiteral(&buf, "detail_log", edata->detail_log, true); else if (edata->detail) appendJSONLiteral(&buf, "detail", edata->detail, true); /* Error hint */ if (edata->hint) appendJSONLiteral(&buf, "hint", edata->hint, true); /* Internal query */ if (edata->internalquery) appendJSONLiteral(&buf, "internal_query", edata->internalquery, true); /* Error context */ if (edata->context) appendJSONLiteral(&buf, "context", edata->context, true); /* 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); appendJSONLiteral(&buf, "file_location", msgbuf.data, true); pfree(msgbuf.data); } /* Application name */ if (application_name && application_name[0] != '\0') appendJSONLiteral(&buf, "application_name", application_name, true); /* Error message */ appendJSONLiteral(&buf, "message", edata->message, false); /* Finish string */ appendStringInfoChar(&buf, '}'); appendStringInfoChar(&buf, '\n'); /* If in the syslogger process, try to write messages direct to file */ if (am_syslogger) write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR); else write_pipe_chunks(buf.data, buf.len); /* Cleanup */ pfree(buf.data); /* Continue chain to previous hook */ if (prev_log_hook) (*prev_log_hook) (edata); }
/* * write_jsonlog * Write logs in json format. */ static void write_jsonlog(ErrorData *edata) { StringInfoData buf; TransactionId txid = GetTopTransactionIdIfAny(); /* * Disable logs to server, we don't want duplicate entries in * the server. */ edata->output_to_server = false; /* Determine whether message is enabled for server log output */ if (!is_log_level_output(edata->elevel, log_min_messages)) return; initStringInfo(&buf); /* Initialize string */ appendStringInfoChar(&buf, '{'); /* Timestamp */ setup_formatted_log_time(); appendJSONLiteral(&buf, "timestamp", formatted_log_time, true); /* Username */ if (MyProcPort && MyProcPort->user_name) appendJSONLiteral(&buf, "user", MyProcPort->user_name, true); /* Database name */ if (MyProcPort && MyProcPort->database_name) appendJSONLiteral(&buf, "dbname", MyProcPort->database_name, true); /* Process ID */ if (MyProcPid != 0) appendStringInfo(&buf, "\"pid\":%d,", MyProcPid); /* Remote host and port */ if (MyProcPort && MyProcPort->remote_host) { appendJSONLiteral(&buf, "remote_host", MyProcPort->remote_host, true); if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0') appendJSONLiteral(&buf, "remote_port", MyProcPort->remote_port, true); } /* Session id */ if (MyProcPid != 0) appendStringInfo(&buf, "\"session_id\":\"%lx.%x\",", (long) MyStartTime, MyProcPid); /* Virtual transaction id */ /* keep VXID format in sync with lockfuncs.c */ if (MyProc != NULL && MyProc->backendId != InvalidBackendId) appendStringInfo(&buf, "\"vxid\":\"%d/%u\",", MyProc->backendId, MyProc->lxid); /* Transaction id */ if (txid != InvalidTransactionId) appendStringInfo(&buf, "\"txid\":%u,", GetTopTransactionIdIfAny()); /* Error severity */ appendJSONLiteral(&buf, "error_severity", (char *) error_severity(edata->elevel), true); /* SQL state code */ if (edata->sqlerrcode != ERRCODE_SUCCESSFUL_COMPLETION) appendJSONLiteral(&buf, "state_code", unpack_sql_state(edata->sqlerrcode), true); /* Error detail or Error detail log */ if (edata->detail_log) appendJSONLiteral(&buf, "detail_log", edata->detail_log, true); else if (edata->detail) appendJSONLiteral(&buf, "detail", edata->detail, true); /* Error hint */ if (edata->hint) appendJSONLiteral(&buf, "hint", edata->hint, true); /* Internal query */ if (edata->internalquery) appendJSONLiteral(&buf, "internal_query", edata->internalquery, true); /* Error context */ if (edata->context) appendJSONLiteral(&buf, "context", edata->context, true); /* user query --- only reported if not disabled by the caller */ if (is_log_level_output(edata->elevel, log_min_error_statement) && debug_query_string != NULL && !edata->hide_stmt) { appendJSONLiteral(&buf, "statement", debug_query_string, true); if (edata->cursorpos > 0) appendStringInfo(&buf, "\"cursor_position\":%d,", edata->cursorpos); else if (edata->internalpos > 0) appendStringInfo(&buf, "\"internal_position\":%d,", edata->internalpos); } /* 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); appendJSONLiteral(&buf, "file_location", msgbuf.data, true); pfree(msgbuf.data); } /* Application name */ if (application_name && application_name[0] != '\0') appendJSONLiteral(&buf, "application_name", application_name, true); /* Error message */ appendJSONLiteral(&buf, "message", edata->message, false); /* Finish string */ appendStringInfoChar(&buf, '}'); appendStringInfoChar(&buf, '\n'); /* Write to stderr, if enabled */ if ((Log_destination & LOG_DESTINATION_STDERR) != 0) { if (Logging_collector && redirection_done && !am_syslogger) write_pipe_chunks(buf.data, buf.len); else write_console(buf.data, buf.len); } /* If in the syslogger process, try to write messages direct to file */ if (am_syslogger) write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR); /* Cleanup */ pfree(buf.data); /* Continue chain to previous hook */ if (prev_log_hook) (*prev_log_hook) (edata); }