PostgreSQL Source Code  git master
syslogger.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include "common/file_perm.h"
#include "lib/stringinfo.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "pgstat.h"
#include "pgtime.h"
#include "port/pg_bitutils.h"
#include "postmaster/fork_process.h"
#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "storage/dsm.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/pg_shmem.h"
#include "tcop/tcopprot.h"
#include "utils/guc.h"
#include "utils/ps_status.h"
#include "utils/timestamp.h"
Include dependency graph for syslogger.c:

Go to the source code of this file.

Data Structures

struct  save_buffer
 

Macros

#define READ_BUF_SIZE   (2 * PIPE_CHUNK_SIZE)
 
#define LOGROTATE_SIGNAL_FILE   "logrotate"
 
#define NBUFFER_LISTS   256
 

Functions

NON_EXEC_STATIC void SysLoggerMain (int argc, char *argv[]) pg_attribute_noreturn()
 
static void process_pipe_input (char *logbuffer, int *bytes_in_logbuffer)
 
static void flush_pipe_input (char *logbuffer, int *bytes_in_logbuffer)
 
static FILE * logfile_open (const char *filename, const char *mode, bool allow_errors)
 
static void logfile_rotate (bool time_based_rotation, int size_rotation_for)
 
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)
 
static char * logfile_getname (pg_time_t timestamp, const char *suffix)
 
static void set_next_rotation_time (void)
 
static void sigUsr1Handler (SIGNAL_ARGS)
 
static void update_metainfo_datafile (void)
 
int SysLogger_Start (void)
 
void write_syslogger_file (const char *buffer, int count, int destination)
 
bool CheckLogrotateSignal (void)
 
void RemoveLogrotateSignalFiles (void)
 

Variables

bool Logging_collector = false
 
int Log_RotationAge = HOURS_PER_DAY * MINS_PER_HOUR
 
int Log_RotationSize = 10 * 1024
 
char * Log_directory = NULL
 
char * Log_filename = NULL
 
bool Log_truncate_on_rotation = false
 
int Log_file_mode = S_IRUSR | S_IWUSR
 
bool redirection_done
 
static pg_time_t next_rotation_time
 
static bool pipe_eof_seen = false
 
static bool rotation_disabled = false
 
static FILE * syslogFile = NULL
 
static FILE * csvlogFile = NULL
 
static FILE * jsonlogFile = NULL
 
NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0
 
static char * last_sys_file_name = NULL
 
static char * last_csv_file_name = NULL
 
static char * last_json_file_name = NULL
 
static Listbuffer_lists [NBUFFER_LISTS]
 
int syslogPipe [2] = {-1, -1}
 
static volatile sig_atomic_t rotation_requested = false
 

Macro Definition Documentation

◆ LOGROTATE_SIGNAL_FILE

#define LOGROTATE_SIGNAL_FILE   "logrotate"

Definition at line 64 of file syslogger.c.

◆ NBUFFER_LISTS

#define NBUFFER_LISTS   256

Definition at line 112 of file syslogger.c.

◆ READ_BUF_SIZE

#define READ_BUF_SIZE   (2 * PIPE_CHUNK_SIZE)

Definition at line 61 of file syslogger.c.

Function Documentation

◆ CheckLogrotateSignal()

bool CheckLogrotateSignal ( void  )

Definition at line 1622 of file syslogger.c.

1623 {
1624  struct stat stat_buf;
1625 
1626  if (stat(LOGROTATE_SIGNAL_FILE, &stat_buf) == 0)
1627  return true;
1628 
1629  return false;
1630 }
#define LOGROTATE_SIGNAL_FILE
Definition: syslogger.c:64
#define stat
Definition: win32_port.h:292

References LOGROTATE_SIGNAL_FILE, and stat.

Referenced by process_pm_pmsignal().

◆ flush_pipe_input()

static void flush_pipe_input ( char *  logbuffer,
int *  bytes_in_logbuffer 
)
static

Definition at line 1092 of file syslogger.c.

