60 #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE)
63 #define LOGROTATE_SIGNAL_FILE "logrotate"
111 #define NBUFFER_LISTS 256
122 static HANDLE threadHandle = 0;
123 static CRITICAL_SECTION sysloggerSection;
134 static int syslogger_fdget(FILE *file);
135 static FILE *syslogger_fdopen(
int fd);
143 static unsigned int __stdcall pipeThread(
void *
arg);
145 static void logfile_rotate(
bool time_based_rotation,
int size_rotation_for);
148 int target_dest,
char **last_file_name,
171 int bytes_in_logbuffer = 0;
174 char *currentLogFilename;
175 int currentLogRotationAge;
190 Assert(startup_data_len ==
sizeof(*slsdata));
196 Assert(startup_data_len == 0);
298 InitializeCriticalSection(&sysloggerSection);
299 EnterCriticalSection(&sysloggerSection);
301 threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL);
302 if (threadHandle == 0)
303 elog(
FATAL,
"could not create syslogger data transfer thread: %m");
351 bool time_based_rotation =
false;
352 int size_rotation_for = 0;
378 pfree(currentLogDir);
389 pfree(currentLogFilename);
474 if (!time_based_rotation && size_rotation_for == 0)
500 if (delay > INT_MAX / 1000)
501 delay = INT_MAX / 1000;
502 cur_timeout = delay * 1000L;
515 WAIT_EVENT_SYSLOGGER_MAIN);
522 logbuffer + bytes_in_logbuffer,
523 sizeof(logbuffer) - bytes_in_logbuffer);
529 errmsg(
"could not read from logger pipe: %m")));
531 else if (bytesRead > 0)
533 bytes_in_logbuffer += bytesRead;
562 LeaveCriticalSection(&sysloggerSection);
565 WAIT_EVENT_SYSLOGGER_MAIN);
567 EnterCriticalSection(&sysloggerSection);
629 errmsg(
"could not create pipe for syslog: %m")));
634 SECURITY_ATTRIBUTES
sa;
636 memset(&
sa, 0,
sizeof(SECURITY_ATTRIBUTES));
637 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
638 sa.bInheritHandle = TRUE;
643 errmsg(
"could not create pipe for syslog: %m")));
709 if (sysloggerPid == -1)
712 (
errmsg(
"could not fork system logger: %m")));
731 (
errmsg(
"redirecting log output to logging collector process"),
732 errhint(
"Future log output will appear in directory \"%s\".",
740 errmsg(
"could not redirect stdout: %m")));
745 errmsg(
"could not redirect stderr: %m")));
758 _O_APPEND | _O_BINARY);
762 errmsg(
"could not redirect stderr: %m")));
789 return (
int) sysloggerPid;
802 syslogger_fdget(FILE *file)
811 return (
int) _get_osfhandle(_fileno(file));
824 syslogger_fdopen(
int fd)
831 file = fdopen(
fd,
"a");
837 fd = _open_osfhandle(
fd, _O_APPEND | _O_TEXT);
840 file = fdopen(
fd,
"a");
883 int count = *bytes_in_logbuffer;
898 if (p.
nuls[0] ==
'\0' && p.
nuls[1] ==
'\0' &&
912 if (count < chunklen)
929 foreach(cell, buffer_list)
938 if (
buf->pid == 0 && free_slot == NULL)
947 if (existing_slot != NULL)
958 if (free_slot == NULL)
965 buffer_list =
lappend(buffer_list, free_slot);
968 free_slot->pid = p.
pid;
969 str = &(free_slot->data);
982 if (existing_slot != NULL)
990 existing_slot->
pid = 0;
1018 for (chunklen = 1; chunklen < count; chunklen++)
1020 if (
cursor[chunklen] ==
'\0')
1031 if (count > 0 &&
cursor != logbuffer)
1032 memmove(logbuffer,
cursor, count);
1033 *bytes_in_logbuffer = count;
1074 if (*bytes_in_logbuffer > 0)
1077 *bytes_in_logbuffer = 0;
1119 rc = fwrite(buffer, 1, count,
logfile);
1140 static unsigned int __stdcall
1141 pipeThread(
void *
arg)
1144 int bytes_in_logbuffer = 0;
1152 logbuffer + bytes_in_logbuffer,
1153 sizeof(logbuffer) - bytes_in_logbuffer,
1162 EnterCriticalSection(&sysloggerSection);
1165 DWORD
error = GetLastError();
1167 if (
error == ERROR_HANDLE_EOF ||
1168 error == ERROR_BROKEN_PIPE)
1173 errmsg(
"could not read from logger pipe: %m")));
1175 else if (bytesRead > 0)
1177 bytes_in_logbuffer += bytesRead;
1192 LeaveCriticalSection(&sysloggerSection);
1204 LeaveCriticalSection(&sysloggerSection);
1237 _setmode(_fileno(fh), _O_TEXT);
1242 int save_errno = errno;
1246 errmsg(
"could not open log file \"%s\": %m",
1265 char **last_file_name, FILE **logFile)
1267 char *logFileExt = NULL;
1280 if (*logFile != NULL)
1283 if (*last_file_name != NULL)
1284 pfree(*last_file_name);
1285 *last_file_name = NULL;
1293 if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
1300 logFileExt =
".csv";
1302 logFileExt =
".json";
1319 *last_file_name != NULL &&
1320 strcmp(
filename, *last_file_name) != 0)
1333 if (errno != ENFILE && errno != EMFILE)
1336 (
errmsg(
"disabling automatic rotation (use SIGHUP to re-enable)")));
1346 if (*logFile != NULL)
1351 if (*last_file_name != NULL)
1352 pfree(*last_file_name);
1373 if (time_based_rotation)
1376 fntime = time(NULL);
1461 now -=
now % rotinterval;
1488 errmsg(
"could not remove file \"%s\": %m",
1504 _setmode(_fileno(fh), _O_TEXT);
1511 errmsg(
"could not open file \"%s\": %m",
1522 errmsg(
"could not write file \"%s\": %m",
1535 errmsg(
"could not write file \"%s\": %m",
1548 errmsg(
"could not write file \"%s\": %m",
1559 errmsg(
"could not rename file \"%s\" to \"%s\": %m",
1575 struct stat stat_buf;
Datum now(PG_FUNCTION_ARGS)
#define write_stderr(str)
#define Assert(condition)
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)
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
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)
void ResetLatch(Latch *latch)
#define WL_SOCKET_READABLE
pid_t postmaster_child_launch(BackendType child_type, 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
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
PGDLLIMPORT pg_tz * log_timezone
pqsigfunc pqsignal(int signo, pqsigfunc func)
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]
int SysLogger_Start(void)
static void sigUsr1Handler(SIGNAL_ARGS)
static void set_next_rotation_time(void)
static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
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)