summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-08-15 23:50:41 +0200
committerDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-08-16 13:31:13 +0200
commit4311b9a2f14ee411ec3dc8b050f8efa25afa0bc5 (patch)
tree793c473392fc7cfd7915e6fc8a5aee5a121d5926
parent0624f95de639a41e8a47c264cdb7387a386a4dcd (diff)
usyslogd: create abstraction for log stream management
This commit seperates the formating and printing of log messages to files more cleanly from the message pump that retrieves the log messages. At a later point, other backends could be added more easiyl (e.g. forward the log message to some server). Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
-rw-r--r--syslogd/Makemodule.am2
-rw-r--r--syslogd/backend.h (renamed from syslogd/logfile.h)18
-rw-r--r--syslogd/logfile.c174
-rw-r--r--syslogd/main.c126
4 files changed, 174 insertions, 146 deletions
diff --git a/syslogd/Makemodule.am b/syslogd/Makemodule.am
index 9e5378d..d954769 100644
--- a/syslogd/Makemodule.am
+++ b/syslogd/Makemodule.am
@@ -1,5 +1,5 @@
usyslogd_SOURCES = syslogd/main.c
-usyslogd_SOURCES += syslogd/logfile.c syslogd/logfile.h
+usyslogd_SOURCES += syslogd/logfile.c syslogd/backend.h
usyslogd_SOURCES += syslogd/proto.c syslogd/proto.h
usyslogd_CPPFLAGS = $(AM_CPPFLAGS)
usyslogd_CFLAGS = $(AM_CFLAGS)
diff --git a/syslogd/logfile.h b/syslogd/backend.h
index ccbfd5d..9f26a54 100644
--- a/syslogd/logfile.h
+++ b/syslogd/backend.h
@@ -18,18 +18,18 @@
#ifndef LOGFILE_H
#define LOGFILE_H
-typedef struct logfile_t {
- struct logfile_t *next;
- int facility;
- int fd;
+#include "proto.h"
- char filename[];
-} logfile_t;
+typedef struct log_backend_t {
+ int (*init)(struct log_backend_t *log);
-logfile_t *logfile_create(const char *filename, int facility);
+ void (*cleanup)(struct log_backend_t *log);
-void logfile_destroy(logfile_t *file);
+ int (*write)(struct log_backend_t *log, const syslog_msg_t *msg);
+} log_backend_t;
+
+
+extern log_backend_t *logmgr;
-void logfile_write(logfile_t *file, const char *format, ...);
#endif /* LOGFILE_H */
diff --git a/syslogd/logfile.c b/syslogd/logfile.c
index adc7e3c..0fe9c9b 100644
--- a/syslogd/logfile.c
+++ b/syslogd/logfile.c
@@ -20,15 +20,72 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
-#include "logfile.h"
+#include "backend.h"
+#include "util.h"
-logfile_t *logfile_create(const char *filename, int facility)
+#define SYSLOG_PATH "/var/log"
+
+
+static const enum_map_t levels[] = {
+ { "emergency", 0 },
+ { "alert", 1 },
+ { "critical", 2 },
+ { "error", 3 },
+ { "warning", 4 },
+ { "notice", 5 },
+ { "info", 6 },
+ { "debug", 7 },
+ { NULL, 0 },
+};
+
+static const enum_map_t facilities[] = {
+ { "kernel.log", 0 },
+ { "user.log", 1 },
+ { "mail.log", 2 },
+ { "daemon.log", 3 },
+ { "auth.log", 4 },
+ { "syslog.log", 5 },
+ { "lpr.log", 6 },
+ { "news.log", 7 },
+ { "uucp.log", 8 },
+ { "clock.log", 9 },
+ { "authpriv.log", 10 },
+ { "ftp.log", 11 },
+ { "ntp.log", 12 },
+ { "audit.log", 13 },
+ { "alert.log", 14 },
+ { "cron.log", 15 },
+ { "local0.log", 16 },
+ { "local1.log", 17 },
+ { "local2.log", 18 },
+ { "local3.log", 19 },
+ { "local4.log", 20 },
+ { "local5.log", 21 },
+ { "local6.log", 22 },
+ { "local7.log", 23 },
+ { NULL, 0 },
+};
+
+
+typedef struct logfile_t {
+ struct logfile_t *next;
+ int fd;
+ char filename[];
+} logfile_t;
+
+
+typedef struct {
+ log_backend_t base;
+ logfile_t *list;
+} log_backend_file_t;
+
+
+static logfile_t *logfile_create(const char *filename)
{
logfile_t *file = calloc(1, sizeof(*file) + strlen(filename) + 1);
@@ -39,8 +96,6 @@ logfile_t *logfile_create(const char *filename, int facility)
strcpy(file->filename, filename);
- file->facility = facility;
-
file->fd = open(file->filename, O_WRONLY | O_CREAT, 0640);
if (file->fd < 0) {
perror(file->filename);
@@ -58,19 +113,110 @@ fail:
return NULL;
}
-void logfile_destroy(logfile_t *file)
+static int logfile_write(logfile_t *file, const syslog_msg_t *msg)
{
- close(file->fd);
- free(file);
+ const char *lvl_str;
+ char timebuf[32];
+ struct tm tm;
+
+ lvl_str = enum_to_name(levels, msg->level);
+ if (lvl_str == NULL)
+ return -1;
+
+ gmtime_r(&msg->timestamp, &tm);
+ strftime(timebuf, sizeof(timebuf), "%FT%T", &tm);
+
+ dprintf(file->fd, "[%s][%s][%u] %s", timebuf, lvl_str, msg->pid,
+ msg->message);
+
+ fsync(file->fd);
+ return 0;
}
-void logfile_write(logfile_t *file, const char *format, ...)
+/*****************************************************************************/
+
+static int file_backend_init(log_backend_t *log)
{
- va_list ap;
+ (void)log;
- va_start(ap, format);
- vdprintf(file->fd, format, ap);
- va_end(ap);
+ if (mkdir(SYSLOG_PATH, 0755)) {
+ if (errno != EEXIST) {
+ perror("mkdir " SYSLOG_PATH);
+ return -1;
+ }
+ }
- fsync(file->fd);
+ if (chdir(SYSLOG_PATH)) {
+ perror("cd " SYSLOG_PATH);
+ return -1;
+ }
+
+ return 0;
}
+
+static void file_backend_cleanup(log_backend_t *backend)
+{
+ log_backend_file_t *log = (log_backend_file_t *)backend;
+ logfile_t *f;
+
+ while (log->list != NULL) {
+ f = log->list;
+ log->list = f->next;
+
+ close(f->fd);
+ free(f);
+ }
+}
+
+static int file_backend_write(log_backend_t *backend, const syslog_msg_t *msg)
+{
+ log_backend_file_t *log = (log_backend_file_t *)backend;
+ const char *fac_name;
+ char *filename;
+ logfile_t *f;
+ size_t len;
+
+ fac_name = enum_to_name(facilities, msg->facility);
+ if (fac_name == NULL)
+ return -1;
+
+ if (msg->ident) {
+ len = strlen(msg->ident) + 1 + strlen(fac_name) + 1;
+ filename = alloca(len);
+ sprintf(filename, "%s/%s", msg->ident, fac_name);
+ } else {
+ filename = (char *)fac_name;
+ }
+
+ for (f = log->list; f != NULL; f = f->next) {
+ if (strcmp(filename, f->filename) == 0)
+ break;
+ }
+
+ if (f == NULL) {
+ if (msg->ident != NULL && mkdir(msg->ident, 0750) != 0 &&
+ errno != EEXIST) {
+ perror(msg->ident);
+ return -1;
+ }
+
+ f = logfile_create(filename);
+ if (f == NULL)
+ return -1;
+ f->next = log->list;
+ log->list = f;
+ }
+
+ return logfile_write(f, msg);
+}
+
+log_backend_file_t filebackend = {
+ .base = {
+ .init = file_backend_init,
+ .cleanup = file_backend_cleanup,
+ .write = file_backend_write,
+ },
+ .list = NULL,
+};
+
+log_backend_t *logmgr = (log_backend_t *)&filebackend;
diff --git a/syslogd/main.c b/syslogd/main.c
index b98c414..8f11906 100644
--- a/syslogd/main.c
+++ b/syslogd/main.c
@@ -25,75 +25,16 @@
#include <errno.h>
#include <stdio.h>
-#include "logfile.h"
+#include "backend.h"
#include "proto.h"
#include "util.h"
#define SYSLOG_SOCKET "/dev/log"
-#define SYSLOG_PATH "/var/log"
static volatile sig_atomic_t syslog_run = 1;
-static logfile_t *logfiles = NULL;
-
-static const enum_map_t facilities[] = {
- { "kernel.log", 0 },
- { "user.log", 1 },
- { "mail.log", 2 },
- { "daemon.log", 3 },
- { "auth.log", 4 },
- { "syslog.log", 5 },
- { "lpr.log", 6 },
- { "news.log", 7 },
- { "uucp.log", 8 },
- { "clock.log", 9 },
- { "authpriv.log", 10 },
- { "ftp.log", 11 },
- { "ntp.log", 12 },
- { "audit.log", 13 },
- { "alert.log", 14 },
- { "cron.log", 15 },
- { "local0.log", 16 },
- { "local1.log", 17 },
- { "local2.log", 18 },
- { "local3.log", 19 },
- { "local4.log", 20 },
- { "local5.log", 21 },
- { "local6.log", 22 },
- { "local7.log", 23 },
- { NULL, 0 },
-};
-
-static const enum_map_t levels[] = {
- { "emergency", 0 },
- { "alert", 1 },
- { "critical", 2 },
- { "error", 3 },
- { "warning", 4 },
- { "notice", 5 },
- { "info", 6 },
- { "debug", 7 },
- { NULL, 0 },
-};
-
-
-static int directory_setup(void)
-{
- if (mkdir(SYSLOG_PATH, 0755)) {
- if (errno != EEXIST) {
- perror("mkdir " SYSLOG_PATH);
- return -1;
- }
- }
-
- if (chdir(SYSLOG_PATH)) {
- perror("cd " SYSLOG_PATH);
- return -1;
- }
- return 0;
-}
static void sighandler(int signo)
{
@@ -118,59 +59,6 @@ static void signal_setup(void)
sigaction(SIGTERM, &act, NULL);
}
-static int print_to_log(const syslog_msg_t *msg)
-{
- const char *fac_name, *lvl_str;
- char timebuf[32], *filename;
- logfile_t *log;
- struct tm tm;
- size_t len;
-
- fac_name = enum_to_name(facilities, msg->facility);
- if (fac_name == NULL)
- return -1;
-
- lvl_str = enum_to_name(levels, msg->level);
- if (lvl_str == NULL)
- return -1;
-
- if (msg->ident) {
- len = strlen(msg->ident) + 1 + strlen(fac_name) + 1;
- filename = alloca(len);
- sprintf(filename, "%s/%s", msg->ident, fac_name);
- } else {
- filename = (char *)fac_name;
- }
-
- for (log = logfiles; log != NULL; log = log->next) {
- if (log->facility != msg->facility)
- continue;
- if (strcmp(filename, log->filename) == 0)
- break;
- }
-
- if (log == NULL) {
- if (msg->ident != NULL && mkdir(msg->ident, 0750) != 0 &&
- errno != EEXIST) {
- perror(msg->ident);
- return -1;
- }
-
- log = logfile_create(filename, msg->facility);
- if (log == NULL)
- return -1;
- log->next = logfiles;
- logfiles = log;
- }
-
- gmtime_r(&msg->timestamp, &tm);
- strftime(timebuf, sizeof(timebuf), "%FT%T", &tm);
-
- logfile_write(log, "[%s][%s][%u] %s", timebuf, lvl_str, msg->pid,
- msg->message);
- return 0;
-}
-
static int handle_data(int fd)
{
char buffer[2048];
@@ -186,13 +74,12 @@ static int handle_data(int fd)
if (syslog_msg_parse(&msg, buffer))
return -1;
- return print_to_log(&msg);
+ return logmgr->write(logmgr, &msg);
}
int main(void)
{
int sfd, status = EXIT_FAILURE;
- logfile_t *log;
signal_setup();
@@ -200,7 +87,7 @@ int main(void)
if (sfd < 0)
return EXIT_FAILURE;
- if (directory_setup())
+ if (logmgr->init(logmgr))
goto out;
while (syslog_run) {
@@ -209,12 +96,7 @@ int main(void)
status = EXIT_SUCCESS;
out:
- while (logfiles != NULL) {
- log = logfiles;
- logfiles = logfiles->next;
-
- logfile_destroy(log);
- }
+ logmgr->cleanup(logmgr);
if (sfd > 0)
close(sfd);
unlink(SYSLOG_SOCKET);