1093 {
1094  int i;
1095 
1096  /* Dump any incomplete protocol messages */
1097  for (i = 0; i < NBUFFER_LISTS; i++)
1098  {
1099  List *list = buffer_lists[i];
1100  ListCell *cell;
1101 
1102  foreach(cell, list)
1103  {
1104  save_buffer *buf = (save_buffer *) lfirst(cell);
1105 
1106  if (buf->pid != 0)
1107  {
1108  StringInfo str = &(buf->data);
1109 
1110  write_syslogger_file(str->data, str->len,
1112  /* Mark the buffer unused, and reclaim string storage */
1113  buf->pid = 0;
1114  pfree(str->data);
1115  }
1116  }
1117  }
1118 
1119  /*
1120  * Force out any remaining pipe data as-is; we don't bother trying to
1121  * remove any protocol headers that may exist in it.
1122  */
1123  if (*bytes_in_logbuffer > 0)
1124  write_syslogger_file(logbuffer, *bytes_in_logbuffer,
1126  *bytes_in_logbuffer = 0;
1127 }
#define LOG_DESTINATION_STDERR
Definition: elog.h:492
int i
Definition: isn.c:73
void pfree(void *pointer)
Definition: mcxt.c:1456
#define lfirst(lc)
Definition: pg_list.h:172
static char * buf
Definition: pg_test_fsync.c:67
Definition: pg_list.h:54
#define NBUFFER_LISTS
Definition: syslogger.c:112
void write_syslogger_file(const char *buffer, int count, int destination)
Definition: syslogger.c:1143
static List * buffer_lists[NBUFFER_LISTS]
Definition: syslogger.c:113

References buf, buffer_lists, i, lfirst, sort-test::list, LOG_DESTINATION_STDERR, NBUFFER_LISTS, pfree(), generate_unaccent_rules::str, and write_syslogger_file().

Referenced by SysLoggerMain().

◆ logfile_getname()

static char * logfile_getname ( pg_time_t  timestamp,
const char *  suffix 
)
static

Definition at line 1460 of file syslogger.c.

1461 {
1462  char *filename;
1463  int len;
1464 
1466 
1468 
1469  len = strlen(filename);
1470 
1471  /* treat Log_filename as a strftime pattern */
1474 
1475  if (suffix != NULL)
1476  {
1477  len = strlen(filename);
1478  if (len > 4 && (strcmp(filename + (len - 4), ".log") == 0))
1479  len -= 4;
1480  strlcpy(filename + len, suffix, MAXPGPATH - len);
1481  }
1482 
1483  return filename;
1484 }
void * palloc(Size size)
Definition: mcxt.c:1226
#define MAXPGPATH
const void size_t len
static char * filename
Definition: pg_dumpall.c:119
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1344
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
Definition: strftime.c:128
PGDLLIMPORT pg_tz * log_timezone
Definition: pgtz.c:31
int64 timestamp
#define snprintf
Definition: port.h:238
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * Log_directory
Definition: syslogger.c:74
char * Log_filename
Definition: syslogger.c:75

References filename, len, Log_directory, Log_filename, log_timezone, MAXPGPATH, palloc(), pg_localtime(), pg_strftime(), snprintf, and strlcpy().

Referenced by logfile_rotate_dest(), SysLogger_Start(), and SysLoggerMain().

◆ logfile_open()

static FILE * logfile_open ( const char *  filename,
const char *  mode,
bool  allow_errors 
)
static

Definition at line 1267 of file syslogger.c.

1268 {
1269  FILE *fh;
1270  mode_t oumask;
1271 
1272  /*
1273  * Note we do not let Log_file_mode disable IWUSR, since we certainly want
1274  * to be able to write the files ourselves.
1275  */
1276  oumask = umask((mode_t) ((~(Log_file_mode | S_IWUSR)) & (S_IRWXU | S_IRWXG | S_IRWXO)));
1277  fh = fopen(filename, mode);
1278  umask(oumask);
1279 
1280  if (fh)
1281  {
1282  setvbuf(fh, NULL, PG_IOLBF, 0);
1283 
1284 #ifdef WIN32
1285  /* use CRLF line endings on Windows */
1286  _setmode(_fileno(fh), _O_TEXT);
1287 #endif
1288  }
1289  else
1290  {
1291  int save_errno = errno;
1292 
1293  ereport(allow_errors ? LOG : FATAL,
1295  errmsg("could not open log file \"%s\": %m",
1296  filename)));
1297  errno = save_errno;
1298  }
1299 
1300  return fh;
1301 }
int errcode_for_file_access(void)
Definition: elog.c:881
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define ereport(elevel,...)
Definition: elog.h:149
static PgChecksumMode mode
Definition: pg_checksums.c:65
#define PG_IOLBF
Definition: port.h:361
int Log_file_mode
Definition: syslogger.c:77
#define S_IRWXG
Definition: win32_port.h:318
#define S_IRWXO
Definition: win32_port.h:330
#define S_IWUSR
Definition: win32_port.h:300
#define S_IRWXU
Definition: win32_port.h:306

References ereport, errcode_for_file_access(), errmsg(), FATAL, filename, LOG, Log_file_mode, mode, PG_IOLBF, S_IRWXG, S_IRWXO, S_IRWXU, and S_IWUSR.

Referenced by logfile_rotate_dest(), and SysLogger_Start().

◆ logfile_rotate()

static void logfile_rotate ( bool  time_based_rotation,
int  size_rotation_for 
)
static

Definition at line 1411 of file syslogger.c.

1412 {
1413  pg_time_t fntime;
1414 
1415  rotation_requested = false;
1416 
1417  /*
1418  * When doing a time-based rotation, invent the new logfile name based on
1419  * the planned rotation time, not current time, to avoid "slippage" in the
1420  * file name when we don't do the rotation immediately.
1421  */
1422  if (time_based_rotation)
1423  fntime = next_rotation_time;
1424  else
1425  fntime = time(NULL);
1426 
1427  /* file rotation for stderr */
1428  if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
1430  &syslogFile))
1431  return;
1432 
1433  /* file rotation for csvlog */
1434  if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
1436  &csvlogFile))
1437  return;
1438 
1439  /* file rotation for jsonlog */
1440  if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
1442  &jsonlogFile))
1443  return;
1444 
1446 
1448 }
#define LOG_DESTINATION_JSONLOG
Definition: elog.h:496
#define LOG_DESTINATION_CSVLOG
Definition: elog.h:495
int64 pg_time_t
Definition: pgtime.h:23
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)
Definition: syslogger.c:1312
static void update_metainfo_datafile(void)
Definition: syslogger.c:1525
static char * last_csv_file_name
Definition: syslogger.c:92
static FILE * syslogFile
Definition: syslogger.c:87
static pg_time_t next_rotation_time
Definition: syslogger.c:84
static volatile sig_atomic_t rotation_requested
Definition: syslogger.c:130
static FILE * csvlogFile
Definition: syslogger.c:88
static void set_next_rotation_time(void)
Definition: syslogger.c:1490
static FILE * jsonlogFile
Definition: syslogger.c:89
static char * last_json_file_name
Definition: syslogger.c:93
static char * last_sys_file_name
Definition: syslogger.c:91

References csvlogFile, jsonlogFile, last_csv_file_name, last_json_file_name, last_sys_file_name, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, LOG_DESTINATION_STDERR, logfile_rotate_dest(), next_rotation_time, rotation_requested, set_next_rotation_time(), syslogFile, and update_metainfo_datafile().

Referenced by SysLoggerMain().

◆ logfile_rotate_dest()

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 
)
static

Definition at line 1312 of file syslogger.c.

