logd: add udebug support
authorFelix Fietkau <nbd@nbd.name>
Thu, 30 Nov 2023 12:42:09 +0000 (13:42 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 30 Nov 2023 12:42:09 +0000 (13:42 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
CMakeLists.txt
log/logd.c
log/syslog.c
log/syslog.h

index 62de1d4b96480eff5e8ee9069ef9d8f130e982d9..f2636ace95278515badc0325d78fcb12c590fa59 100644 (file)
@@ -57,7 +57,7 @@ INSTALL(TARGETS validate_data
 )
 
 ADD_EXECUTABLE(logd log/logd.c log/syslog.c)
-TARGET_LINK_LIBRARIES(logd ubox ubus)
+TARGET_LINK_LIBRARIES(logd ubox ubus udebug)
 INSTALL(TARGETS logd
        RUNTIME DESTINATION sbin
 )
index 94c7b2f8271618773c626b1bf70d736c1fd4b42e..96042964a5f8c07041d4e899fc7f0fe31e910b9c 100644 (file)
@@ -24,6 +24,7 @@
 #include <libubox/blobmsg.h>
 #include <libubox/list.h>
 #include <libubox/ustream.h>
+#include <libubox/utils.h>
 #include <libubus.h>
 
 #include "syslog.h"
@@ -31,6 +32,7 @@
 int debug = 0;
 static struct blob_buf b;
 static struct ubus_auto_conn conn;
+static struct udebug_ubus udebug;
 static LIST_HEAD(clients);
 
 enum {
@@ -261,6 +263,7 @@ main(int argc, char **argv)
        log_init(log_size);
        conn.cb = ubus_connect_handler;
        ubus_auto_connect(&conn);
+       udebug_ubus_init(&udebug, &conn.ctx, "log", log_udebug_config);
        p = getpwnam("logd");
        if (p) {
                if (setgid(p->pw_gid) < 0) {
@@ -274,6 +277,7 @@ main(int argc, char **argv)
                }
        }
        uloop_run();
+       udebug_ubus_free(&udebug);
        log_shutdown();
        uloop_done();
        ubus_auto_shutdown(&conn);
index 0e1f2a92a8f8f1527b192a770c4af8cfdb6a0d64..785452397fa833f6d1fa84fda3d3b75caaa36a55 100644 (file)
@@ -31,6 +31,7 @@
 #include <libubox/uloop.h>
 #include <libubox/usock.h>
 #include <libubox/ustream.h>
+#include <libubox/utils.h>
 
 #include "syslog.h"
 
@@ -48,6 +49,40 @@ static struct log_head *log, *log_end, *oldest, *newest;
 static int current_id = 0;
 static regex_t pat_prio;
 static regex_t pat_tstamp;
+static struct udebug ud;
+static struct udebug_buf udb_kernel, udb_user, udb_debug;
+static const struct udebug_buf_meta meta_kernel = {
+       .name = "kernel",
+       .format = UDEBUG_FORMAT_STRING,
+};
+static const struct udebug_buf_meta meta_user = {
+       .name = "syslog",
+       .format = UDEBUG_FORMAT_STRING,
+};
+static const struct udebug_buf_meta meta_debug = {
+       .name = "debug",
+       .format = UDEBUG_FORMAT_STRING,
+};
+static struct udebug_ubus_ring rings[] = {
+       {
+               .buf = &udb_kernel,
+               .meta = &meta_kernel,
+               .default_entries = 1024,
+               .default_size = 65536,
+       },
+       {
+               .buf = &udb_user,
+               .meta = &meta_user,
+               .default_entries = 1024,
+               .default_size = 65536,
+       },
+       {
+               .buf = &udb_debug,
+               .meta = &meta_debug,
+               .default_entries = 1024,
+               .default_size = 65536,
+       },
+};
 
 static struct log_head*
 log_next(struct log_head *h, int size)
@@ -57,10 +92,61 @@ log_next(struct log_head *h, int size)
        return (n >= log_end) ? (log) : (n);
 }
 
+static uint64_t
+get_kernel_ts(const char *ts_sec, const char *ts_nsec)
+{
+       uint64_t ts = strtoull(ts_sec, NULL, 10) * UDEBUG_TS_SEC +
+                     strtoull(ts_nsec, NULL, 10) / 1000;
+       struct timespec wall, mono;
+
+       if (clock_gettime(CLOCK_REALTIME, &wall) ||
+           clock_gettime(CLOCK_MONOTONIC, &mono))
+               return 0;
+
+       ts += (wall.tv_sec - mono.tv_sec) * UDEBUG_TS_SEC;
+       ts += (wall.tv_nsec - mono.tv_nsec) / 1000;
+
+       return ts;
+}
+
+static void
+log_add_udebug(int priority, char *buf, int size, int source)
+{
+       regmatch_t matches[4];
+       struct udebug_buf *udb;
+       uint64_t ts = 0;
+
+       if (source == SOURCE_KLOG)
+               udb = &udb_kernel;
+       else if ((priority & LOG_FACMASK) == LOG_LOCAL7)
+               udb = &udb_debug;
+       else
+               udb = &udb_user;
+
+       if (!udebug_buf_valid(udb))
+               return;
+
+       if (source == SOURCE_KLOG &&
+           !regexec(&pat_tstamp, buf, 4, matches, 0)) {
+               ts = get_kernel_ts(&buf[matches[1].rm_so], &buf[matches[2].rm_so]);
+               buf += matches[3].rm_so;
+               size -= matches[3].rm_so;
+       }
+
+       if (!ts)
+               ts = udebug_timestamp();
+
+       udebug_entry_init_ts(udb, ts);
+       udebug_entry_printf(udb, "<%d>", priority);
+       udebug_entry_append(udb, buf, size - 1);
+       udebug_entry_add(udb);
+}
+
+
 void
 log_add(char *buf, int size, int source)
 {
-       regmatch_t matches[4];
+       regmatch_t matches[3];
        struct log_head *next;
        int priority = 0;
        int ret;
@@ -93,22 +179,17 @@ log_add(char *buf, int size, int source)
                buf += matches[2].rm_so;
        }
 
-#if 0
-       /* strip kernel timestamp */
-       ret = regexec(&pat_tstamp,buf, 4, matches, 0);
-       if ((source == SOURCE_KLOG) && !ret) {
-               size -= matches[3].rm_so;
-               buf += matches[3].rm_so;
-       }
-#endif
-
        /* strip syslog timestamp */
        if ((source == SOURCE_SYSLOG) && (size > SYSLOG_PADDING) && (buf[SYSLOG_PADDING - 1] == ' ')) {
                size -= SYSLOG_PADDING;
                buf += SYSLOG_PADDING;
        }
 
-       //fprintf(stderr, "-> %d - %s\n", priority, buf);
+       log_add_udebug(priority, buf, size, source);
+
+       /* debug message */
+       if ((priority & LOG_FACMASK) == LOG_LOCAL7)
+               return;
 
        /* find new oldest entry */
        next = log_next(newest, size);
@@ -278,6 +359,12 @@ log_buffer_init(int size)
        return 0;
 }
 
+void log_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data,
+                      bool enabled)
+{
+       udebug_ubus_apply_config(&ud, rings, ARRAY_SIZE(rings), data, enabled);
+}
+
 void
 log_init(int _log_size)
 {
@@ -285,13 +372,18 @@ log_init(int _log_size)
                log_size = _log_size;
 
        regcomp(&pat_prio, "^<([0-9]*)>(.*)", REG_EXTENDED);
-       regcomp(&pat_tstamp, "^\[[ 0]*([0-9]*).([0-9]*)] (.*)", REG_EXTENDED);
+       regcomp(&pat_tstamp, "^\\[[ 0]*([0-9]*).([0-9]*)\\] (.*)", REG_EXTENDED);
 
        if (log_buffer_init(log_size)) {
                fprintf(stderr, "Failed to allocate log memory\n");
                exit(-1);
        }
 
+       udebug_init(&ud);
+       udebug_auto_connect(&ud, NULL);
+       for (size_t i = 0; i < ARRAY_SIZE(rings); i++)
+               udebug_ubus_ring_init(&ud, &rings[i]);
+
        syslog_open();
        klog_open();
        openlog("sysinit", LOG_CONS, LOG_DAEMON);
index 56ccbb9d9020ef63b2e99e90b87b476db4888a4b..b6419e5d66a89c8b646ac2d9016e704e828c4632 100644 (file)
@@ -16,6 +16,8 @@
 
 #define LOG_LINE_SIZE          1024
 
+#include <udebug.h>
+
 enum {
        SOURCE_KLOG = 0,
        SOURCE_SYSLOG = 1,
@@ -40,5 +42,7 @@ struct log_head* log_list(int count, struct log_head *h);
 int log_buffer_init(int size);
 void log_add(char *buf, int size, int source);
 void ubus_notify_log(struct log_head *l);
+void log_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data,
+                      bool enabled);
 
 #endif