61 #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE)
64 #define LOGROTATE_SIGNAL_FILE "logrotate"
112 #define NBUFFER_LISTS 256
123 static HANDLE threadHandle = 0;
124 static CRITICAL_SECTION sysloggerSection;
135 static int syslogger_fdget(FILE *file);
136 static FILE *syslogger_fdopen(
int fd);
137 static pid_t syslogger_forkexec(
void);
138 static void syslogger_parseArgs(
int argc,
char *argv[]);
147 static unsigned int __stdcall pipeThread(
void *
arg);
149 static void logfile_rotate(
bool time_based_rotation,
int size_rotation_for);
152 int target_dest,
char **last_file_name,
169 int bytes_in_logbuffer = 0;
172 char *currentLogFilename;
173 int currentLogRotationAge;
180 syslogger_parseArgs(argc, argv);
270 InitializeCriticalSection(&sysloggerSection);
271 EnterCriticalSection(&sysloggerSection);
273 threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL);
274 if (threadHandle == 0)
275 elog(
FATAL,
"could not create syslogger data transfer thread: %m");
323 bool time_based_rotation =
false;
324 int size_rotation_for = 0;
350 pfree(currentLogDir);
361 pfree(currentLogFilename);
446 if (!time_based_rotation && size_rotation_for == 0)
472 if (delay > INT_MAX / 1000)
473 delay = INT_MAX / 1000;
474 cur_timeout = delay * 1000L;
487 WAIT_EVENT_SYSLOGGER_MAIN);
494 logbuffer + bytes_in_logbuffer,
495 sizeof(logbuffer) - bytes_in_logbuffer);
501 errmsg(
"could not read from logger pipe: %m")));
503 else if (bytesRead > 0)
505 bytes_in_logbuffer += bytesRead;
534 LeaveCriticalSection(&sysloggerSection);
537 WAIT_EVENT_SYSLOGGER_MAIN);
539 EnterCriticalSection(&sysloggerSection);
598 errmsg(
"could not create pipe for syslog: %m")));
603 SECURITY_ATTRIBUTES
sa;
605 memset(&
sa, 0,
sizeof(SECURITY_ATTRIBUTES));
606 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
607 sa.bInheritHandle = TRUE;
612 errmsg(
"could not create pipe for syslog: %m")));
670 switch ((sysloggerPid = syslogger_forkexec()))
677 (
errmsg(
"could not fork system logger: %m")));
713 (
errmsg(
"redirecting log output to logging collector process"),
714 errhint(
"Future log output will appear in directory \"%s\".",
722 errmsg(
"could not redirect stdout: %m")));
727 errmsg(
"could not redirect stderr: %m")));
740 _O_APPEND | _O_BINARY);
744 errmsg(
"could not redirect stderr: %m")));
771 return (
int) sysloggerPid;
788 syslogger_fdget(FILE *file)
797 return (
int) _get_osfhandle(_fileno(file));
810 syslogger_fdopen(
int fd)
817 file = fdopen(
fd,
"a");
823 fd = _open_osfhandle(
fd, _O_APPEND | _O_TEXT);
826 file = fdopen(
fd,
"a");
841 syslogger_forkexec(
void)
846 char csvfilenobuf[32];
847 char jsonfilenobuf[32];
849 av[ac++] =
"postgres";
850 av[ac++] =
"--forklog";
854 snprintf(filenobuf,
sizeof(filenobuf),
"%d",
856 av[ac++] = filenobuf;
857 snprintf(csvfilenobuf,
sizeof(csvfilenobuf),
"%d",
859 av[ac++] = csvfilenobuf;
860 snprintf(jsonfilenobuf,
sizeof(jsonfilenobuf),
"%d",
862 av[ac++] = jsonfilenobuf;
867 return postmaster_forkexec(ac,
av);
876 syslogger_parseArgs(
int argc,
char *argv[])
932 int count = *bytes_in_logbuffer;
947 if (p.
nuls[0] ==
'\0' && p.
nuls[1] ==
'\0' &&
961 if (count < chunklen)
978 foreach(cell, buffer_list)
987 if (
buf->pid == 0 && free_slot == NULL)
996 if (existing_slot != NULL)
1007 if (free_slot == NULL)
1014 buffer_list =
lappend(buffer_list, free_slot);
1017 free_slot->pid = p.
pid;
1018 str = &(free_slot->data);
1031 if (existing_slot != NULL)
1039 existing_slot->
pid = 0;
1067 for (chunklen = 1; chunklen < count; chunklen++)
1069 if (
cursor[chunklen] ==
'\0')
1080 if (count > 0 &&
cursor != logbuffer)
1081 memmove(logbuffer,
cursor, count);
1082 *bytes_in_logbuffer = count;
1123 if (*bytes_in_logbuffer > 0)
1126 *bytes_in_logbuffer = 0;
1168 rc = fwrite(buffer, 1, count,
logfile);
1189 static unsigned int __stdcall
1190 pipeThread(
void *
arg)
1193 int bytes_in_logbuffer = 0;
1201 logbuffer + bytes_in_logbuffer,
1202 sizeof(logbuffer) - bytes_in_logbuffer,
1211 EnterCriticalSection(&sysloggerSection);
1214 DWORD
error = GetLastError();
1216 if (
error == ERROR_HANDLE_EOF ||
1217 error == ERROR_BROKEN_PIPE)
1222 errmsg(
"could not read from logger pipe: %m")));
1224 else if (bytesRead > 0)
1226 bytes_in_logbuffer += bytesRead;
1241 LeaveCriticalSection(&sysloggerSection);
1253 LeaveCriticalSection(&sysloggerSection);
1286 _setmode(_fileno(fh), _O_TEXT);
1291 int save_errno = errno;
1295 errmsg(
"could not open log file \"%s\": %m",
1314 char **last_file_name, FILE **logFile)
1316 char *logFileExt = NULL;
1329 if (*logFile != NULL)
1332 if (*last_file_name != NULL)
1333 pfree(*last_file_name);
1334 *last_file_name = NULL;
1342 if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
1349 logFileExt =
".csv";
1351 logFileExt =
".json";
1368 *last_file_name != NULL &&
1369 strcmp(
filename, *last_file_name) != 0)
1382 if (errno != ENFILE && errno != EMFILE)
1385 (
errmsg(
"disabling automatic rotation (use SIGHUP to re-enable)")));
1395 if (*logFile != NULL)
1400 if (*last_file_name != NULL)
1401 pfree(*last_file_name);
1422 if (time_based_rotation)
1425 fntime = time(NULL);
1510 now -=
now % rotinterval;
1537 errmsg(
"could not remove file \"%s\": %m",
1553 _setmode(_fileno(fh), _O_TEXT);
1560 errmsg(
"could not open file \"%s\": %m",
1571 errmsg(
"could not write file \"%s\": %m",
1584 errmsg(
"could not write file \"%s\": %m",
1597 errmsg(
"could not write file \"%s\": %m",
1608 errmsg(
"could not rename file \"%s\" to \"%s\": %m",
1624 struct stat stat_buf;
1645 int save_errno = errno;
Datum now(PG_FUNCTION_ARGS)
#define write_stderr(str)
#define pg_attribute_noreturn()
elog(ERROR, "%s: %s", p2, msg)
void dsm_detach_all(void)
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
static void const char fflush(stdout)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
char * pstrdup(const char *in)
void pfree(void *pointer)
void InitPostmasterChild(void)
BackendType MyBackendType
uint64 pg_popcount(const char *buf, int bytes)
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
void ClosePostmasterPorts(bool am_syslogger)
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
NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn()
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 PGSharedMemoryDetach(void)
void _dosmaperr(unsigned long)