v4-0001-Refactor-per-destination-file-rotation-in-syslogg.patch
text/x-diff
Filename: v4-0001-Refactor-per-destination-file-rotation-in-syslogg.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v4-0001
Subject: Refactor per-destination file rotation in syslogger
| File | + | − |
|---|---|---|
| src/backend/postmaster/syslogger.c | 119 | 123 |
From 4641f8535c2be4b75285ac34d87e883bec250e48 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 28 Sep 2021 11:48:18 +0900
Subject: [PATCH v4 1/5] Refactor per-destination file rotation in syslogger
---
src/backend/postmaster/syslogger.c | 242 ++++++++++++++---------------
1 file changed, 119 insertions(+), 123 deletions(-)
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index c5f9c5202d..4a019db7f4 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;
/*
@@ -274,7 +274,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");
@@ -1241,16 +1241,118 @@ logfile_open(const char *filename, const char *mode, bool allow_errors)
return fh;
}
+/*
+ * 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, and true to move on to
+ * the processing of other formats.
+ */
+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;
+ FILE *fh;
+
+ /*
+ * 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
+ * LOG_DESTINATION_STDERR is disabled.
+ */
+ 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;
+ }
+
+ /*
+ * Leave if it is not time for a rotation or if the target destination
+ * has no need to do a rotation.
+ */
+ 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
+ {
+ /* 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.
+ */
+ 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)
+ {
+ /*
+ * 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);
+ return false;
+ }
+
+ /* fill in the new information */
+ if (*logFile != NULL)
+ fclose(*logFile);
+ *logFile = fh;
+
+ /* instead of pfree'ing filename, remember it for next time */
+ if (*last_file_name != NULL)
+ pfree(*last_file_name);
+ *last_file_name = filename;
+
+ return true;
+}
+
/*
* perform logfile rotation
*/
static void
logfile_rotate(bool time_based_rotation, int size_rotation_for)
{
- char *filename;
- char *csvfilename = NULL;
pg_time_t fntime;
- FILE *fh;
rotation_requested = false;
@@ -1263,124 +1365,18 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
fntime = next_rotation_time;
else
fntime = time(NULL);
- filename = logfile_getname(fntime, NULL);
- if (Log_destination & LOG_DESTINATION_CSVLOG)
- csvfilename = logfile_getname(fntime, ".csv");
- /*
- * 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);
+ /* file rotation for stderr */
+ if (!logfile_rotate_dest(time_based_rotation, size_rotation_for, fntime,
+ LOG_DESTINATION_STDERR, &last_sys_file_name,
+ &syslogFile))
+ return;
- 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;
- }
-
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
- return;
- }
-
- 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;
- }
-
- /*
- * 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);
-
- 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;
- }
-
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
- return;
- }
-
- if (csvlogFile != NULL)
- fclose(csvlogFile);
- csvlogFile = fh;
-
- /* 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;
- }
-
- if (filename)
- pfree(filename);
- if (csvfilename)
- pfree(csvfilename);
+ /* 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 +1497,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(),
--
2.33.0