60#define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE)
63#define LOGROTATE_SIGNAL_FILE "logrotate"
109#define NBUFFER_LISTS 256
120static HANDLE threadHandle = 0;
121static CRITICAL_SECTION sysloggerSection;
132static int syslogger_fdget(FILE *file);
133static FILE *syslogger_fdopen(
int fd);
141static unsigned int __stdcall pipeThread(
void *
arg);
143static void logfile_rotate(
bool time_based_rotation,
int size_rotation_for);
146 int target_dest,
char **last_file_name,
169 int bytes_in_logbuffer = 0;
172 char *currentLogFilename;
173 int currentLogRotationAge;
188 Assert(startup_data_len ==
sizeof(*slsdata));
194 Assert(startup_data_len == 0);
296 InitializeCriticalSection(&sysloggerSection);
297 EnterCriticalSection(&sysloggerSection);
299 threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL);
300 if (threadHandle == 0)
301 elog(
FATAL,
"could not create syslogger data transfer thread: %m");
349 bool time_based_rotation =
false;
350 int size_rotation_for = 0;
376 pfree(currentLogDir);
387 pfree(currentLogFilename);
472 if (!time_based_rotation && size_rotation_for == 0)
498 if (delay > INT_MAX / 1000)
499 delay = INT_MAX / 1000;
500 cur_timeout = delay * 1000L;
513 WAIT_EVENT_SYSLOGGER_MAIN);
520 logbuffer + bytes_in_logbuffer,
521 sizeof(logbuffer) - bytes_in_logbuffer);
527 errmsg(
"could not read from logger pipe: %m")));
529 else if (bytesRead > 0)
531 bytes_in_logbuffer += bytesRead;
560 LeaveCriticalSection(&sysloggerSection);
563 WAIT_EVENT_SYSLOGGER_MAIN);
565 EnterCriticalSection(&sysloggerSection);
626 errmsg(
"could not create pipe for syslog: %m")));
631 SECURITY_ATTRIBUTES
sa;
633 memset(&
sa, 0,
sizeof(SECURITY_ATTRIBUTES));
634 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
635 sa.bInheritHandle = TRUE;
640 errmsg(
"could not create pipe for syslog: %m")));
702 (
char *) &startup_data,
sizeof(startup_data), NULL);
708 if (sysloggerPid == -1)
711 (
errmsg(
"could not fork system logger: %m")));
730 (
errmsg(
"redirecting log output to logging collector process"),
731 errhint(
"Future log output will appear in directory \"%s\".",
739 errmsg(
"could not redirect stdout: %m")));
744 errmsg(
"could not redirect stderr: %m")));
757 _O_APPEND | _O_BINARY);
761 errmsg(
"could not redirect stderr: %m")));
788 return (
int) sysloggerPid;
801syslogger_fdget(FILE *file)
810 return (
int) _get_osfhandle(_fileno(file));
823syslogger_fdopen(
int fd)
830 file = fdopen(
fd,
"a");
836 fd = _open_osfhandle(
fd, _O_APPEND | _O_TEXT);
839 file = fdopen(
fd,
"a");
882 int count = *bytes_in_logbuffer;
897 if (p.
nuls[0] ==
'\0' && p.
nuls[1] ==
'\0' &&
911 if (count < chunklen)
928 foreach(cell, buffer_list)
937 if (
buf->pid == 0 && free_slot == NULL)
946 if (existing_slot != NULL)
957 if (free_slot == NULL)
964 buffer_list =
lappend(buffer_list, free_slot);
967 free_slot->pid = p.
pid;
968 str = &(free_slot->data);
981 if (existing_slot != NULL)
989 existing_slot->
pid = 0;
1017 for (chunklen = 1; chunklen < count; chunklen++)
1019 if (
cursor[chunklen] ==
'\0')
1030 if (count > 0 &&
cursor != logbuffer)
1031 memmove(logbuffer,
cursor, count);
1032 *bytes_in_logbuffer = count;
1073 if (*bytes_in_logbuffer > 0)
1076 *bytes_in_logbuffer = 0;
1118 rc = fwrite(buffer, 1, count,
logfile);
1139static unsigned int __stdcall
1140pipeThread(
void *
arg)
1143 int bytes_in_logbuffer = 0;
1151 logbuffer + bytes_in_logbuffer,
1152 sizeof(logbuffer) - bytes_in_logbuffer,
1161 EnterCriticalSection(&sysloggerSection);
1164 DWORD
error = GetLastError();
1166 if (
error == ERROR_HANDLE_EOF ||
1167 error == ERROR_BROKEN_PIPE)
1172 errmsg(
"could not read from logger pipe: %m")));
1174 else if (bytesRead > 0)
1176 bytes_in_logbuffer += bytesRead;
1193 LeaveCriticalSection(&sysloggerSection);
1205 LeaveCriticalSection(&sysloggerSection);
1238 _setmode(_fileno(fh), _O_TEXT);
1243 int save_errno = errno;
1247 errmsg(
"could not open log file \"%s\": %m",
1266 char **last_file_name, FILE **logFile)
1268 char *logFileExt = NULL;
1281 if (*logFile != NULL)
1284 if (*last_file_name != NULL)
1285 pfree(*last_file_name);
1286 *last_file_name = NULL;
1294 if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
1301 logFileExt =
".csv";
1303 logFileExt =
".json";
1320 *last_file_name != NULL &&
1321 strcmp(
filename, *last_file_name) != 0)
1334 if (errno != ENFILE && errno != EMFILE)
1337 (
errmsg(
"disabling automatic rotation (use SIGHUP to re-enable)")));
1347 if (*logFile != NULL)
1352 if (*last_file_name != NULL)
1353 pfree(*last_file_name);
1374 if (time_based_rotation)
1377 fntime = time(NULL);
1462 now -=
now % rotinterval;
1489 errmsg(
"could not remove file \"%s\": %m",
1505 _setmode(_fileno(fh), _O_TEXT);
1512 errmsg(
"could not open file \"%s\": %m",
1523 errmsg(
"could not write file \"%s\": %m",
1536 errmsg(
"could not write file \"%s\": %m",
1549 errmsg(
"could not write file \"%s\": %m",
1560 errmsg(
"could not rename file \"%s\" to \"%s\": %m",
1576 struct stat stat_buf;
Datum now(PG_FUNCTION_ARGS)
#define write_stderr(str)
#define Assert(condition)
#define fprintf(file, fmt, msg)
int errcode_for_socket_access(void)
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
#define LOG_DESTINATION_JSONLOG
#define LOG_DESTINATION_STDERR
#define ereport(elevel,...)
#define LOG_DESTINATION_CSVLOG
int MakePGDirectory(const char *directoryName)
void ProcessConfigFile(GucContext context)
volatile sig_atomic_t ConfigReloadPending
void SignalHandlerForConfigReload(SIGNAL_ARGS)
void SetLatch(Latch *latch)
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
void ResetLatch(Latch *latch)
#define WL_SOCKET_READABLE
pid_t postmaster_child_launch(BackendType child_type, int child_slot, char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
static void const char fflush(stdout)
List * lappend(List *list, void *datum)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext PostmasterContext
void MemoryContextDelete(MemoryContext context)
BackendType MyBackendType
PGDLLIMPORT const uint8 pg_number_of_ones[256]
static PgChecksumMode mode
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
PGDLLIMPORT pg_tz * log_timezone
size_t strlcpy(char *dst, const char *src, size_t siz)
CommandDest whereToSendOutput
static int fd(const char *x, int i)
void init_ps_display(const char *fixed_part)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void initStringInfo(StringInfo str)
bool Log_truncate_on_rotation
static bool rotation_disabled
static void logfile_rotate(bool time_based_rotation, int size_rotation_for)
static bool pipe_eof_seen
static bool logfile_rotate_dest(bool time_based_rotation, int size_rotation_for, pg_time_t fntime, int target_dest, char **last_file_name, FILE **logFile)
bool CheckLogrotateSignal(void)
static char * logfile_getname(pg_time_t timestamp, const char *suffix)
#define LOGROTATE_SIGNAL_FILE
static FILE * logfile_open(const char *filename, const char *mode, bool allow_errors)
static void update_metainfo_datafile(void)
static char * last_csv_file_name
NON_EXEC_STATIC pg_time_t first_syslogger_file_time
static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
void RemoveLogrotateSignalFiles(void)
void write_syslogger_file(const char *buffer, int count, int destination)
static pg_time_t next_rotation_time
static volatile sig_atomic_t rotation_requested
static List * buffer_lists[NBUFFER_LISTS]
static void sigUsr1Handler(SIGNAL_ARGS)
static void set_next_rotation_time(void)
static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
int SysLogger_Start(int child_slot)
static FILE * jsonlogFile
static char * last_json_file_name
void SysLoggerMain(char *startup_data, size_t startup_data_len)
static char * last_sys_file_name
#define PIPE_PROTO_DEST_JSONLOG
#define PIPE_PROTO_IS_LAST
#define PIPE_PROTO_DEST_CSVLOG
#define LOG_METAINFO_DATAFILE_TMP
#define PIPE_PROTO_DEST_STDERR
#define LOG_METAINFO_DATAFILE
void _dosmaperr(unsigned long)