1315 {
1316  char *logFileExt = NULL;
1317  char *filename;
1318  FILE *fh;
1319 
1320  /*
1321  * If the target destination was just turned off, close the previous file
1322  * and unregister its data. This cannot happen for stderr as syslogFile
1323  * is assumed to be always opened even if stderr is disabled in
1324  * log_destination.
1325  */
1326  if ((Log_destination & target_dest) == 0 &&
1327  target_dest != LOG_DESTINATION_STDERR)
1328  {
1329  if (*logFile != NULL)
1330  fclose(*logFile);
1331  *logFile = NULL;
1332  if (*last_file_name != NULL)
1333  pfree(*last_file_name);
1334  *last_file_name = NULL;
1335  return true;
1336  }
1337 
1338  /*
1339  * Leave if it is not time for a rotation or if the target destination has
1340  * no need to do a rotation based on the size of its file.
1341  */
1342  if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
1343  return true;
1344 
1345  /* file extension depends on the destination type */
1346  if (target_dest == LOG_DESTINATION_STDERR)
1347  logFileExt = NULL;
1348  else if (target_dest == LOG_DESTINATION_CSVLOG)
1349  logFileExt = ".csv";
1350  else if (target_dest == LOG_DESTINATION_JSONLOG)
1351  logFileExt = ".json";
1352  else
1353  {
1354  /* cannot happen */
1355  Assert(false);
1356  }
1357 
1358  /* build the new file name */
1359  filename = logfile_getname(fntime, logFileExt);
1360 
1361  /*
1362  * Decide whether to overwrite or append. We can overwrite if (a)
1363  * Log_truncate_on_rotation is set, (b) the rotation was triggered by
1364  * elapsed time and not something else, and (c) the computed file name is
1365  * different from what we were previously logging into.
1366  */
1367  if (Log_truncate_on_rotation && time_based_rotation &&
1368  *last_file_name != NULL &&
1369  strcmp(filename, *last_file_name) != 0)
1370  fh = logfile_open(filename, "w", true);
1371  else
1372  fh = logfile_open(filename, "a", true);
1373 
1374  if (!fh)
1375  {
1376  /*
1377  * ENFILE/EMFILE are not too surprising on a busy system; just keep
1378  * using the old file till we manage to get a new one. Otherwise,
1379  * assume something's wrong with Log_directory and stop trying to
1380  * create files.
1381  */
1382  if (errno != ENFILE && errno != EMFILE)
1383  {
1384  ereport(LOG,
1385  (errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
1386  rotation_disabled = true;
1387  }
1388 
1389  if (filename)
1390  pfree(filename);
1391  return false;
1392  }
1393 
1394  /* fill in the new information */
1395  if (*logFile != NULL)
1396  fclose(*logFile);
1397  *logFile = fh;
1398 
1399  /* instead of pfree'ing filename, remember it for next time */
1400  if (*last_file_name != NULL)
1401  pfree(*last_file_name);
1402  *last_file_name = filename;
1403 
1404  return true;
1405 }
int Log_destination
Definition: elog.c:113
Assert(fmt[strlen(fmt) - 1] !='\n')
bool Log_truncate_on_rotation
Definition: syslogger.c:76
static bool rotation_disabled
Definition: syslogger.c:86
static char * logfile_getname(pg_time_t timestamp, const char *suffix)
Definition: syslogger.c:1460
static FILE * logfile_open(const char *filename, const char *mode, bool allow_errors)
Definition: syslogger.c:1267

References Assert(), ereport, errmsg(), filename, LOG, Log_destination, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, LOG_DESTINATION_STDERR, Log_truncate_on_rotation, logfile_getname(), logfile_open(), pfree(), and rotation_disabled.

Referenced by logfile_rotate().

◆ process_pipe_input()

static void process_pipe_input ( char *  logbuffer,
int *  bytes_in_logbuffer 
)
static

Definition at line 929 of file syslogger.c.

930 {
931  char *cursor = logbuffer;
932  int count = *bytes_in_logbuffer;
934 
935  /* While we have enough for a header, process data... */
936  while (count >= (int) (offsetof(PipeProtoHeader, data) + 1))
937  {
938  PipeProtoHeader p;
939  int chunklen;
940  bits8 dest_flags;
941 
942  /* Do we have a valid header? */
943  memcpy(&p, cursor, offsetof(PipeProtoHeader, data));
944  dest_flags = p.flags & (PIPE_PROTO_DEST_STDERR |
947  if (p.nuls[0] == '\0' && p.nuls[1] == '\0' &&
948  p.len > 0 && p.len <= PIPE_MAX_PAYLOAD &&
949  p.pid != 0 &&
950  pg_popcount((char *) &dest_flags, 1) == 1)
951  {
952  List *buffer_list;
953  ListCell *cell;
954  save_buffer *existing_slot = NULL,
955  *free_slot = NULL;
956  StringInfo str;
957 
958  chunklen = PIPE_HEADER_SIZE + p.len;
959 
960  /* Fall out of loop if we don't have the whole chunk yet */
961  if (count < chunklen)
962  break;
963 
964  if ((p.flags & PIPE_PROTO_DEST_STDERR) != 0)
966  else if ((p.flags & PIPE_PROTO_DEST_CSVLOG) != 0)
968  else if ((p.flags & PIPE_PROTO_DEST_JSONLOG) != 0)
970  else
971  {
972  /* this should never happen as of the header validation */
973  Assert(false);
974  }
975 
976  /* Locate any existing buffer for this source pid */
977  buffer_list = buffer_lists[p.pid % NBUFFER_LISTS];
978  foreach(cell, buffer_list)
979  {
980  save_buffer *buf = (save_buffer *) lfirst(cell);
981 
982  if (buf->pid == p.pid)
983  {
984  existing_slot = buf;
985  break;
986  }
987  if (buf->pid == 0 && free_slot == NULL)
988  free_slot = buf;
989  }
990 
991  if ((p.flags & PIPE_PROTO_IS_LAST) == 0)
992  {
993  /*
994  * Save a complete non-final chunk in a per-pid buffer
995  */
996  if (existing_slot != NULL)
997  {
998  /* Add chunk to data from preceding chunks */
999  str = &(existing_slot->data);
1002  p.len);
1003  }
1004  else
1005  {
1006  /* First chunk of message, save in a new buffer */
1007  if (free_slot == NULL)
1008  {
1009  /*
1010  * Need a free slot, but there isn't one in the list,
1011  * so create a new one and extend the list with it.
1012  */
1013  free_slot = palloc(sizeof(save_buffer));
1014  buffer_list = lappend(buffer_list, free_slot);
1015  buffer_lists[p.pid % NBUFFER_LISTS] = buffer_list;
1016  }
1017  free_slot->pid = p.pid;
1018  str = &(free_slot->data);
1022  p.len);
1023  }
1024  }
1025  else
1026  {
1027  /*
1028  * Final chunk --- add it to anything saved for that pid, and
1029  * either way write the whole thing out.
1030  */
1031  if (existing_slot != NULL)
1032  {
1033  str = &(existing_slot->data);
1036  p.len);
1037  write_syslogger_file(str->data, str->len, dest);
1038  /* Mark the buffer unused, and reclaim string storage */
1039  existing_slot->pid = 0;
1040  pfree(str->data);
1041  }
1042  else
1043  {
1044  /* The whole message was one chunk, evidently. */
1046  dest);
1047  }
1048  }
1049 
1050  /* Finished processing this chunk */
1051  cursor += chunklen;
1052  count -= chunklen;
1053  }
1054  else
1055  {
1056  /* Process non-protocol data */
1057 
1058  /*
1059  * Look for the start of a protocol header. If found, dump data
1060  * up to there and repeat the loop. Otherwise, dump it all and
1061  * fall out of the loop. (Note: we want to dump it all if at all
1062  * possible, so as to avoid dividing non-protocol messages across
1063  * logfiles. We expect that in many scenarios, a non-protocol
1064  * message will arrive all in one read(), and we want to respect
1065  * the read() boundary if possible.)
1066  */
1067  for (chunklen = 1; chunklen < count; chunklen++)
1068  {
1069  if (cursor[chunklen] == '\0')
1070  break;
1071  }
1072  /* fall back on the stderr log as the destination */
1074  cursor += chunklen;
1075  count -= chunklen;
1076  }
1077  }
1078 
1079  /* We don't have a full chunk, so left-align what remains in the buffer */
1080  if (count > 0 && cursor != logbuffer)
1081  memmove(logbuffer, cursor, count);
1082  *bytes_in_logbuffer = count;
1083 }
uint8 bits8
Definition: c.h:497
List * lappend(List *list, void *datum)
Definition: list.c:338
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:296
const void * data
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:227
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char nuls[2]
Definition: syslogger.h:46
Definition: type.h:137
StringInfoData data
Definition: syslogger.c:109
int32 pid
Definition: syslogger.c:108
#define PIPE_PROTO_DEST_JSONLOG
Definition: syslogger.h:67
#define PIPE_PROTO_IS_LAST
Definition: syslogger.h:63
#define PIPE_PROTO_DEST_CSVLOG
Definition: syslogger.h:66
#define PIPE_PROTO_DEST_STDERR
Definition: syslogger.h:65
#define PIPE_MAX_PAYLOAD
Definition: syslogger.h:60
#define PIPE_HEADER_SIZE
Definition: syslogger.h:59

References appendBinaryStringInfo(), Assert(), buf, buffer_lists, save_buffer::data, data, generate_unaccent_rules::dest, PipeProtoHeader::flags, initStringInfo(), lappend(), PipeProtoHeader::len, lfirst, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, LOG_DESTINATION_STDERR, NBUFFER_LISTS, PipeProtoHeader::nuls, palloc(), pfree(), pg_popcount(), save_buffer::pid, PipeProtoHeader::pid, PIPE_HEADER_SIZE, PIPE_MAX_PAYLOAD, PIPE_PROTO_DEST_CSVLOG, PIPE_PROTO_DEST_JSONLOG, PIPE_PROTO_DEST_STDERR, PIPE_PROTO_IS_LAST, generate_unaccent_rules::str, and write_syslogger_file().

