]> git.ipfire.org Git - pakfire.git/commitdiff
log buffer: Store a timestamp with each line
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 7 Feb 2025 11:40:23 +0000 (11:40 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 7 Feb 2025 11:40:23 +0000 (11:40 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/job.c
src/pakfire/log_buffer.c
src/pakfire/log_buffer.h
tests/libpakfire/log_buffer.c

index 6e28ff98fdf0e27799b83c136b2ba9283c4602a0..d52946870d916ef1352f27c008f4eae7aee17f5a 100644 (file)
@@ -816,6 +816,7 @@ ERROR:
 
 static int pakfire_job_stream(sd_event_source* s, void* data) {
        struct pakfire_job* job = data;
+       struct timeval timestamp = {};
        char* line = NULL;
        size_t length = 0;
        int priority;
@@ -824,7 +825,7 @@ static int pakfire_job_stream(sd_event_source* s, void* data) {
        // Send as many log messages as possible
        for (;;) {
                // Try to dequeue a line from the log buffer
-               r = pakfire_log_buffer_dequeue(job->log.buffer, &priority, &line, &length);
+               r = pakfire_log_buffer_dequeue(job->log.buffer, &timestamp, &priority, &line, &length);
                if (r < 0) {
                        ERROR(job->ctx, "Could not dequeue from the log buffer: %s\n", strerror(-r));
                        return r;
index 3cfafac8a5c427b3675fbf6d6022e126c99c7b8a..dbf3f103fd26be08d6ea67553ecb89e0353fbb1d 100644 (file)
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/queue.h>
+#include <sys/time.h>
 
 #include <pakfire/ctx.h>
 #include <pakfire/log_buffer.h>
@@ -28,6 +29,7 @@
 struct pakfire_log_line {
        STAILQ_ENTRY(pakfire_log_line) nodes;
 
+       struct timeval timestamp;
        int priority;
        char* line;
        size_t length;
@@ -97,12 +99,13 @@ struct pakfire_log_buffer* pakfire_log_buffer_unref(struct pakfire_log_buffer* b
 }
 
 static int pakfire_log_buffer_drop(struct pakfire_log_buffer* self) {
+       struct timeval timestamp = {};
        int priority = 0;
        char* line = NULL;
        int r;
 
        // Dequeue one line
-       r = pakfire_log_buffer_dequeue(self, &priority, &line, NULL);
+       r = pakfire_log_buffer_dequeue(self, &timestamp, &priority, &line, NULL);
        if (r < 0)
                return r;
 
@@ -136,6 +139,14 @@ int pakfire_log_buffer_enqueue(struct pakfire_log_buffer* buffer, int priority,
        if (!l)
                return -errno;
 
+       // Store the current time
+       r = gettimeofday(&l->timestamp, NULL);
+       if (r < 0) {
+               ERROR(buffer->ctx, "Could not determine the current time: %m\n");
+               r = -errno;
+               goto ERROR;
+       }
+
        // Store the priority
        l->priority = priority;
 
@@ -162,17 +173,19 @@ ERROR:
        return -errno;
 }
 
-int pakfire_log_buffer_dequeue(struct pakfire_log_buffer* buffer, int* priority, char** line, size_t* length) {
+int pakfire_log_buffer_dequeue(struct pakfire_log_buffer* buffer,
+               struct timeval* timestamp, int* priority, char** line, size_t* length) {
        struct pakfire_log_line* l = NULL;
 
-       // Priority & Line must be set, length is optional
-       if (!priority || !line)
+       // Timestamp, priority & line must be set, length is optional
+       if (!timestamp || !priority || !line)
                return -EINVAL;
 
        // Fetch the first line
        l = STAILQ_FIRST(&buffer->lines);
        if (!l) {
-               // Reset all pointers
+               // Reset all values
+               (*timestamp).tv_sec = (*timestamp).tv_usec = 0;
                *priority = -1;
                *line = NULL;
 
@@ -182,6 +195,9 @@ int pakfire_log_buffer_dequeue(struct pakfire_log_buffer* buffer, int* priority,
                return 0;
        }
 
+       // Return the timestamp
+       *timestamp = l->timestamp;
+
        // Return the priority
        *priority = l->priority;
 
index 9727a79a1e7aeb2f3d36cc11825527dce1312ac7..09ccb9ea14c8673777009e5da9d232e109951524 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PAKFIRE_LOG_BUFFER_H
 #define PAKFIRE_LOG_BUFFER_H
 
+#include <sys/time.h>
+
 #include <pakfire/ctx.h>
 
 /*
@@ -34,7 +36,8 @@ struct pakfire_log_buffer* pakfire_log_buffer_ref(struct pakfire_log_buffer* buf
 struct pakfire_log_buffer* pakfire_log_buffer_unref(struct pakfire_log_buffer* buffer);
 
 int pakfire_log_buffer_enqueue(struct pakfire_log_buffer* buffer, int priority, const char* line, ssize_t length);
-int pakfire_log_buffer_dequeue(struct pakfire_log_buffer* buffer, int* priority, char** line, size_t* length);
+int pakfire_log_buffer_dequeue(struct pakfire_log_buffer* buffer,
+       struct timeval* timestamp, int* priority, char** line, size_t* length);
 
 int pakfire_log_buffer_dump(struct pakfire_log_buffer* buffer, char** result, size_t* length);
 
index d7a5c3a4358b9afe061731204aa8e3825461e754..26f2e010b39c87432ec39f7ae422d46e24c3753b 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <sys/time.h>
+
 #include <pakfire/log_buffer.h>
 
 #include "../testsuite.h"
 
 static int test_simple(const struct test* t) {
        struct pakfire_log_buffer* buffer = NULL;
+       struct timeval timestamp = {};
        char* line = NULL;
        size_t length = 0;
        int priority = 0;
@@ -37,7 +40,7 @@ static int test_simple(const struct test* t) {
        ASSERT_SUCCESS(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "CCC", -1));
 
        // Dequeue the first string
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
 
        ASSERT_EQUALS(priority, LOG_DEBUG);
        ASSERT_STRING_EQUALS(line, "A");
@@ -45,7 +48,7 @@ static int test_simple(const struct test* t) {
        free(line);
 
        // Dequeue the second string
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
 
        ASSERT_EQUALS(priority, LOG_DEBUG);
        ASSERT_STRING_EQUALS(line, "BB");
@@ -53,7 +56,7 @@ static int test_simple(const struct test* t) {
        free(line);
 
        // Dequeue the third string
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
 
        ASSERT_EQUALS(priority, LOG_DEBUG);
        ASSERT_STRING_EQUALS(line, "CCC");
@@ -61,7 +64,7 @@ static int test_simple(const struct test* t) {
        free(line);
 
        // Dequeue more than we put in
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
 
        ASSERT_EQUALS(priority, -1);
        ASSERT_EQUALS(line, NULL);
@@ -79,6 +82,7 @@ FAIL:
 
 static int test_wrong_usage(const struct test* t) {
        struct pakfire_log_buffer* buffer = NULL;
+       struct timeval timestamp = {};
        int priority = -1;
        char* line = NULL;
        int r = EXIT_FAILURE;
@@ -91,8 +95,9 @@ static int test_wrong_usage(const struct test* t) {
        ASSERT_ERROR(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, NULL, -1), EINVAL);
 
        // Wrong dequeue
-       ASSERT_ERROR(pakfire_log_buffer_dequeue(buffer, NULL, &line, NULL), EINVAL);
-       ASSERT_ERROR(pakfire_log_buffer_dequeue(buffer, &priority, NULL, NULL), EINVAL);
+       ASSERT_ERROR(pakfire_log_buffer_dequeue(buffer, &timestamp, NULL, &line, NULL), EINVAL);
+       ASSERT_ERROR(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, NULL, NULL), EINVAL);
+       ASSERT_ERROR(pakfire_log_buffer_dequeue(buffer, NULL, &priority, NULL, NULL), EINVAL);
 
        // Everything passed
        r = EXIT_SUCCESS;
@@ -106,6 +111,7 @@ FAIL:
 
 static int test_full(const struct test* t) {
        struct pakfire_log_buffer* buffer = NULL;
+       struct timeval timestamp = {};
        char* line = NULL;
        size_t length = 0;
        int priority = 0;
@@ -122,15 +128,15 @@ static int test_full(const struct test* t) {
        ASSERT_SUCCESS(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "Line 3", -1));
 
        // On dequeue we should now miss Line 1, but get Line 2 instead
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
        ASSERT_STRING_EQUALS(line, "Line 2");
 
        // On the next iteration, we should get Line 3
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
        ASSERT_STRING_EQUALS(line, "Line 3");
 
        // On the next iteration, the buffer should be empty
-       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &timestamp, &priority, &line, &length));
        ASSERT(line == NULL);
 
        // Everything passed