| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * syslogger.h |
| 4 | * Exports from postmaster/syslogger.c. |
| 5 | * |
| 6 | * Copyright (c) 2004-2019, PostgreSQL Global Development Group |
| 7 | * |
| 8 | * src/include/postmaster/syslogger.h |
| 9 | * |
| 10 | *------------------------------------------------------------------------- |
| 11 | */ |
| 12 | #ifndef _SYSLOGGER_H |
| 13 | #define _SYSLOGGER_H |
| 14 | |
| 15 | #include <limits.h> /* for PIPE_BUF */ |
| 16 | |
| 17 | |
| 18 | /* |
| 19 | * Primitive protocol structure for writing to syslogger pipe(s). The idea |
| 20 | * here is to divide long messages into chunks that are not more than |
| 21 | * PIPE_BUF bytes long, which according to POSIX spec must be written into |
| 22 | * the pipe atomically. The pipe reader then uses the protocol headers to |
| 23 | * reassemble the parts of a message into a single string. The reader can |
| 24 | * also cope with non-protocol data coming down the pipe, though we cannot |
| 25 | * guarantee long strings won't get split apart. |
| 26 | * |
| 27 | * We use non-nul bytes in is_last to make the protocol a tiny bit |
| 28 | * more robust against finding a false double nul byte prologue. But |
| 29 | * we still might find it in the len and/or pid bytes unless we're careful. |
| 30 | */ |
| 31 | |
| 32 | #ifdef PIPE_BUF |
| 33 | /* Are there any systems with PIPE_BUF > 64K? Unlikely, but ... */ |
| 34 | #if PIPE_BUF > 65536 |
| 35 | #define PIPE_CHUNK_SIZE 65536 |
| 36 | #else |
| 37 | #define PIPE_CHUNK_SIZE ((int) PIPE_BUF) |
| 38 | #endif |
| 39 | #else /* not defined */ |
| 40 | /* POSIX says the value of PIPE_BUF must be at least 512, so use that */ |
| 41 | #define PIPE_CHUNK_SIZE 512 |
| 42 | #endif |
| 43 | |
| 44 | typedef struct |
| 45 | { |
| 46 | char nuls[2]; /* always \0\0 */ |
| 47 | uint16 len; /* size of this chunk (counts data only) */ |
| 48 | int32 pid; /* writer's pid */ |
| 49 | char is_last; /* last chunk of message? 't' or 'f' ('T' or |
| 50 | * 'F' for CSV case) */ |
| 51 | char data[FLEXIBLE_ARRAY_MEMBER]; /* data payload starts here */ |
| 52 | } ; |
| 53 | |
| 54 | typedef union |
| 55 | { |
| 56 | PipeProtoHeader proto; |
| 57 | char filler[PIPE_CHUNK_SIZE]; |
| 58 | } PipeProtoChunk; |
| 59 | |
| 60 | #define offsetof(PipeProtoHeader, data) |
| 61 | #define PIPE_MAX_PAYLOAD ((int) (PIPE_CHUNK_SIZE - PIPE_HEADER_SIZE)) |
| 62 | |
| 63 | |
| 64 | /* GUC options */ |
| 65 | extern bool Logging_collector; |
| 66 | extern int Log_RotationAge; |
| 67 | extern int Log_RotationSize; |
| 68 | extern PGDLLIMPORT char *Log_directory; |
| 69 | extern PGDLLIMPORT char *Log_filename; |
| 70 | extern bool Log_truncate_on_rotation; |
| 71 | extern int Log_file_mode; |
| 72 | |
| 73 | extern bool am_syslogger; |
| 74 | |
| 75 | #ifndef WIN32 |
| 76 | extern int syslogPipe[2]; |
| 77 | #else |
| 78 | extern HANDLE syslogPipe[2]; |
| 79 | #endif |
| 80 | |
| 81 | |
| 82 | extern int SysLogger_Start(void); |
| 83 | |
| 84 | extern void write_syslogger_file(const char *buffer, int count, int dest); |
| 85 | |
| 86 | #ifdef EXEC_BACKEND |
| 87 | extern void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn(); |
| 88 | #endif |
| 89 | |
| 90 | extern bool CheckLogrotateSignal(void); |
| 91 | extern void RemoveLogrotateSignalFiles(void); |
| 92 | |
| 93 | /* |
| 94 | * Name of files saving meta-data information about the log |
| 95 | * files currently in use by the syslogger |
| 96 | */ |
| 97 | #define LOG_METAINFO_DATAFILE "current_logfiles" |
| 98 | #define LOG_METAINFO_DATAFILE_TMP LOG_METAINFO_DATAFILE ".tmp" |
| 99 | |
| 100 | #endif /* _SYSLOGGER_H */ |
| 101 | |