aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/syslogger.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2021-09-13 09:03:45 +0900
committerMichael Paquier <michael@paquier.xyz>2021-09-13 09:03:45 +0900
commit2d77d835403a20b51e17e59f0343ddc17f431eec (patch)
tree9d0ab1c3b3e3752c5209f7c8ae4c2922a762457b /src/backend/postmaster/syslogger.c
parente757080e041214cf6983e3e77ef01e83f1371d72 (diff)
downloadpostgresql-2d77d835403a20b51e17e59f0343ddc17f431eec.tar.gz
postgresql-2d77d835403a20b51e17e59f0343ddc17f431eec.zip
Refactor the syslogger pipe protocol to use a bitmask for its options
The previous protocol expected a set of matching characters to check if a message sent was the last one or not, that changed depending on the destination wanted: - 't' and 'f' tracked the last message of a log sent to stderr. - 'T' and 'F' tracked the last message of a log sent to csvlog. This could be extended with more characters when introducing new destinations, but using a bitmask is much more elegant. This commit changes the protocol so as a bitmask is used in the header of a log chunk message sent to the syslogger, with the following options available for now: - log_destination as stderr. - log_destination as csvlog. - if a message is the last chunk of a message. Sehrope found this issue in a patch set to introduce JSON as an option for log_destination, but his patch made the size of the protocol header larger. This commit keeps the same size as the original, and adapts the protocol as wanted. Thanks also to Andrew Dunstan and Greg Stark for the discussion. Author: Michael Paquier, Sehrope Sarkuni Discussion: https://postgr.es/m/CAH7T-aqswBM6JWe4pDehi1uOiufqe06DJWaU5=X7dDLyqUExHg@mail.gmail.com
Diffstat (limited to 'src/backend/postmaster/syslogger.c')
-rw-r--r--src/backend/postmaster/syslogger.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index cad43bdef23..bca38835726 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -38,6 +38,7 @@
#include "nodes/pg_list.h"
#include "pgstat.h"
#include "pgtime.h"
+#include "port/pg_bitutils.h"
#include "postmaster/fork_process.h"
#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
@@ -885,14 +886,15 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
{
PipeProtoHeader p;
int chunklen;
+ bits8 dest_flags;
/* Do we have a valid header? */
memcpy(&p, cursor, offsetof(PipeProtoHeader, data));
+ dest_flags = p.flags & (PIPE_PROTO_DEST_STDERR | PIPE_PROTO_DEST_CSVLOG);
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'))
+ pg_popcount((char *) &dest_flags, 1) == 1)
{
List *buffer_list;
ListCell *cell;
@@ -906,8 +908,15 @@ 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;
+ if ((p.flags & PIPE_PROTO_DEST_STDERR) != 0)
+ dest = LOG_DESTINATION_STDERR;
+ else if ((p.flags & PIPE_PROTO_DEST_CSVLOG) != 0)
+ dest = LOG_DESTINATION_CSVLOG;
+ else
+ {
+ /* this should never happen as of the header validation */
+ Assert(false);
+ }
/* Locate any existing buffer for this source pid */
buffer_list = buffer_lists[p.pid % NBUFFER_LISTS];
@@ -924,7 +933,7 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
free_slot = buf;
}
- if (p.is_last == 'f' || p.is_last == 'F')
+ if ((p.flags & PIPE_PROTO_IS_LAST) == 0)
{
/*
* Save a complete non-final chunk in a per-pid buffer