Referenced by SysLoggerMain().

◆ RemoveLogrotateSignalFiles()

void RemoveLogrotateSignalFiles ( void  )

Definition at line 1636 of file syslogger.c.

1637 {
1638  unlink(LOGROTATE_SIGNAL_FILE);
1639 }

References LOGROTATE_SIGNAL_FILE.

Referenced by PostmasterMain(), and process_pm_pmsignal().

◆ set_next_rotation_time()

static void set_next_rotation_time ( void  )
static

Definition at line 1490 of file syslogger.c.

1491 {
1492  pg_time_t now;
1493  struct pg_tm *tm;
1494  int rotinterval;
1495 
1496  /* nothing to do if time-based rotation is disabled */
1497  if (Log_RotationAge <= 0)
1498  return;
1499 
1500  /*
1501  * The requirements here are to choose the next time > now that is a
1502  * "multiple" of the log rotation interval. "Multiple" can be interpreted
1503  * fairly loosely. In this version we align to log_timezone rather than
1504  * GMT.
1505  */
1506  rotinterval = Log_RotationAge * SECS_PER_MINUTE; /* convert to seconds */
1507  now = (pg_time_t) time(NULL);
1509  now += tm->tm_gmtoff;
1510  now -= now % rotinterval;
1511  now += rotinterval;
1512  now -= tm->tm_gmtoff;
1514 }
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1547
#define SECS_PER_MINUTE
Definition: timestamp.h:127
static struct pg_tm tm
Definition: localtime.c:104
Definition: pgtime.h:35
long int tm_gmtoff
Definition: pgtime.h:45
int Log_RotationAge
Definition: syslogger.c:72

References Log_RotationAge, log_timezone, next_rotation_time, now(), pg_localtime(), SECS_PER_MINUTE, tm, and pg_tm::tm_gmtoff.

Referenced by logfile_rotate(), and SysLoggerMain().

◆ sigUsr1Handler()

static void sigUsr1Handler ( SIGNAL_ARGS  )
static

Definition at line 1643 of file syslogger.c.

1644 {
1645  int save_errno = errno;
1646 
1647  rotation_requested = true;
1648  SetLatch(MyLatch);
1649 
1650  errno = save_errno;
1651 }
struct Latch * MyLatch
Definition: globals.c:58
void SetLatch(Latch *latch)
Definition: latch.c:607

References MyLatch, rotation_requested, and SetLatch().

Referenced by SysLoggerMain().

◆ SysLogger_Start()

int SysLogger_Start ( void  )

Definition at line 567 of file syslogger.c.

568 {
569  pid_t sysloggerPid;
570  char *filename;
571 
572  if (!Logging_collector)
573  return 0;
574 
575  /*
576  * If first time through, create the pipe which will receive stderr
577  * output.
578  *
579  * If the syslogger crashes and needs to be restarted, we continue to use
580  * the same pipe (indeed must do so, since extant backends will be writing
581  * into that pipe).
582  *
583  * This means the postmaster must continue to hold the read end of the
584  * pipe open, so we can pass it down to the reincarnated syslogger. This
585  * is a bit klugy but we have little choice.
586  *
587  * Also note that we don't bother counting the pipe FDs by calling
588  * Reserve/ReleaseExternalFD. There's no real need to account for them
589  * accurately in the postmaster or syslogger process, and both ends of the
590  * pipe will wind up closed in all other postmaster children.
591  */
592 #ifndef WIN32
593  if (syslogPipe[0] < 0)
594  {
595  if (pipe(syslogPipe) < 0)
596  ereport(FATAL,
598  errmsg("could not create pipe for syslog: %m")));
599  }
600 #else
601  if (!syslogPipe[0])
602  {
603  SECURITY_ATTRIBUTES sa;
604 
605  memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
606  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
607  sa.bInheritHandle = TRUE;
608 
609  if (!CreatePipe(&syslogPipe[0], &syslogPipe[1], &sa, 32768))
610  ereport(FATAL,
612  errmsg("could not create pipe for syslog: %m")));
613  }
614 #endif
615 
616  /*
617  * Create log directory if not present; ignore errors
618  */
620 
621  /*
622  * The initial logfile is created right in the postmaster, to verify that
623  * the Log_directory is writable. We save the reference time so that the
624  * syslogger child process can recompute this file name.
625  *
626  * It might look a bit strange to re-do this during a syslogger restart,
627  * but we must do so since the postmaster closed syslogFile after the
628  * previous fork (and remembering that old file wouldn't be right anyway).
629  * Note we always append here, we won't overwrite any existing file. This
630  * is consistent with the normal rules, because by definition this is not
631  * a time-based rotation.
632  */
633  first_syslogger_file_time = time(NULL);
634 
636 
637  syslogFile = logfile_open(filename, "a", false);
638 
639  pfree(filename);
640 
641  /*
642  * Likewise for the initial CSV log file, if that's enabled. (Note that
643  * we open syslogFile even when only CSV output is nominally enabled,
644  * since some code paths will write to syslogFile anyway.)
645  */
647  {
649 
650  csvlogFile = logfile_open(filename, "a", false);
651 
652  pfree(filename);
653  }
654 
655  /*
656  * Likewise for the initial JSON log file, if that's enabled. (Note that
657  * we open syslogFile even when only JSON output is nominally enabled,
658  * since some code paths will write to syslogFile anyway.)
659  */
661  {
663 
664  jsonlogFile = logfile_open(filename, "a", false);
665 
666  pfree(filename);
667  }
668 
669 #ifdef EXEC_BACKEND
670  switch ((sysloggerPid = syslogger_forkexec()))
671 #else
672  switch ((sysloggerPid = fork_process()))
673 #endif
674  {
675  case -1:
676  ereport(LOG,
677  (errmsg("could not fork system logger: %m")));
678  return 0;
679 
680 #ifndef EXEC_BACKEND
681  case 0:
682  /* in postmaster child ... */
684 
685  /* Close the postmaster's sockets */
686  ClosePostmasterPorts(true);
687 
688  /* Drop our connection to postmaster's shared memory, as well */
689  dsm_detach_all();
691 
692  /* do the work */
693  SysLoggerMain(0, NULL);
694  break;
695 #endif
696 
697  default:
698  /* success, in postmaster */
699 
700  /* now we redirect stderr, if not done already */
701  if (!redirection_done)
702  {
703 #ifdef WIN32
704  int fd;
705 #endif
706 
707  /*
708  * Leave a breadcrumb trail when redirecting, in case the user
709  * forgets that redirection is active and looks only at the
710  * original stderr target file.
711  */
712  ereport(LOG,
713  (errmsg("redirecting log output to logging collector process"),
714  errhint("Future log output will appear in directory \"%s\".",
715  Log_directory)));
716 
717 #ifndef WIN32
718  fflush(stdout);
719  if (dup2(syslogPipe[1], STDOUT_FILENO) < 0)
720  ereport(FATAL,
722  errmsg("could not redirect stdout: %m")));
723  fflush(stderr);
724  if (dup2(syslogPipe[1], STDERR_FILENO) < 0)
725  ereport(FATAL,
727  errmsg("could not redirect stderr: %m")));
728  /* Now we are done with the write end of the pipe. */
729  close(syslogPipe[1]);
730  syslogPipe[1] = -1;
731 #else
732 
733  /*
734  * open the pipe in binary mode and make sure stderr is binary
735  * after it's been dup'ed into, to avoid disturbing the pipe
736  * chunking protocol.
737  */
738  fflush(stderr);
739  fd = _open_osfhandle((intptr_t) syslogPipe[1],
740  _O_APPEND | _O_BINARY);
741  if (dup2(fd, STDERR_FILENO) < 0)
742  ereport(FATAL,
744  errmsg("could not redirect stderr: %m")));
745  close(fd);
746  _setmode(STDERR_FILENO, _O_BINARY);
747 
748  /*
749  * Now we are done with the write end of the pipe.
750  * CloseHandle() must not be called because the preceding
751  * close() closes the underlying handle.
752  */
753  syslogPipe[1] = 0;
754 #endif
755  redirection_done = true;
756  }
757 
758  /* postmaster will never write the file(s); close 'em */
759  fclose(syslogFile);
760  syslogFile = NULL;
761  if (csvlogFile != NULL)
762  {
763  fclose(csvlogFile);
764  csvlogFile = NULL;
765  }
766  if (jsonlogFile != NULL)
767  {
768  fclose(jsonlogFile);
769  jsonlogFile = NULL;
770  }
771  return (int) sysloggerPid;
772  }
773 
774  /* we should never reach here */
775  return 0;
776 }
void dsm_detach_all(void)
Definition: dsm.c:748
int errcode_for_socket_access(void)
Definition: elog.c:952
int errhint(const char *fmt,...)
Definition: elog.c:1316
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3810
pid_t fork_process(void)
Definition: fork_process.c:32
#define close(a)
Definition: win32.h:12
static void const char fflush(stdout)
void InitPostmasterChild(void)
Definition: miscinit.c:95
void ClosePostmasterPorts(bool am_syslogger)
Definition: postmaster.c:2574
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool redirection_done
Definition: postmaster.c:359
NON_EXEC_STATIC pg_time_t first_syslogger_file_time
Definition: syslogger.c:90
int syslogPipe[2]
Definition: syslogger.c:117
bool Logging_collector
Definition: syslogger.c:71
NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn()
Definition: syslogger.c:165
void PGSharedMemoryDetach(void)
Definition: sysv_shmem.c:955
#define STDOUT_FILENO
Definition: unistd.h:8
#define STDERR_FILENO
Definition: unistd.h:9

