From 2cbf74bfe6d1394895de3cc3dbc3ca6f467fe15d Mon Sep 17 00:00:00 2001 From: Davidson Francis Date: Mon, 15 Jul 2024 22:47:57 -0300 Subject: [PATCH] Rework logging --- Makefile | 2 +- alertik.c | 79 ++------------------------------------------ log.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ log.h | 19 +++++++++++ 4 files changed, 120 insertions(+), 78 deletions(-) create mode 100644 log.c create mode 100644 log.h diff --git a/Makefile b/Makefile index 4611d24..658078b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ CFLAGS += -Wall -Wextra LDLIBS += -pthread -lcurl STRIP = strip VERSION = v0.1 -OBJS = alertik.o events.o env_events.o notifiers.o +OBJS = alertik.o events.o env_events.o notifiers.o log.o ifeq ($(LOG_FILE),yes) CFLAGS += -DUSE_FILE_AS_LOG diff --git a/alertik.c b/alertik.c index b252da1..3d0f811 100644 --- a/alertik.c +++ b/alertik.c @@ -5,7 +5,6 @@ #define _POSIX_C_SOURCE 200809L #include -#include #include #include #include @@ -22,6 +21,7 @@ #include "alertik.h" #include "events.h" #include "env_events.h" +#include "log.h" #include "notifiers.h" /* Uncomment/comment to enable/disable the following settings. */ @@ -29,7 +29,6 @@ #define FIFO_MAX 64 #define SYSLOG_PORT 5140 -#define LOG_FILE "log/log.txt" /* Circular message buffer. */ static struct circ_buffer { @@ -40,80 +39,11 @@ static struct circ_buffer { /* Sync. */ static pthread_mutex_t fifo_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t fifo_new_log_entry = PTHREAD_COND_INITIALIZER; /* Misc. */ #define LAST_SENT_THRESHOLD_SECS 10 /* Minimum time (in secs) between two */ time_t time_last_sent_notify; /* notifications. */ -static int curr_file; - -//////////////////////////////// LOGGING ////////////////////////////////////// - -/* There should *always* be a corresponding close_log_file() call. */ -static inline void open_log_file(void) -{ - struct stat sb; - - pthread_mutex_lock(&log_mutex); - if (curr_file == STDOUT_FILENO) - return; - - if (stat("log", &sb) < 0) - if (mkdir("log", 0755) < 0) - return; - - curr_file = openat(AT_FDCWD, LOG_FILE, - O_WRONLY|O_CREAT|O_APPEND, 0666); - - if (curr_file < 0) - curr_file = STDOUT_FILENO; /* fallback to stdout if can't open. */ -} - -/* This should *always* be called *after* a call to open_log_file(). */ -static void close_log_file(void) -{ - if (curr_file || curr_file == STDOUT_FILENO) - goto out; - - fsync(curr_file); - close(curr_file); -out: - pthread_mutex_unlock(&log_mutex); -} - -char *get_formatted_time(time_t time, char *time_str) -{ - strftime( - time_str, - 32, - "%Y-%m-%d %H:%M:%S", - localtime(&time) - ); - return time_str; -} - -void log_msg(const char *fmt, ...) -{ - char time_str[32] = {0}; - va_list ap; - - open_log_file(); - dprintf(curr_file, "[%s] ", get_formatted_time(time(NULL), time_str)); - va_start(ap, fmt); - vdprintf(curr_file, fmt, ap); - va_end(ap); - close_log_file(); -} - -static inline void print_log_event(struct log_event *ev) -{ - char time_str[32] = {0}; - open_log_file(); - dprintf(curr_file, "\n[%s] %s\n", - get_formatted_time(ev->timestamp, time_str), ev->msg); - close_log_file(); -} /////////////////////////////////// NETWORK /////////////////////////////////// static int push_msg_into_fifo(const char *msg, time_t timestamp); @@ -250,12 +180,7 @@ int main(void) pthread_t handler; int fd; - atexit(close_log_file); - -#ifndef USE_FILE_AS_LOG - curr_file = STDOUT_FILENO; -#endif - + log_init(); setup_notifiers(); init_environment_events(); diff --git a/log.c b/log.c new file mode 100644 index 0000000..4062c13 --- /dev/null +++ b/log.c @@ -0,0 +1,98 @@ +/* + * Alertik: a tiny 'syslog' server & notification tool for Mikrotik routers. + * This is free and unencumbered software released into the public domain. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "events.h" +#include "log.h" + +static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; +static int curr_file; + +/* There should *always* be a corresponding close_log_file() call. */ +static inline void open_log_file(void) +{ + struct stat sb; + pthread_mutex_lock(&log_mutex); + if (curr_file == STDOUT_FILENO) + return; + + if (stat("log", &sb) < 0) + if (mkdir("log", 0755) < 0) + return; + + curr_file = openat(AT_FDCWD, LOG_FILE, + O_WRONLY|O_CREAT|O_APPEND, 0666); + + if (curr_file < 0) + curr_file = STDOUT_FILENO; /* fallback to stdout if can't open. */ +} + +/* This should *always* be called *after* a call to open_log_file(). */ +static void close_log_file(void) +{ + if (curr_file || curr_file == STDOUT_FILENO) + goto out; + + fsync(curr_file); + close(curr_file); +out: + pthread_mutex_unlock(&log_mutex); +} + +/**/ +char *get_formatted_time(time_t time, char *time_str) +{ + strftime( + time_str, + 32, + "%Y-%m-%d %H:%M:%S", + localtime(&time) + ); + return time_str; +} + +/**/ +void log_msg(const char *fmt, ...) +{ + char time_str[32] = {0}; + va_list ap; + + open_log_file(); + dprintf(curr_file, "[%s] ", get_formatted_time(time(NULL), time_str)); + va_start(ap, fmt); + vdprintf(curr_file, fmt, ap); + va_end(ap); + close_log_file(); +} + +/**/ +void print_log_event(struct log_event *ev) +{ + char time_str[32] = {0}; + open_log_file(); + dprintf(curr_file, "\n[%s] %s\n", + get_formatted_time(ev->timestamp, time_str), ev->msg); + close_log_file(); +} + +/**/ +void log_init(void) { + atexit(close_log_file); +#ifndef USE_FILE_AS_LOG + curr_file = STDOUT_FILENO; +#endif +} diff --git a/log.h b/log.h new file mode 100644 index 0000000..ab292ed --- /dev/null +++ b/log.h @@ -0,0 +1,19 @@ +/* + * Alertik: a tiny 'syslog' server & notification tool for Mikrotik routers. + * This is free and unencumbered software released into the public domain. + */ + +#ifndef LOG_H +#define LOG_H + + /* Uncomment/comment to enable/disable the following settings. */ + // #define USE_FILE_AS_LOG /* stdout if commented. */ + + #define LOG_FILE "log/log.txt" + + extern char *get_formatted_time(time_t time, char *time_str); + extern void print_log_event(struct log_event *ev); + extern void log_msg(const char *fmt, ...); + extern void log_init(void); + +#endif /* LOG_H */