diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 76f48b13d2..217910c9de 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1068,11 +1068,14 @@ exec_simple_query(const char *query_string) /* Log immediately if dictated by log_statement */ if (check_log_statement(parsetree_list)) { - ereport(LOG, - (errmsg("statement: %s", query_string), - errhidestmt(true), - errdetail_execute(parsetree_list))); - was_logged = true; + if (!Log_has_xid || TransactionIdIsValid(GetTopTransactionIdIfAny())) + { + ereport(LOG, + (errmsg("statement: %s", query_string), + errhidestmt(true), + errdetail_execute(parsetree_list))); + was_logged = true; + } } /* @@ -1283,6 +1286,16 @@ exec_simple_query(const char *query_string) PortalDrop(portal, false); + /* Log if dictated by log_statement and has not been logged. */ + if (!was_logged && check_log_statement(parsetree_list)) + { + ereport(LOG, + (errmsg("statement: %s", query_string), + errhidestmt(true), + errdetail_execute(parsetree_list))); + was_logged = true; + } + if (lnext(parsetree_list, parsetree_item) == NULL) { /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 605ff3b045..e7dd9f5027 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -79,6 +79,7 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "tcop/tcopprot.h" +#include "utils/guc.h" #include "utils/guc_hooks.h" #include "utils/memutils.h" #include "utils/ps_status.h" @@ -114,6 +115,9 @@ char *Log_destination_string = NULL; bool syslog_sequence_numbers = true; bool syslog_split_messages = true; +/* Whether the transaction id will appear in the log messages. */ +bool Log_has_xid = false; + /* Processed form of backtrace_functions GUC */ static char *backtrace_function_list; @@ -286,6 +290,50 @@ message_level_is_interesting(int elevel) } +/* + * check_log_line_prefix: GUC check_hook for Log_line_prefix + */ +bool check_log_line_prefix(char **newval, void **extra, GucSource source) +{ + const char *p; + + if ((*newval) == NULL) + { + Log_has_xid = false; + return true; + } + + Log_has_xid = false; + + for (p = (*newval); *p != '\0'; p++) + { + if (*p != '%') + { + /* literal char, just skip */ + continue; + } + + /* must be a '%', so skip to the next char */ + p++; + if (*p == '\0') + break; /* format error - ignore it */ + else if (*p == '%') + { + /* string contains %% */ + continue; + } + + /* process the option */ + if (*p == 'x') + { + Log_has_xid = true; + break; + } + } + + return true; +} + /* * in_error_recursion_trouble --- are we at risk of infinite error recursion? * diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index c68fdc008b..96948e5005 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -4103,7 +4103,7 @@ struct config_string ConfigureNamesString[] = }, &Log_line_prefix, "%m [%p] ", - NULL, NULL, NULL + check_log_line_prefix, NULL, NULL }, { diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 054dd2bf62..9536146ce3 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -502,6 +502,8 @@ extern PGDLLIMPORT char *Log_destination_string; extern PGDLLIMPORT bool syslog_sequence_numbers; extern PGDLLIMPORT bool syslog_split_messages; +extern PGDLLIMPORT bool Log_has_xid; + /* Log destination bitmap */ #define LOG_DESTINATION_STDERR 1 #define LOG_DESTINATION_SYSLOG 2 diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h index d64dc5fcdb..41f8ba3f16 100644 --- a/src/include/utils/guc_hooks.h +++ b/src/include/utils/guc_hooks.h @@ -78,6 +78,7 @@ extern bool check_log_destination(char **newval, void **extra, extern void assign_log_destination(const char *newval, void *extra); extern const char *show_log_file_mode(void); extern bool check_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_log_line_prefix(char **newval, void **extra, GucSource source); extern bool check_log_timezone(char **newval, void **extra, GucSource source); extern void assign_log_timezone(const char *newval, void *extra); extern const char *show_log_timezone(void);