60 #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE)
63 #define LOGROTATE_SIGNAL_FILE "logrotate"
109 #define NBUFFER_LISTS 256
120 static HANDLE threadHandle = 0;
121 static CRITICAL_SECTION sysloggerSection;
132 static int syslogger_fdget(FILE *file);
133 static FILE *syslogger_fdopen(
int fd);
141 static unsigned int __stdcall pipeThread(
void *
arg);
143 static 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);
627 errmsg(
"could not create pipe for syslog: %m")));
632 SECURITY_ATTRIBUTES
sa;
634 memset(&
sa, 0,
sizeof(SECURITY_ATTRIBUTES));
635 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
636 sa.bInheritHandle = TRUE;
641 errmsg(
"could not create pipe for syslog: %m")));
707 if (sysloggerPid == -1)
710 (
errmsg(
"could not fork system logger: %m")));
729 (
errmsg(
"redirecting log output to logging collector process"),
730 errhint(
"Future log output will appear in directory \"%s\".",
738 errmsg(
"could not redirect stdout: %m")));
743 errmsg(
"could not redirect stderr: %m")));
756 _O_APPEND | _O_BINARY);
760 errmsg(
"could not redirect stderr: %m")));
787 return (
int) sysloggerPid;
800 syslogger_fdget(FILE *file)
809 return (
int) _get_osfhandle(_fileno(file));
822 syslogger_fdopen(
int fd)
829 file = fdopen(
fd,
"a");
835 fd = _open_osfhandle(
fd, _O_APPEND | _O_TEXT);
838 file = fdopen(
fd,
"a");
881 int count = *bytes_in_logbuffer;
896 if (p.
nuls[0] ==
'\0' && p.
nuls[1] ==
'\0' &&
910 if (count < chunklen)
927 foreach(cell, buffer_list)
936 if (
buf->pid == 0 && free_slot == NULL)
945 if (existing_slot != NULL)
956 if (free_slot == NULL)
963 buffer_list =
lappend(buffer_list, free_slot);
966 free_slot->pid = p.
pid;
967 str = &(free_slot->data);
980 if (existing_slot != NULL)
988 existing_slot->
pid = 0;
1016 for (chunklen = 1; chunklen < count; chunklen++)
1018 if (
cursor[chunklen] ==
'\0')
1029 if (count > 0 &&
cursor != logbuffer)
1030 memmove(logbuffer,
cursor, count);
1031 *bytes_in_logbuffer = count;
1072 if (*bytes_in_logbuffer > 0)
1075 *bytes_in_logbuffer = 0;
1117 rc = fwrite(buffer, 1, count,
logfile);
1138 static unsigned int __stdcall
1139 pipeThread(
void *
arg)
1142 int bytes_in_logbuffer = 0;
1150 logbuffer + bytes_in_logbuffer,
1151 sizeof(logbuffer) - bytes_in_logbuffer,
1160 EnterCriticalSection(&sysloggerSection);
1163 DWORD
error = GetLastError();
1165 if (
error == ERROR_HANDLE_EOF ||
1166 error == ERROR_BROKEN_PIPE)
1171 errmsg(
"could not read from logger pipe: %m")));
1173 else if (bytesRead > 0)
1175 bytes_in_logbuffer += bytesRead;
1190 LeaveCriticalSection(&sysloggerSection);
1202 LeaveCriticalSection(&sysloggerSection);
1235 _setmode(_fileno(fh), _O_TEXT);
1240 int save_errno = errno;
1244 errmsg(
"could not open log file \"%s\": %m",
1263 char **last_file_name, FILE **logFile)
1265 char *logFileExt = NULL;
1278 if (*logFile != NULL)
1281 if (*last_file_name != NULL)
1282 pfree(*last_file_name);
1283 *last_file_name = NULL;
1291 if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
1298 logFileExt =
".csv";
1300 logFileExt =
".json";
1317 *last_file_name != NULL &&
1318 strcmp(
filename, *last_file_name) != 0)
1331 if (errno != ENFILE && errno != EMFILE)
1334 (
errmsg(
"disabling automatic rotation (use SIGHUP to re-enable)")));
1344 if (*logFile != NULL)
1349 if (*last_file_name != NULL)
1350 pfree(*last_file_name);
1371 if (time_based_rotation)
1374 fntime = time(NULL);
1459 now -=
now % rotinterval;
1486 errmsg(
"could not remove file \"%s\": %m",
1502 _setmode(_fileno(fh), _O_TEXT);
1509 errmsg(
"could not open file \"%s\": %m",
1520 errmsg(
"could not write file \"%s\": %m",
1533 errmsg(
"could not write file \"%s\": %m",
1546 errmsg(
"could not write file \"%s\": %m",
1557 errmsg(
"could not rename file \"%s\" to \"%s\": %m",
1573 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)