From ad3fd72018fec9b180860c7d868de766ee7c1c4f Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Wed, 10 Jul 2019 09:29:15 -0400 Subject: [PATCH 2/2] Use log destination bitmap in log pipe protocol Replaces the dest field in PipeProtoHeader with dest_last, a bitmap of the log destination and whether the message is the last chunk of a message. --- src/backend/postmaster/syslogger.c | 12 +++++------- src/backend/utils/error/elog.c | 4 ++-- src/include/postmaster/syslogger.h | 5 +++-- src/include/utils/elog.h | 5 ++++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index bafd31d22b..f8a8cee401 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -879,21 +879,22 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer) { char *cursor = logbuffer; int count = *bytes_in_logbuffer; - int dest = LOG_DESTINATION_STDERR; /* While we have enough for a header, process data... */ while (count >= (int) (offsetof(PipeProtoHeader, data) + 1)) { PipeProtoHeader p; int chunklen; + int dest; /* Do we have a valid header? */ memcpy(&p, cursor, offsetof(PipeProtoHeader, data)); + dest = p.dest_last & ~PIPE_MESSAGE_IS_LAST; if (p.nuls[0] == '\0' && p.nuls[1] == '\0' && p.len > 0 && p.len <= PIPE_MAX_PAYLOAD && p.pid != 0 && - (p.is_last == 't' || p.is_last == 'f' || - p.is_last == 'T' || p.is_last == 'F')) + (dest == LOG_DESTINATION_CSVLOG || + dest == LOG_DESTINATION_STDERR)) { List *buffer_list; ListCell *cell; @@ -907,9 +908,6 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer) if (count < chunklen) break; - dest = (p.is_last == 'T' || p.is_last == 'F') ? - LOG_DESTINATION_CSVLOG : LOG_DESTINATION_STDERR; - /* Locate any existing buffer for this source pid */ buffer_list = buffer_lists[p.pid % NBUFFER_LISTS]; foreach(cell, buffer_list) @@ -925,7 +923,7 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer) free_slot = buf; } - if (p.is_last == 'f' || p.is_last == 'F') + if (!(p.dest_last & PIPE_MESSAGE_IS_LAST)) { /* * Save a complete non-final chunk in a per-pid buffer diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 8b4720ef3a..e69fb6b87c 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -3089,7 +3089,7 @@ write_pipe_chunks(char *data, int len, int dest) /* write all but the last chunk */ while (len > PIPE_MAX_PAYLOAD) { - p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'F' : 'f'); + p.proto.dest_last = (unsigned char) dest; p.proto.len = PIPE_MAX_PAYLOAD; memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD); rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD); @@ -3099,7 +3099,7 @@ write_pipe_chunks(char *data, int len, int dest) } /* write the last chunk */ - p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'T' : 't'); + p.proto.dest_last = (unsigned char) (dest | PIPE_MESSAGE_IS_LAST); p.proto.len = len; memcpy(p.proto.data, data, len); rc = write(fd, &p, PIPE_HEADER_SIZE + len); diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h index 3a61104573..3b95700cdb 100644 --- a/src/include/postmaster/syslogger.h +++ b/src/include/postmaster/syslogger.h @@ -46,8 +46,8 @@ typedef struct char nuls[2]; /* always \0\0 */ uint16 len; /* size of this chunk (counts data only) */ int32 pid; /* writer's pid */ - char is_last; /* last chunk of message? 't' or 'f' ('T' or - * 'F' for CSV case) */ + unsigned char dest_last; /* bitmap for log destination and whether + * this is the last chunk of message */ char data[FLEXIBLE_ARRAY_MEMBER]; /* data payload starts here */ } PipeProtoHeader; @@ -60,6 +60,7 @@ typedef union #define PIPE_HEADER_SIZE offsetof(PipeProtoHeader, data) #define PIPE_MAX_PAYLOAD ((int) (PIPE_CHUNK_SIZE - PIPE_HEADER_SIZE)) +#define PIPE_MESSAGE_IS_LAST (1<<7) /* GUC options */ extern bool Logging_collector; diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index dbfd8efd26..c9f33c8a5f 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -408,7 +408,10 @@ extern char *Log_destination_string; extern bool syslog_sequence_numbers; extern bool syslog_split_messages; -/* Log destination bitmap */ +/* + * Log destination bitmap + * Max value is 1<<6 as PipeProtoHeader.dest_last uses the last bit as a flag. + */ #define LOG_DESTINATION_STDERR 1 #define LOG_DESTINATION_SYSLOG 2 #define LOG_DESTINATION_EVENTLOG 4 -- 2.17.1