]> git.ipfire.org Git - collecty.git/commitdiff
daemon: Implement logging
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Sep 2025 11:48:50 +0000 (11:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 27 Sep 2025 11:48:50 +0000 (11:48 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/daemon/ctx.c
src/daemon/ctx.h
src/daemon/logging.c [new file with mode: 0644]
src/daemon/logging.h [new file with mode: 0644]
src/daemon/main.c

index f99bcdcaf3b6c1026751e8fe3467d72629985859..3ba95af24ea0d6525610e8c5c675fe7ec7bddef1 100644 (file)
@@ -91,6 +91,8 @@ bin_PROGRAMS += \
 dist_collectyd_SOURCES = \
        src/daemon/ctx.c \
        src/daemon/ctx.h \
+       src/daemon/logging.c \
+       src/daemon/logging.h \
        src/daemon/main.c
 
 collectyd_CPPFLAGS = \
index 72394e70eac9839aa2f54429c431fbdf5092dbc7..4f9296b37310d8c63ff32ef5c9cb625054a02488 100644 (file)
 
 #include <errno.h>
 #include <stdlib.h>
+#include <syslog.h>
 
 #include "ctx.h"
+#include "logging.h"
 
 struct collecty_ctx {
        int nrefs;
@@ -29,15 +31,30 @@ struct collecty_ctx {
        // Logging
        struct {
                int level;
+
+               // Callback
+               collecty_log_callback callback;
+               void* data;
        } log;
 };
 
+static int collecty_ctx_setup_logging(collecty_ctx* ctx) {
+       // Log informational messages
+       ctx->log.level = LOG_INFO;
+
+       // Setup a logging callback
+       ctx->log.callback = collecty_log_syslog;
+
+       return 0;
+}
+
 static void collecty_ctx_free(collecty_ctx* ctx) {
        return;
 }
 
 int collecty_ctx_create(collecty_ctx** ctx) {
        struct collecty_ctx* self = NULL;
+       int r;
 
        // Allocate some memory
        self = calloc(1, sizeof(*self));
@@ -47,10 +64,20 @@ int collecty_ctx_create(collecty_ctx** ctx) {
        // Initialize the reference counter
        self->nrefs = 1;
 
+       // Setup logging
+       r = collecty_ctx_setup_logging(self);
+       if (r < 0)
+               goto ERROR;
+
        // Return the pointer
        *ctx = self;
-
        return 0;
+
+ERROR:
+       if (self)
+               collecty_ctx_unref(self);
+
+       return r;
 }
 
 collecty_ctx* collecty_ctx_ref(collecty_ctx* ctx) {
@@ -70,6 +97,30 @@ collecty_ctx* collecty_ctx_unref(collecty_ctx* ctx) {
 /*
        Logging
 */
+
+int collecty_ctx_get_log_level(collecty_ctx* ctx) {
+       return ctx->log.level;
+}
+
 void collecty_ctx_set_log_level(collecty_ctx* ctx, int level) {
        ctx->log.level = level;
 }
+
+void collecty_ctx_set_log_callback(collecty_ctx* ctx,
+               collecty_log_callback callback, void* data) {
+       ctx->log.callback = callback;
+       ctx->log.data     = data;
+}
+
+void collecty_ctx_log(collecty_ctx* self, int level,
+               const char* file, int line, const char* fn, const char* format, ...) {
+       va_list args;
+
+       // Return if the callback hasn't been set
+       if (!self->log.callback)
+               return;
+
+       va_start(args, format);
+       self->log.callback(self->log.data, level, file, line, fn, format, args);
+       va_end(args);
+}
index 5dedd7ee95e52fa3cf0d78c2eb816d04f1d48d7d..66387877e2648e0583b6a2381b661c9980185e73 100644 (file)
@@ -29,6 +29,15 @@ collecty_ctx* collecty_ctx_ref(collecty_ctx* ctx);
 collecty_ctx* collecty_ctx_unref(collecty_ctx* ctx);
 
 // Logging
+#include "logging.h"
+
+int collecty_ctx_get_log_level(collecty_ctx* ctx);
 void collecty_ctx_set_log_level(collecty_ctx* ctx, int level);
 
+void collecty_ctx_set_log_callback(collecty_ctx* ctx,
+       collecty_log_callback callback, void* data);
+
+void collecty_ctx_log(collecty_ctx* self, int level,
+       const char* file, int line, const char* fn, const char* format, ...);
+
 #endif /* COLLECTY_CTX_H */
diff --git a/src/daemon/logging.c b/src/daemon/logging.c
new file mode 100644 (file)
index 0000000..0a7118a
--- /dev/null
@@ -0,0 +1,75 @@
+/*#############################################################################
+#                                                                             #
+# collecty - A system statistics collection daemon for IPFire                 #
+# Copyright (C) 2025 IPFire Development Team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <systemd/sd-journal.h>
+
+#include "ctx.h"
+#include "logging.h"
+
+void collecty_log_stderr(void* data, int priority, const char* file,
+               int line, const char* fn, const char* format, va_list args) {
+       fprintf(stderr, PACKAGE_NAME ": ");
+
+       // Optionally log the function name
+       if (fn)
+               fprintf(stderr, "%s: ", fn);
+
+       vfprintf(stderr, format, args);
+}
+
+void collecty_log_syslog(void* data, int priority, const char* file,
+               int line, const char* fn, const char* format, va_list args) {
+       char* buffer = NULL;
+       int r;
+
+       // Format log message
+       r = vasprintf(&buffer, format, args);
+       if (r < 0)
+               return;
+
+       // Send message to journald
+       r = sd_journal_send(
+               "MESSAGE=%s", buffer,
+               "PRIORITY=%d", priority,
+
+               // Syslog compat
+               "SYSLOG_IDENTIFIER=" PACKAGE_NAME,
+
+               // Debugging stuff
+               "ERRNO=%d", errno,
+               "CODE_FILE=%s", file,
+               "CODE_LINE=%d", line,
+               "CODE_FUNC=%s", fn,
+
+               NULL
+       );
+
+       // Fall back to standard output
+       if (r)
+               sd_journal_perror(buffer);
+
+       // Cleanup
+       if (buffer)
+               free(buffer);
+}
diff --git a/src/daemon/logging.h b/src/daemon/logging.h
new file mode 100644 (file)
index 0000000..092bf51
--- /dev/null
@@ -0,0 +1,58 @@
+/*#############################################################################
+#                                                                             #
+# collecty - A system statistics collection daemon for IPFire                 #
+# Copyright (C) 2025 IPFire Development Team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef COLLECTY_LOGGING_H
+#define COLLECTY_LOGGING_H
+
+#include <stdarg.h>
+
+typedef void (*collecty_log_callback)(void* data, int priority, const char* file,
+       int line, const char* fn, const char* format, va_list args);
+
+#include "ctx.h"
+
+void collecty_log_stderr(void* data, int priority, const char* file,
+       int line, const char* fn, const char* format, va_list args)
+       __attribute__((format(printf, 6, 0)));
+void collecty_log_syslog(void* data, int priority, const char* file,
+       int line, const char* fn, const char* format, va_list args)
+       __attribute__((format(printf, 6, 0)));
+
+#define collecty_ctx_log_condition(ctx, level, arg...) \
+       do { \
+               if (collecty_ctx_get_log_level(ctx) >= level) \
+                       collecty_ctx_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, ## arg); \
+       } while (0)
+
+#define INFO(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_INFO, ## arg)
+#define WARN(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_WARNING, ## arg)
+#define ERROR(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_ERR, ## arg)
+
+// This function does absolutely nothing
+static inline void __attribute__((always_inline, format(printf, 2, 3)))
+       collecty_ctx_log_null(collecty_ctx* ctx, const char *format, ...) {}
+
+#ifdef ENABLE_DEBUG
+#      define DEBUG(ctx, arg...) collecty_ctx_log_condition(ctx, LOG_DEBUG, ## arg)
+#else
+#      define DEBUG collecty_ctx_log_null
+#endif
+
+#endif /* COLLECTY_LOGGING_H */
index bf8246ce31bab02630891f4ecc4dc7bae8d93fa8..92dff8e9308d84f7b51a84472048c6e2639a0028 100644 (file)
@@ -24,6 +24,7 @@
 #include <syslog.h>
 
 #include "ctx.h"
+#include "logging.h"
 
 const char* argp_program_version = PACKAGE_VERSION;
 
@@ -43,6 +44,10 @@ static error_t parse(int key, char* arg, struct argp_state* state) {
 
        switch (key) {
                case OPT_DEBUG:
+                       // Log to stdout
+                       collecty_ctx_set_log_callback(ctx, collecty_log_stderr, NULL);
+
+                       // Increase the log level
                        collecty_ctx_set_log_level(ctx, LOG_DEBUG);
                        break;
 
@@ -69,10 +74,12 @@ int main(int argc, char* argv[]) {
                goto ERROR;
 
        // Parse command line arguments
-       r = argp_parse(&parser, argc, argv, ARGP_NO_ARGS, &arg_index, &ctx);
+       r = argp_parse(&parser, argc, argv, ARGP_NO_ARGS, &arg_index, ctx);
        if (r)
                goto ERROR;
 
+       INFO(ctx, "Daemon initialized\n");
+
 ERROR:
        if (ctx)
                collecty_ctx_unref(ctx);