From d62ee95689e1e8c6fa4b395adfc8c0fcbca96b6f Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 16 Aug 2018 00:10:03 +0200 Subject: [PATCH] Implement simple log rotation Signed-off-by: David Oberhollenzer --- syslogd/backend.h | 2 ++ syslogd/logfile.c | 68 ++++++++++++++++++++++++++++++++++++++--------- syslogd/main.c | 10 +++++++ 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/syslogd/backend.h b/syslogd/backend.h index 9f26a54..b5e238a 100644 --- a/syslogd/backend.h +++ b/syslogd/backend.h @@ -26,6 +26,8 @@ typedef struct log_backend_t { void (*cleanup)(struct log_backend_t *log); int (*write)(struct log_backend_t *log, const syslog_msg_t *msg); + + void (*rotate)(struct log_backend_t *log); } log_backend_t; diff --git a/syslogd/logfile.c b/syslogd/logfile.c index 0fe9c9b..5f0f98a 100644 --- a/syslogd/logfile.c +++ b/syslogd/logfile.c @@ -85,6 +85,22 @@ typedef struct { } log_backend_file_t; +static int logfile_open(logfile_t *file) +{ + file->fd = open(file->filename, O_WRONLY | O_CREAT, 0640); + if (file->fd < 0) { + perror(file->filename); + return -1; + } + + if (lseek(file->fd, 0, SEEK_END)) { + close(file->fd); + return -1; + } + + return 0; +} + static logfile_t *logfile_create(const char *filename) { logfile_t *file = calloc(1, sizeof(*file) + strlen(filename) + 1); @@ -96,21 +112,12 @@ static logfile_t *logfile_create(const char *filename) strcpy(file->filename, filename); - file->fd = open(file->filename, O_WRONLY | O_CREAT, 0640); - if (file->fd < 0) { - perror(file->filename); - goto fail; + if (logfile_open(file)) { + free(file); + return NULL; } - if (lseek(file->fd, 0, SEEK_END)) - goto fail_fd; - return file; -fail_fd: - close(file->fd); -fail: - free(file); - return NULL; } static int logfile_write(logfile_t *file, const syslog_msg_t *msg) @@ -119,6 +126,9 @@ static int logfile_write(logfile_t *file, const syslog_msg_t *msg) char timebuf[32]; struct tm tm; + if (file->fd < 0 && logfile_open(file) != 0) + return -1; + lvl_str = enum_to_name(levels, msg->level); if (lvl_str == NULL) return -1; @@ -133,6 +143,30 @@ static int logfile_write(logfile_t *file, const syslog_msg_t *msg) return 0; } +static int logfile_rotate(logfile_t *f) +{ + char timebuf[32]; + char *filename; + struct tm tm; + time_t now; + + now = time(NULL); + gmtime_r(&now, &tm); + strftime(timebuf, sizeof(timebuf), "%FT%T", &tm); + + filename = alloca(strlen(f->filename) + strlen(timebuf) + 2); + sprintf(filename, "%s.%s", f->filename, timebuf); + + if (rename(f->filename, filename)) { + perror(filename); + return -1; + } + + close(f->fd); + logfile_open(f); + return 0; +} + /*****************************************************************************/ static int file_backend_init(log_backend_t *log) @@ -210,11 +244,21 @@ static int file_backend_write(log_backend_t *backend, const syslog_msg_t *msg) return logfile_write(f, msg); } +static void file_backend_rotate(log_backend_t *backend) +{ + log_backend_file_t *log = (log_backend_file_t *)backend; + logfile_t *f; + + for (f = log->list; f != NULL; f = f->next) + logfile_rotate(f); +} + log_backend_file_t filebackend = { .base = { .init = file_backend_init, .cleanup = file_backend_cleanup, .write = file_backend_write, + .rotate = file_backend_rotate, }, .list = NULL, }; diff --git a/syslogd/main.c b/syslogd/main.c index 8f11906..6b4937e 100644 --- a/syslogd/main.c +++ b/syslogd/main.c @@ -34,6 +34,7 @@ static volatile sig_atomic_t syslog_run = 1; +static volatile sig_atomic_t syslog_rotate = 0; static void sighandler(int signo) @@ -43,6 +44,9 @@ static void sighandler(int signo) case SIGTERM: syslog_run = 0; break; + case SIGHUP: + syslog_rotate = 1; + break; default: break; } @@ -57,6 +61,7 @@ static void signal_setup(void) sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); + sigaction(SIGHUP, &act, NULL); } static int handle_data(int fd) @@ -91,6 +96,11 @@ int main(void) goto out; while (syslog_run) { + if (syslog_rotate) { + logmgr->rotate(logmgr); + syslog_rotate = 0; + } + handle_data(sfd); }