Skip to content

Commit c2e8782

Browse files
committed
log_rotation_age works
1 parent e56ae30 commit c2e8782

File tree

1 file changed

+76
-29
lines changed

1 file changed

+76
-29
lines changed

utils/logger.c

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <time.h>
1616

1717
#include "logger.h"
18+
#include "pgut.h"
1819

1920
/* Logger parameters */
2021

@@ -25,7 +26,9 @@ char *error_log_filename = NULL;
2526
char *log_directory = NULL;
2627
char log_path[MAXPGPATH] = "";
2728

29+
/* Maximum size of an individual log file in kilobytes */
2830
int log_rotation_size = 0;
31+
/* Maximum lifetime of an individual log file in minutes */
2932
int log_rotation_age = 0;
3033

3134
/* Implementation for logging.h */
@@ -102,7 +105,9 @@ elog_internal(int elevel, const char *fmt, va_list args)
102105
{
103106
bool wrote_to_file = false;
104107

105-
pthread_mutex_lock(&log_file_mutex);
108+
/* There is no need to lock if this is elog() from upper elog() */
109+
if (!logging_to_file)
110+
pthread_mutex_lock(&log_file_mutex);
106111

107112
/*
108113
* Write message to log file.
@@ -161,7 +166,8 @@ elog_internal(int elevel, const char *fmt, va_list args)
161166
fflush(stderr);
162167
}
163168

164-
pthread_mutex_unlock(&log_file_mutex);
169+
if (!logging_to_file)
170+
pthread_mutex_unlock(&log_file_mutex);
165171

166172
/* Exit with code if it is an error */
167173
if (elevel > WARNING)
@@ -329,56 +335,82 @@ static void
329335
open_logfile(FILE **file, const char *filename_format)
330336
{
331337
char *filename;
338+
char control[MAXPGPATH];
332339
struct stat st;
333-
bool rotation_requested = false;
340+
FILE *control_file;
341+
time_t cur_time = time(NULL);
342+
bool rotation_requested = false,
343+
logfile_exists = false;
334344

335-
filename = logfile_getname(filename_format, time(NULL));
345+
filename = logfile_getname(filename_format, cur_time);
336346

337-
/* First check for rotation */
338-
if (log_rotation_size > 0 || log_rotation_age > 0)
347+
/* "log_path" was checked in logfile_getname() */
348+
snprintf(control, MAXPGPATH, "%s/log_rotation", log_path);
349+
350+
if (stat(filename, &st) == -1)
339351
{
340-
if (stat(filename, &st) == -1)
352+
if (errno == ENOENT)
341353
{
342-
if (errno == ENOENT)
343-
{
344-
/* There is no file "filename" and rotation does not need */
345-
goto logfile_open;
346-
}
347-
else
348-
elog(ERROR, "cannot stat log file \"%s\": %s",
349-
filename, strerror(errno));
354+
/* There is no file "filename" and rotation does not need */
355+
goto logfile_open;
350356
}
351-
/* Found log file "filename" */
357+
else
358+
elog(ERROR, "cannot stat log file \"%s\": %s",
359+
filename, strerror(errno));
360+
}
361+
/* Found log file "filename" */
362+
logfile_exists = true;
352363

364+
/* First check for rotation */
365+
if (log_rotation_size > 0 || log_rotation_age > 0)
366+
{
353367
/* Check for rotation by age */
354368
if (log_rotation_age > 0)
355369
{
356-
char control[MAXPGPATH];
357370
struct stat control_st;
358-
FILE *control_file;
359371

360-
snprintf(control, MAXPGPATH, "%s.rotation", filename);
361372
if (stat(control, &control_st) == -1)
362373
{
363-
if (errno == ENOENT)
364-
{
365-
/* There is no control file for rotation */
366-
goto logfile_open;
367-
}
368-
else
374+
if (errno != ENOENT)
369375
elog(ERROR, "cannot stat rotation file \"%s\": %s",
370376
control, strerror(errno));
371377
}
378+
else
379+
{
380+
char buf[1024];
372381

373-
/* Found control file for rotation */
382+
control_file = fopen(control, "r");
383+
if (control_file == NULL)
384+
elog(ERROR, "cannot open rotation file \"%s\": %s",
385+
control, strerror(errno));
386+
387+
if (fgets(buf, lengthof(buf), control_file))
388+
{
389+
time_t creation_time;
390+
391+
if (!parse_int64(buf, (int64 *) &creation_time))
392+
elog(ERROR, "rotation file \"%s\" has wrong "
393+
"creation timestamp \"%s\"",
394+
control, buf);
395+
/* Parsed creation time */
396+
397+
rotation_requested = (cur_time - creation_time) >
398+
/* convert to seconds */
399+
log_rotation_age * 60;
400+
}
401+
else
402+
elog(ERROR, "cannot read creation timestamp from "
403+
"rotation file \"%s\"", control);
374404

375-
control_file = fopen(control, "r");
376-
fclose(control_file);
405+
fclose(control_file);
406+
}
377407
}
378408

379409
/* Check for rotation by size */
380410
if (!rotation_requested && log_rotation_size > 0)
381-
rotation_requested = (st.st_size >= log_rotation_size * 1024L);
411+
rotation_requested = st.st_size >=
412+
/* convert to bytes */
413+
log_rotation_size * 1024L;
382414
}
383415

384416
logfile_open:
@@ -388,6 +420,21 @@ open_logfile(FILE **file, const char *filename_format)
388420
*file = logfile_open(filename, "a");
389421
pfree(filename);
390422

423+
/* Rewrite rotation control file */
424+
if (rotation_requested || !logfile_exists)
425+
{
426+
time_t timestamp = time(NULL);
427+
428+
control_file = fopen(control, "w");
429+
if (control_file == NULL)
430+
elog(ERROR, "cannot open rotation file \"%s\": %s",
431+
control, strerror(errno));
432+
433+
fprintf(control_file, "%ld", timestamp);
434+
435+
fclose(control_file);
436+
}
437+
391438
/*
392439
* Arrange to close opened file at proc_exit.
393440
*/

0 commit comments

Comments
 (0)