aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/syslogger.c229
1 files changed, 113 insertions, 116 deletions
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index c5f9c5202da..34b16ba3bb3 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -87,7 +87,7 @@ static bool rotation_disabled = false;
static FILE *syslogFile = NULL;
static FILE *csvlogFile = NULL;
NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0;
-static char *last_file_name = NULL;
+static char *last_sys_file_name = NULL;
static char *last_csv_file_name = NULL;
/*
@@ -145,6 +145,10 @@ static FILE *logfile_open(const char *filename, const char *mode,
static unsigned int __stdcall pipeThread(void *arg);
#endif
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);
@@ -274,7 +278,7 @@ SysLoggerMain(int argc, char *argv[])
* time because passing down just the pg_time_t is a lot cheaper than
* passing a whole file path in the EXEC_BACKEND case.
*/
- last_file_name = logfile_getname(first_syslogger_file_time, NULL);
+ last_sys_file_name = logfile_getname(first_syslogger_file_time, NULL);
if (csvlogFile != NULL)
last_csv_file_name = logfile_getname(first_syslogger_file_time, ".csv");
@@ -1242,145 +1246,138 @@ logfile_open(const char *filename, const char *mode, bool allow_errors)
}
/*
- * perform logfile rotation
+ * Do logfile rotation for a single destination, as specified by target_dest.
+ * The information stored in *last_file_name and *logFile is updated on a
+ * successful file rotation.
+ *
+ * Returns false if the rotation has been stopped, or true to move on to
+ * the processing of other formats.
*/
-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)
{
+ char *logFileExt;
char *filename;
- char *csvfilename = NULL;
- pg_time_t fntime;
FILE *fh;
- rotation_requested = false;
+ /*
+ * If the target destination was just turned off, close the previous file
+ * and unregister its data. This cannot happen for stderr as syslogFile
+ * is assumed to be always opened even if stderr is disabled in
+ * log_destination.
+ */
+ if ((Log_destination & target_dest) == 0 &&
+ target_dest != LOG_DESTINATION_STDERR)
+ {
+ if (*logFile != NULL)
+ fclose(*logFile);
+ *logFile = NULL;
+ if (*last_file_name != NULL)
+ pfree(*last_file_name);
+ *last_file_name = NULL;
+ return true;
+ }
/*
- * When doing a time-based rotation, invent the new logfile name based on
- * the planned rotation time, not current time, to avoid "slippage" in the
- * file name when we don't do the rotation immediately.
+ * Leave if it is not time for a rotation or if the target destination has
+ * no need to do a rotation based on the size of its file.
*/
- if (time_based_rotation)
- fntime = next_rotation_time;
+ if (!time_based_rotation && (size_rotation_for & target_dest) == 0)
+ return true;
+
+ /* file extension depends on the destination type */
+ if (target_dest == LOG_DESTINATION_STDERR)
+ logFileExt = NULL;
+ else if (target_dest == LOG_DESTINATION_CSVLOG)
+ logFileExt = ".csv";
else
- fntime = time(NULL);
- filename = logfile_getname(fntime, NULL);
- if (Log_destination & LOG_DESTINATION_CSVLOG)
- csvfilename = logfile_getname(fntime, ".csv");
+ {
+ /* cannot happen */
+ Assert(false);
+ }
+
+ /* build the new file name */
+ filename = logfile_getname(fntime, logFileExt);
/*
* Decide whether to overwrite or append. We can overwrite if (a)
* Log_truncate_on_rotation is set, (b) the rotation was triggered by
* elapsed time and not something else, and (c) the computed file name is
* different from what we were previously logging into.
- *
- * Note: last_file_name should never be NULL here, but if it is, append.
*/
- if (time_based_rotation || (size_rotation_for & LOG_DESTINATION_STDERR))
- {
- if (Log_truncate_on_rotation && time_based_rotation &&
- last_file_name != NULL &&
- strcmp(filename, last_file_name) != 0)
- fh = logfile_open(filename, "w", true);
- else
- fh = logfile_open(filename, "a", true);
+ if (Log_truncate_on_rotation && time_based_rotation &&
+ *last_file_name != NULL &&
+ strcmp(filename, *last_file_name) != 0)
+ fh = logfile_open(filename, "w", true);
+ else
+ fh = logfile_open(filename, "a", true);
- if (!fh)
+ if (!fh)
+ {
+ /*
+ * ENFILE/EMFILE are not too surprising on a busy system; just keep
+ * using the old file till we manage to get a new one. Otherwise,
+ * assume something's wrong with Log_directory and stop trying to
+ * create files.
+ */
+ if (errno != ENFILE && errno != EMFILE)
{
- /*
- * ENFILE/EMFILE are not too surprising on a busy system; just
- * keep using the old file till we manage to get a new one.
- * Otherwise, assume something's wrong with Log_directory and stop
- * trying to create files.
- */
- if (errno != ENFILE && errno != EMFILE)
- {
- ereport(LOG,
- (errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
- rotation_disabled = true;
- }
-
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
- return;
+ ereport(LOG,
+ (errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
+ rotation_disabled = true;
}
- fclose(syslogFile);
- syslogFile = fh;
-
- /* instead of pfree'ing filename, remember it for next time */
- if (last_file_name != NULL)
- pfree(last_file_name);
- last_file_name = filename;
- filename = NULL;
+ if (filename)
+ pfree(filename);
+ return false;
}
- /*
- * Same as above, but for csv file. Note that if LOG_DESTINATION_CSVLOG
- * was just turned on, we might have to open csvlogFile here though it was
- * not open before. In such a case we'll append not overwrite (since
- * last_csv_file_name will be NULL); that is consistent with the normal
- * rules since it's not a time-based rotation.
- */
- if ((Log_destination & LOG_DESTINATION_CSVLOG) &&
- (csvlogFile == NULL ||
- time_based_rotation || (size_rotation_for & LOG_DESTINATION_CSVLOG)))
- {
- if (Log_truncate_on_rotation && time_based_rotation &&
- last_csv_file_name != NULL &&
- strcmp(csvfilename, last_csv_file_name) != 0)
- fh = logfile_open(csvfilename, "w", true);
- else
- fh = logfile_open(csvfilename, "a", true);
+ /* fill in the new information */
+ if (*logFile != NULL)
+ fclose(*logFile);
+ *logFile = fh;
- if (!fh)
- {
- /*
- * ENFILE/EMFILE are not too surprising on a busy system; just
- * keep using the old file till we manage to get a new one.
- * Otherwise, assume something's wrong with Log_directory and stop
- * trying to create files.
- */
- if (errno != ENFILE && errno != EMFILE)
- {
- ereport(LOG,
- (errmsg("disabling automatic rotation (use SIGHUP to re-enable)")));
- rotation_disabled = true;
- }
+ /* instead of pfree'ing filename, remember it for next time */
+ if (*last_file_name != NULL)
+ pfree(*last_file_name);
+ *last_file_name = filename;
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
- return;
- }
+ return true;
+}
+
+/*
+ * perform logfile rotation
+ */
+static void
+logfile_rotate(bool time_based_rotation, int size_rotation_for)
+{
+ pg_time_t fntime;
- if (csvlogFile != NULL)
- fclose(csvlogFile);
- csvlogFile = fh;
+ rotation_requested = false;
- /* instead of pfree'ing filename, remember it for next time */
- if (last_csv_file_name != NULL)
- pfree(last_csv_file_name);
- last_csv_file_name = csvfilename;
- csvfilename = NULL;
- }
- else if (!(Log_destination & LOG_DESTINATION_CSVLOG) &&
- csvlogFile != NULL)
- {
- /* CSVLOG was just turned off, so close the old file */
- fclose(csvlogFile);
- csvlogFile = NULL;
- if (last_csv_file_name != NULL)
- pfree(last_csv_file_name);
- last_csv_file_name = NULL;
- }
+ /*
+ * When doing a time-based rotation, invent the new logfile name based on
+ * the planned rotation time, not current time, to avoid "slippage" in the
+ * file name when we don't do the rotation immediately.
+ */
+ if (time_based_rotation)
+ fntime = next_rotation_time;
+ else
+ fntime = time(NULL);
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
+ /* file rotation for stderr */
+ if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
+ LOG_DESTINATION_STDERR, &last_sys_file_name,
+ &syslogFile))
+ return;
+
+ /* file rotation for csvlog */
+ if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
+ LOG_DESTINATION_CSVLOG, &last_csv_file_name,
+ &csvlogFile))
+ return;
update_metainfo_datafile();
@@ -1501,9 +1498,9 @@ update_metainfo_datafile(void)
return;
}
- if (last_file_name && (Log_destination & LOG_DESTINATION_STDERR))
+ if (last_sys_file_name && (Log_destination & LOG_DESTINATION_STDERR))
{
- if (fprintf(fh, "stderr %s\n", last_file_name) < 0)
+ if (fprintf(fh, "stderr %s\n", last_sys_file_name) < 0)
{
ereport(LOG,
(errcode_for_file_access(),