diff options
| author | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-08-15 23:50:41 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@tele2.at> | 2018-08-16 13:31:13 +0200 | 
| commit | 4311b9a2f14ee411ec3dc8b050f8efa25afa0bc5 (patch) | |
| tree | 793c473392fc7cfd7915e6fc8a5aee5a121d5926 /syslogd | |
| parent | 0624f95de639a41e8a47c264cdb7387a386a4dcd (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>
Diffstat (limited to 'syslogd')
| -rw-r--r-- | syslogd/Makemodule.am | 2 | ||||
| -rw-r--r-- | syslogd/backend.h (renamed from syslogd/logfile.h) | 18 | ||||
| -rw-r--r-- | syslogd/logfile.c | 174 | ||||
| -rw-r--r-- | syslogd/main.c | 126 | 
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); | 
