From 95f20b96d4f76480044d86d6c30c85fb50954978 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 21 Sep 2004 00:21:25 +0000 Subject: [PATCH] Rotate on time boundaries that are sensible per local time rather than GMT. Also, avoid truncating the file we just wrote into, which might otherwise easily happen at DST boundaries. Ed L. and Tom Lane. --- src/backend/postmaster/syslogger.c | 32 +++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index a1e8870e92..958af88117 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -18,7 +18,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.8 2004/08/31 04:53:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.9 2004/09/21 00:21:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -81,6 +81,8 @@ static bool pipe_eof_seen = false; static FILE *syslogFile = NULL; +static char *last_file_name = NULL; + /* These must be exported for EXEC_BACKEND case ... annoying */ #ifndef WIN32 int syslogPipe[2] = {-1, -1}; @@ -761,7 +763,20 @@ logfile_rotate(bool time_based_rotation) else filename = logfile_getname(time(NULL)); - if (Log_truncate_on_rotation && time_based_rotation) + /* + * 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: during the first rotation after forking off from the postmaster, + * last_file_name will be NULL. (We don't bother to set it in the + * postmaster because it ain't gonna work in the EXEC_BACKEND case.) + * So we will always append in that situation, even though truncating + * would usually be safe. + */ + if (Log_truncate_on_rotation && time_based_rotation && + last_file_name != NULL && strcmp(filename, last_file_name) != 0) fh = fopen(filename, "w"); else fh = fopen(filename, "a"); @@ -806,7 +821,10 @@ logfile_rotate(bool time_based_rotation) set_next_rotation_time(); - pfree(filename); + /* instead of pfree'ing filename, remember it for next time */ + if (last_file_name != NULL) + pfree(last_file_name); + last_file_name = filename; } @@ -854,6 +872,7 @@ static void set_next_rotation_time(void) { pg_time_t now; + struct pg_tm *tm; int rotinterval; /* nothing to do if time-based rotation is disabled */ @@ -863,13 +882,16 @@ set_next_rotation_time(void) /* * The requirements here are to choose the next time > now that is a * "multiple" of the log rotation interval. "Multiple" can be interpreted - * fairly loosely --- in particular, for intervals larger than an hour, - * it might be interesting to align to local time instead of GMT. + * fairly loosely. In this version we align to local time rather than + * GMT. */ rotinterval = Log_RotationAge * 60; /* convert to seconds */ now = time(NULL); + tm = pg_localtime(&now); + now += tm->tm_gmtoff; now -= now % rotinterval; now += rotinterval; + now -= tm->tm_gmtoff; next_rotation_time = now; }