/*
* Saved timeval and buffers for formatted timestamps that might be used by
- * both log_line_prefix and csv logs.
+ * log_line_prefix, csv logs and JSON logs.
*/
static struct timeval saved_timeval;
static bool saved_timeval_set = false;
CHECK_STACK_DEPTH();
oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+ /*
+ * Reset the formatted timestamp fields before emitting any logs. This
+ * includes all the log destinations and emit_log_hook, as the latter
+ * could use log_line_prefix or the formatted timestamps.
+ */
+ saved_timeval_set = false;
+ formatted_log_time[0] = '\0';
+
/*
* Call hook before sending message to log. The hook function is allowed
* to turn off edata->output_to_server, so we must recheck that afterward.
/*
* Note: we expect that guc.c will ensure that log_timezone is set up (at
* least with a minimal GMT value) before Log_line_prefix can become
- * nonempty or CSV mode can be selected.
+ * nonempty or CSV/JSON mode can be selected.
*/
pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
/* leave room for milliseconds... */
/*
* Note: we expect that guc.c will ensure that log_timezone is set up (at
* least with a minimal GMT value) before Log_line_prefix can become
- * nonempty or CSV mode can be selected.
+ * nonempty or CSV/JSON mode can be selected.
*/
pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
"%Y-%m-%d %H:%M:%S %Z",
initStringInfo(&buf);
- saved_timeval_set = false;
- formatted_log_time[0] = '\0';
-
log_line_prefix(&buf, edata);
appendStringInfo(&buf, "%s: ", _(error_severity(edata->elevel)));