References close, ClosePostmasterPorts(), csvlogFile, dsm_detach_all(), ereport, errcode_for_file_access(), errcode_for_socket_access(), errhint(), errmsg(), FATAL, fd(), fflush(), filename, first_syslogger_file_time, fork_process(), InitPostmasterChild(), jsonlogFile, LOG, Log_destination, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, Log_directory, logfile_getname(), logfile_open(), Logging_collector, MakePGDirectory(), pfree(), PGSharedMemoryDetach(), redirection_done, STDERR_FILENO, generate_unaccent_rules::stdout, STDOUT_FILENO, syslogFile, SysLoggerMain(), and syslogPipe.

Referenced by PostmasterMain(), process_pm_child_exit(), and ServerLoop().

◆ SysLoggerMain()

NON_EXEC_STATIC void SysLoggerMain ( int  argc,
char *  argv[] 
)

Definition at line 165 of file syslogger.c.

166 {
167 #ifndef WIN32
168  char logbuffer[READ_BUF_SIZE];
169  int bytes_in_logbuffer = 0;
170 #endif
171  char *currentLogDir;
172  char *currentLogFilename;
173  int currentLogRotationAge;
174  pg_time_t now;
175  WaitEventSet *wes;
176 
177  now = MyStartTime;
178 
179 #ifdef EXEC_BACKEND
180  syslogger_parseArgs(argc, argv);
181 #endif /* EXEC_BACKEND */
182 
184  init_ps_display(NULL);
185 
186  /*
187  * If we restarted, our stderr is already redirected into our own input
188  * pipe. This is of course pretty useless, not to mention that it
189  * interferes with detecting pipe EOF. Point stderr to /dev/null. This
190  * assumes that all interesting messages generated in the syslogger will
191  * come through elog.c and will be sent to write_syslogger_file.
192  */
193  if (redirection_done)
194  {
195  int fd = open(DEVNULL, O_WRONLY, 0);
196 
197  /*
198  * The closes might look redundant, but they are not: we want to be
199  * darn sure the pipe gets closed even if the open failed. We can
200  * survive running with stderr pointing nowhere, but we can't afford
201  * to have extra pipe input descriptors hanging around.
202  *
203  * As we're just trying to reset these to go to DEVNULL, there's not
204  * much point in checking for failure from the close/dup2 calls here,
205  * if they fail then presumably the file descriptors are closed and
206  * any writes will go into the bitbucket anyway.
207  */
210  if (fd != -1)
211  {
212  (void) dup2(fd, STDOUT_FILENO);
213  (void) dup2(fd, STDERR_FILENO);
214  close(fd);
215  }
216  }
217 
218  /*
219  * Syslogger's own stderr can't be the syslogPipe, so set it back to text
220  * mode if we didn't just close it. (It was set to binary in
221  * SubPostmasterMain).
222  */
223 #ifdef WIN32
224  else
225  _setmode(STDERR_FILENO, _O_TEXT);
226 #endif
227 
228  /*
229  * Also close our copy of the write end of the pipe. This is needed to
230  * ensure we can detect pipe EOF correctly. (But note that in the restart
231  * case, the postmaster already did this.)
232  */
233 #ifndef WIN32
234  if (syslogPipe[1] >= 0)
235  close(syslogPipe[1]);
236  syslogPipe[1] = -1;
237 #else
238  if (syslogPipe[1])
239  CloseHandle(syslogPipe[1]);
240  syslogPipe[1] = 0;
241 #endif
242 
243  /*
244  * Properly accept or ignore signals the postmaster might send us
245  *
246  * Note: we ignore all termination signals, and instead exit only when all
247  * upstream processes are gone, to ensure we don't miss any dying gasps of
248  * broken backends...
249  */
250 
251  pqsignal(SIGHUP, SignalHandlerForConfigReload); /* set flag to read config
252  * file */
253  pqsignal(SIGINT, SIG_IGN);
254  pqsignal(SIGTERM, SIG_IGN);
258  pqsignal(SIGUSR1, sigUsr1Handler); /* request log rotation */
260 
261  /*
262  * Reset some signals that are accepted by postmaster but not here
263  */
265 
266  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
267 
268 #ifdef WIN32
269  /* Fire up separate data transfer thread */
270  InitializeCriticalSection(&sysloggerSection);
271  EnterCriticalSection(&sysloggerSection);
272 
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");
276 #endif /* WIN32 */
277 
278  /*
279  * Remember active logfiles' name(s). We recompute 'em from the reference
280  * time because passing down just the pg_time_t is a lot cheaper than
281  * passing a whole file path in the EXEC_BACKEND case.
282  */
284  if (csvlogFile != NULL)
286  if (jsonlogFile != NULL)
288 
289  /* remember active logfile parameters */
290  currentLogDir = pstrdup(Log_directory);
291  currentLogFilename = pstrdup(Log_filename);
292  currentLogRotationAge = Log_RotationAge;
293  /* set next planned rotation time */
296 
297  /*
298  * Reset whereToSendOutput, as the postmaster will do (but hasn't yet, at
299  * the point where we forked). This prevents duplicate output of messages
300  * from syslogger itself.
301  */
303 
304  /*
305  * Set up a reusable WaitEventSet object we'll use to wait for our latch,
306  * and (except on Windows) our socket.
307  *
308  * Unlike all other postmaster child processes, we'll ignore postmaster
309  * death because we want to collect final log output from all backends and
310  * then exit last. We'll do that by running until we see EOF on the
311  * syslog pipe, which implies that all other backends have exited
312  * (including the postmaster).
313  */
316 #ifndef WIN32
317  AddWaitEventToSet(wes, WL_SOCKET_READABLE, syslogPipe[0], NULL, NULL);
318 #endif
319 
320  /* main worker loop */
321  for (;;)
322  {
323  bool time_based_rotation = false;
324  int size_rotation_for = 0;
325  long cur_timeout;
326  WaitEvent event;
327 
328 #ifndef WIN32
329  int rc;
330 #endif
331 
332  /* Clear any already-pending wakeups */
334 
335  /*
336  * Process any requests or signals received recently.
337  */
339  {
340  ConfigReloadPending = false;
342 
343  /*
344  * Check if the log directory or filename pattern changed in
345  * postgresql.conf. If so, force rotation to make sure we're
346  * writing the logfiles in the right place.
347  */
348  if (strcmp(Log_directory, currentLogDir) != 0)
349  {
350  pfree(currentLogDir);
351  currentLogDir = pstrdup(Log_directory);
352  rotation_requested = true;
353 
354  /*
355  * Also, create new directory if not present; ignore errors
356  */
358  }
359  if (strcmp(Log_filename, currentLogFilename) != 0)
360  {
361  pfree(currentLogFilename);
362  currentLogFilename = pstrdup(Log_filename);
363  rotation_requested = true;
364  }
365 
366  /*
367  * Force a rotation if CSVLOG output was just turned on or off and
368  * we need to open or close csvlogFile accordingly.
369  */
370  if (((Log_destination & LOG_DESTINATION_CSVLOG) != 0) !=
371  (csvlogFile != NULL))
372  rotation_requested = true;
373 
374  /*
375  * Force a rotation if JSONLOG output was just turned on or off
376  * and we need to open or close jsonlogFile accordingly.
377  */
378  if (((Log_destination & LOG_DESTINATION_JSONLOG) != 0) !=
379  (jsonlogFile != NULL))
380  rotation_requested = true;
381 
382  /*
383  * If rotation time parameter changed, reset next rotation time,
384  * but don't immediately force a rotation.
385  */
386  if (currentLogRotationAge != Log_RotationAge)
387  {
388  currentLogRotationAge = Log_RotationAge;
390  }
391 
392  /*
393  * If we had a rotation-disabling failure, re-enable rotation
394  * attempts after SIGHUP, and force one immediately.
395  */
396  if (rotation_disabled)
397  {
398  rotation_disabled = false;
399  rotation_requested = true;
400  }
401 
402  /*
403  * Force rewriting last log filename when reloading configuration.
404  * Even if rotation_requested is false, log_destination may have
405  * been changed and we don't want to wait the next file rotation.
406  */
408  }
409 
411  {
412  /* Do a logfile rotation if it's time */
413  now = (pg_time_t) time(NULL);
414  if (now >= next_rotation_time)
415  rotation_requested = time_based_rotation = true;
416  }
417 
419  {
420  /* Do a rotation if file is too big */
421  if (ftell(syslogFile) >= Log_RotationSize * 1024L)
422  {
423  rotation_requested = true;
424  size_rotation_for |= LOG_DESTINATION_STDERR;
425  }
426  if (csvlogFile != NULL &&
427  ftell(csvlogFile) >= Log_RotationSize * 1024L)
428  {
429  rotation_requested = true;
430  size_rotation_for |= LOG_DESTINATION_CSVLOG;
431  }
432  if (jsonlogFile != NULL &&
433  ftell(jsonlogFile) >= Log_RotationSize * 1024L)
434  {
435  rotation_requested = true;
436  size_rotation_for |= LOG_DESTINATION_JSONLOG;
437  }
438  }
439 
440  if (rotation_requested)
441  {
442  /*
443  * Force rotation when both values are zero. It means the request
444  * was sent by pg_rotate_logfile() or "pg_ctl logrotate".
445  */
446  if (!time_based_rotation && size_rotation_for == 0)
447  size_rotation_for = LOG_DESTINATION_STDERR |
450  logfile_rotate(time_based_rotation, size_rotation_for);
451  }
452 
453  /*
454  * Calculate time till next time-based rotation, so that we don't
455  * sleep longer than that. We assume the value of "now" obtained
456  * above is still close enough. Note we can't make this calculation
457  * until after calling logfile_rotate(), since it will advance
458  * next_rotation_time.
459  *
460  * Also note that we need to beware of overflow in calculation of the
461  * timeout: with large settings of Log_RotationAge, next_rotation_time
462  * could be more than INT_MAX msec in the future. In that case we'll
463  * wait no more than INT_MAX msec, and try again.
464  */
466  {
467  pg_time_t delay;
468 
469  delay = next_rotation_time - now;
470  if (delay > 0)
471  {
472  if (delay > INT_MAX / 1000)
473  delay = INT_MAX / 1000;
474  cur_timeout = delay * 1000L; /* msec */
475  }
476  else
477  cur_timeout = 0;
478  }
479  else
480  cur_timeout = -1L;
481 
482  /*
483  * Sleep until there's something to do
484  */
485 #ifndef WIN32
486  rc = WaitEventSetWait(wes, cur_timeout, &event, 1,
488 
489  if (rc == 1 && event.events == WL_SOCKET_READABLE)
490  {
491  int bytesRead;
492 
493  bytesRead = read(syslogPipe[0],
494  logbuffer + bytes_in_logbuffer,
495  sizeof(logbuffer) - bytes_in_logbuffer);
496  if (bytesRead < 0)
497  {
498  if (errno != EINTR)
499  ereport(LOG,
501  errmsg("could not read from logger pipe: %m")));
502  }
503  else if (bytesRead > 0)
504  {
505  bytes_in_logbuffer += bytesRead;
506  process_pipe_input(logbuffer, &bytes_in_logbuffer);
507  continue;
508  }
509  else
510  {
511  /*
512  * Zero bytes read when select() is saying read-ready means
513  * EOF on the pipe: that is, there are no longer any processes
514  * with the pipe write end open. Therefore, the postmaster
515  * and all backends are shut down, and we are done.
516  */
517  pipe_eof_seen = true;
518 
519  /* if there's any data left then force it out now */
520  flush_pipe_input(logbuffer, &bytes_in_logbuffer);
521  }
522  }
523 #else /* WIN32 */
524 
525  /*
526  * On Windows we leave it to a separate thread to transfer data and
527  * detect pipe EOF. The main thread just wakes up to handle SIGHUP
528  * and rotation conditions.
529  *
530  * Server code isn't generally thread-safe, so we ensure that only one
531  * of the threads is active at a time by entering the critical section
532  * whenever we're not sleeping.
533  */
534  LeaveCriticalSection(&sysloggerSection);
535 
536  (void) WaitEventSetWait(wes, cur_timeout, &event, 1,
538 
539  EnterCriticalSection(&sysloggerSection);
540 #endif /* WIN32 */
541 
542  if (pipe_eof_seen)
543  {
544  /*
545  * seeing this message on the real stderr is annoying - so we make
546  * it DEBUG1 to suppress in normal use.
547  */
548  ereport(DEBUG1,
549  (errmsg_internal("logger shutting down")));
550 
551  /*
552  * Normal exit from the syslogger is here. Note that we
553  * deliberately do not close syslogFile before exiting; this is to
554  * allow for the possibility of elog messages being generated
555  * inside proc_exit. Regular exit() will take care of flushing
556  * and closing stdio channels.
557  */
558  proc_exit(0);
559  }
560  }
561 }
sigset_t UnBlockSig
Definition: pqsignal.c:22
@ DestNone
Definition: dest.h:87
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
#define DEBUG1
Definition: elog.h:30
pg_time_t MyStartTime
Definition: globals.c:45
@ PGC_SIGHUP
Definition: guc.h:71
void ProcessConfigFile(GucContext context)
#define read(a, b, c)
Definition: win32.h:13
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:27
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:61
void proc_exit(int code)
Definition: ipc.c:104
WaitEventSet * CreateWaitEventSet(MemoryContext context, int nevents)
Definition: latch.c:723
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: latch.c:922
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:1383
void ResetLatch(Latch *latch)
Definition: latch.c:699
#define WL_SOCKET_READABLE
Definition: latch.h:126
#define WL_LATCH_SET
Definition: latch.h:125
char * pstrdup(const char *in)
Definition: mcxt.c:1644
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
@ B_LOGGER
Definition: miscadmin.h:336
BackendType MyBackendType
Definition: miscinit.c:63
pqsigfunc pqsignal(int signo, pqsigfunc func)
#define DEVNULL
Definition: port.h:160
#define PGINVALID_SOCKET
Definition: port.h:31
CommandDest whereToSendOutput
Definition: postgres.c:88
void init_ps_display(const char *fixed_part)
Definition: ps_status.c:242
uint32 events
Definition: latch.h:153
static void logfile_rotate(bool time_based_rotation, int size_rotation_for)
Definition: syslogger.c:1411
static bool pipe_eof_seen
Definition: syslogger.c:85
#define READ_BUF_SIZE
Definition: syslogger.c:61
static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
Definition: syslogger.c:929
int Log_RotationSize
Definition: syslogger.c:73
static void sigUsr1Handler(SIGNAL_ARGS)
Definition: syslogger.c:1643
static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
Definition: syslogger.c:1092
@ WAIT_EVENT_SYSLOGGER_MAIN
Definition: wait_event.h:47
#define SIGCHLD
Definition: win32_port.h:186
#define SIGHUP
Definition: win32_port.h:176
#define SIG_DFL
Definition: win32_port.h:171
#define EINTR
Definition: win32_port.h:382
#define SIGPIPE
Definition: win32_port.h:181
#define SIGQUIT
Definition: win32_port.h:177
#define SIGUSR1
Definition: win32_port.h:188
#define SIGALRM
Definition: win32_port.h:182
#define SIGUSR2
Definition: win32_port.h:189
#define SIG_IGN
Definition: win32_port.h:173

References AddWaitEventToSet(), B_LOGGER, close, ConfigReloadPending, CreateWaitEventSet(), csvlogFile, CurrentMemoryContext, DEBUG1, DestNone, DEVNULL, EINTR, elog(), ereport, errcode_for_socket_access(), errmsg(), errmsg_internal(), WaitEvent::events, FATAL, fd(), first_syslogger_file_time, flush_pipe_input(), init_ps_display(), jsonlogFile, last_csv_file_name, last_json_file_name, last_sys_file_name, LOG, Log_destination, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, LOG_DESTINATION_STDERR, Log_directory, Log_filename, Log_RotationAge, Log_RotationSize, logfile_getname(), logfile_rotate(), MakePGDirectory(), MyBackendType, MyLatch, MyStartTime, next_rotation_time, now(), pfree(), PGC_SIGHUP, PGINVALID_SOCKET, pipe_eof_seen, pqsignal(), proc_exit(), process_pipe_input(), ProcessConfigFile(), pstrdup(), read, READ_BUF_SIZE, redirection_done, ResetLatch(), rotation_disabled, rotation_requested, set_next_rotation_time(), SIG_DFL, SIG_IGN, SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SIGPIPE, SIGQUIT, SIGUSR1, sigUsr1Handler(), SIGUSR2, STDERR_FILENO, STDOUT_FILENO, syslogFile, syslogPipe, UnBlockSig, update_metainfo_datafile(), WAIT_EVENT_SYSLOGGER_MAIN, WaitEventSetWait(), whereToSendOutput, WL_LATCH_SET, and WL_SOCKET_READABLE.

Referenced by SysLogger_Start().

◆ update_metainfo_datafile()

static void update_metainfo_datafile ( void  )
static

Definition at line 1525 of file syslogger.c.

1526 {
1527  FILE *fh;
1528  mode_t oumask;
1529 
1533  {
1534  if (unlink(LOG_METAINFO_DATAFILE) < 0 && errno != ENOENT)
1535  ereport(LOG,
1537  errmsg("could not remove file \"%s\": %m",
1539  return;
1540  }
1541 
1542  /* use the same permissions as the data directory for the new file */
1543  oumask = umask(pg_mode_mask);
1544  fh = fopen(LOG_METAINFO_DATAFILE_TMP, "w");
1545  umask(oumask);
1546 
1547  if (fh)
1548  {
1549  setvbuf(fh, NULL, PG_IOLBF, 0);
1550 
1551 #ifdef WIN32
1552  /* use CRLF line endings on Windows */
1553  _setmode(_fileno(fh), _O_TEXT);
1554 #endif
1555  }
1556  else
1557  {
1558  ereport(LOG,
1560  errmsg("could not open file \"%s\": %m",
1562  return;
1563  }
1564 
1566  {
1567  if (fprintf(fh, "stderr %s\n", last_sys_file_name) < 0)
1568  {
1569  ereport(LOG,
1571  errmsg("could not write file \"%s\": %m",
1573  fclose(fh);
1574  return;
1575  }
1576  }
1577 
1579  {
1580  if (fprintf(fh, "csvlog %s\n", last_csv_file_name) < 0)
1581  {
1582  ereport(LOG,
1584  errmsg("could not write file \"%s\": %m",
1586  fclose(fh);
1587  return;
1588  }
1589  }
1590 
1592  {
1593  if (fprintf(fh, "jsonlog %s\n", last_json_file_name) < 0)
1594  {
1595  ereport(LOG,
1597  errmsg("could not write file \"%s\": %m",
1599  fclose(fh);
1600  return;
1601  }
1602  }
1603  fclose(fh);
1604 
1606  ereport(LOG,
1608  errmsg("could not rename file \"%s\" to \"%s\": %m",
1610 }
int pg_mode_mask
Definition: file_perm.c:25
#define fprintf
Definition: port.h:242
#define LOG_METAINFO_DATAFILE_TMP
Definition: syslogger.h:101
#define LOG_METAINFO_DATAFILE
Definition: syslogger.h:100

References ereport, errcode_for_file_access(), errmsg(), fprintf, last_csv_file_name, last_json_file_name, last_sys_file_name, LOG, Log_destination, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, LOG_DESTINATION_STDERR, LOG_METAINFO_DATAFILE, LOG_METAINFO_DATAFILE_TMP, PG_IOLBF, and pg_mode_mask.

Referenced by logfile_rotate(), and SysLoggerMain().

◆ write_syslogger_file()

void write_syslogger_file ( const char *  buffer,
int  count,
int  destination 
)

Definition at line 1143 of file syslogger.c.

1144 {
1145  int rc;
1146  FILE *logfile;
1147 
1148  /*
1149  * If we're told to write to a structured log file, but it's not open,
1150  * dump the data to syslogFile (which is always open) instead. This can
1151  * happen if structured output is enabled after postmaster start and we've
1152  * been unable to open logFile. There are also race conditions during a
1153  * parameter change whereby backends might send us structured output
1154  * before we open the logFile or after we close it. Writing formatted
1155  * output to the regular log file isn't great, but it beats dropping log
1156  * output on the floor.
1157  *
1158  * Think not to improve this by trying to open logFile on-the-fly. Any
1159  * failure in that would lead to recursion.
1160  */
1161  if ((destination & LOG_DESTINATION_CSVLOG) && csvlogFile != NULL)
1162  logfile = csvlogFile;
1163  else if ((destination & LOG_DESTINATION_JSONLOG) && jsonlogFile != NULL)
1164  logfile = jsonlogFile;
1165  else
1166  logfile = syslogFile;
1167 
1168  rc = fwrite(buffer, 1, count, logfile);
1169 
1170  /*
1171  * Try to report any failure. We mustn't use ereport because it would
1172  * just recurse right back here, but write_stderr is OK: it will write
1173  * either to the postmaster's original stderr, or to /dev/null, but never
1174  * to our input pipe which would result in a different sort of looping.
1175  */
1176  if (rc != count)
1177  write_stderr("could not write to log file: %s\n", strerror(errno));
1178 }
#define write_stderr(str)
Definition: parallel.c:184
static FILE * logfile
Definition: pg_regress.c:119
#define strerror
Definition: port.h:251

References csvlogFile, jsonlogFile, LOG_DESTINATION_CSVLOG, LOG_DESTINATION_JSONLOG, logfile, strerror, syslogFile, and write_stderr.

Referenced by flush_pipe_input(), process_pipe_input(), send_message_to_server_log(), write_csvlog(), and write_jsonlog().

Variable Documentation

◆ buffer_lists

List* buffer_lists[NBUFFER_LISTS]
static

Definition at line 113 of file syslogger.c.

Referenced by flush_pipe_input(), and process_pipe_input().

◆ csvlogFile

FILE* csvlogFile = NULL
static

Definition at line 88 of file syslogger.c.

Referenced by logfile_rotate(), SysLogger_Start(), SysLoggerMain(), and write_syslogger_file().

◆ first_syslogger_file_time

NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0

Definition at line 90 of file syslogger.c.

Referenced by SysLogger_Start(), and SysLoggerMain().

◆ jsonlogFile

FILE* jsonlogFile = NULL
static

Definition at line 89 of file syslogger.c.

Referenced by logfile_rotate(), SysLogger_Start(), SysLoggerMain(), and write_syslogger_file().

◆ last_csv_file_name

char* last_csv_file_name = NULL
static

Definition at line 92 of file syslogger.c.

Referenced by logfile_rotate(), SysLoggerMain(), and update_metainfo_datafile().

◆ last_json_file_name

char* last_json_file_name = NULL
static

Definition at line 93 of file syslogger.c.

Referenced by logfile_rotate(), SysLoggerMain(), and update_metainfo_datafile().

◆ last_sys_file_name

char* last_sys_file_name = NULL
static

Definition at line 91 of file syslogger.c.

Referenced by logfile_rotate(), SysLoggerMain(), and update_metainfo_datafile().

◆ Log_directory

char* Log_directory = NULL

◆ Log_file_mode

int Log_file_mode = S_IRUSR | S_IWUSR

Definition at line 77 of file syslogger.c.

Referenced by logfile_open(), and show_log_file_mode().

◆ Log_filename

char* Log_filename = NULL

Definition at line 75 of file syslogger.c.

Referenced by logfile_getname(), pg_logdir_ls_internal(), and SysLoggerMain().

◆ Log_RotationAge

int Log_RotationAge = HOURS_PER_DAY * MINS_PER_HOUR

Definition at line 72 of file syslogger.c.

Referenced by set_next_rotation_time(), and SysLoggerMain().

◆ Log_RotationSize

int Log_RotationSize = 10 * 1024

Definition at line 73 of file syslogger.c.

Referenced by SysLoggerMain().

◆ Log_truncate_on_rotation

bool Log_truncate_on_rotation = false

Definition at line 76 of file syslogger.c.

Referenced by logfile_rotate_dest().

◆ Logging_collector

bool Logging_collector = false

Definition at line 71 of file syslogger.c.

Referenced by pg_rotate_logfile(), pg_rotate_logfile_v2(), ServerLoop(), and SysLogger_Start().

◆ next_rotation_time

pg_time_t next_rotation_time
static

Definition at line 84 of file syslogger.c.

Referenced by logfile_rotate(), set_next_rotation_time(), and SysLoggerMain().

◆ pipe_eof_seen

bool pipe_eof_seen = false
static

Definition at line 85 of file syslogger.c.

Referenced by SysLoggerMain().

◆ redirection_done

bool redirection_done
extern

Definition at line 359 of file postmaster.c.

Referenced by SysLogger_Start(), and SysLoggerMain().

◆ rotation_disabled

bool rotation_disabled = false
static

Definition at line 86 of file syslogger.c.

Referenced by logfile_rotate_dest(), and SysLoggerMain().

◆ rotation_requested

volatile sig_atomic_t rotation_requested = false
static

Definition at line 130 of file syslogger.c.

Referenced by logfile_rotate(), sigUsr1Handler(), and SysLoggerMain().

◆ syslogFile

FILE* syslogFile = NULL
static

Definition at line 87 of file syslogger.c.

Referenced by logfile_rotate(), SysLogger_Start(), SysLoggerMain(), and write_syslogger_file().

◆ syslogPipe

int syslogPipe[2] = {-1, -1}

Definition at line 117 of file syslogger.c.

Referenced by ClosePostmasterPorts(), SysLogger_Start(), and SysLoggerMain().