From: Justin Pryzby Date: Fri, 13 Mar 2020 22:03:06 -0500 Subject: [PATCH v1 2/2] Include the leader PID in logfile See also: b025f32e0b, which adds the leader PID to pg_stat_activity --- doc/src/sgml/config.sgml | 8 +++- src/backend/utils/error/elog.c | 47 +++++++++++++++++++ src/backend/utils/misc/postgresql.conf.sample | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index fc0e2c00c3..d53b62e2df 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -6487,6 +6487,11 @@ local0.* /var/log/postgresql Process ID no + + %k + Leader PID for a parallel process, NULL otherwise + yes + %t Time stamp without milliseconds @@ -6777,7 +6782,7 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' character count of the error position therein, location of the error in the PostgreSQL source code (if log_error_verbosity is set to verbose), - application name, and backend type. + application name, backend type, and leader PID. Here is a sample table definition for storing CSV-format log output: @@ -6807,6 +6812,7 @@ CREATE TABLE postgres_log location text, application_name text, backend_type text, + leader_pid integer, PRIMARY KEY (session_id, session_line_num) ); diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 62eef7b71f..e6b3caf414 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -77,6 +77,7 @@ #include "postmaster/syslogger.h" #include "storage/ipc.h" #include "storage/proc.h" +#include "storage/procarray.h" #include "tcop/tcopprot.h" #include "utils/guc.h" #include "utils/memutils.h" @@ -177,6 +178,7 @@ static void write_console(const char *line, int len); static void setup_formatted_log_time(void); static void setup_formatted_start_time(void); static const char *process_log_prefix_padding(const char *p, int *padding); +static pid_t get_leader_pid(); static void log_line_prefix(StringInfo buf, ErrorData *edata); static void write_csvlog(ErrorData *edata); static void send_message_to_server_log(ErrorData *edata); @@ -2402,6 +2404,24 @@ process_log_prefix_padding(const char *p, int *ppadding) return p; } +/* Return PID of leader, or InvalidPid if not a parallel worker */ +static pid_t +get_leader_pid() +{ + PGPROC *proc; + pid_t leader_pid = InvalidPid; + + if (MyBackendType != B_BG_WORKER) + return InvalidPid; + + LWLockAcquire(ProcArrayLock, LW_SHARED); + proc = BackendPidGetProcWithLock(MyProcPid); + if (proc && proc->lockGroupLeader) + leader_pid = proc->lockGroupLeader->pid; + LWLockRelease(ProcArrayLock); + return leader_pid; +} + /* * Format tag info for log lines; append to the provided buffer. */ @@ -2413,6 +2433,10 @@ log_line_prefix(StringInfo buf, ErrorData *edata) /* has counter been reset in current process? */ static int log_my_pid = 0; + + /* Leader PID is retrieved only once per process after forking from postmaster */ + static pid_t leader_pid = InvalidPid; + int padding; const char *p; @@ -2427,6 +2451,7 @@ log_line_prefix(StringInfo buf, ErrorData *edata) log_line_number = 0; log_my_pid = MyProcPid; formatted_start_time[0] = '\0'; + leader_pid = get_leader_pid(); } log_line_number++; @@ -2560,6 +2585,18 @@ log_line_prefix(StringInfo buf, ErrorData *edata) else appendStringInfo(buf, "%d", MyProcPid); break; + + case 'k': + if (!MyProcPort) + ; /* Do nothing */ + else if (leader_pid == InvalidPid) + ; /* Do nothing */ + else if (padding != 0) + appendStringInfo(buf, "%*d", padding, leader_pid); + else + appendStringInfo(buf, "%d", leader_pid); + break; + case 'l': if (padding != 0) appendStringInfo(buf, "%*ld", padding, log_line_number); @@ -2768,6 +2805,9 @@ write_csvlog(ErrorData *edata) /* has counter been reset in current process? */ static int log_my_pid = 0; + /* Leader PID is retrieved only once per process after forking from postmaster */ + static pid_t leader_pid = InvalidPid; + /* * This is one of the few places where we'd rather not inherit a static * variable's value from the postmaster. But since we will, reset it when @@ -2778,6 +2818,7 @@ write_csvlog(ErrorData *edata) log_line_number = 0; log_my_pid = MyProcPid; formatted_start_time[0] = '\0'; + leader_pid = get_leader_pid(); } log_line_number++; @@ -2948,6 +2989,12 @@ write_csvlog(ErrorData *edata) else appendCSVLiteral(&buf, GetBackendTypeDesc(MyBackendType)); + appendStringInfoChar(&buf, ','); + + /* leader PID */ + if (MyProcPort && leader_pid != InvalidPid) + appendStringInfo(&buf, "%d", leader_pid); + appendStringInfoChar(&buf, '\n'); /* If in the syslogger process, try to write messages direct to file */ diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index c0e9531f9c..32fc4b18e6 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -530,6 +530,7 @@ # %r = remote host and port # %h = remote host # %p = process ID + # %k = leader PID # %t = timestamp without milliseconds # %m = timestamp with milliseconds # %n = timestamp with milliseconds (as a Unix epoch) -- 2.17.0 --QTprm0S8XgL7H0Dt--