changed logger to behave more like printf + added possibility to specify write function

Fri, 08 Feb 2013 10:37:24 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 08 Feb 2013 10:37:24 +0100
changeset 81
86a23238d8a1
parent 80
0125e4089f88
child 82
6068d965328b

changed logger to behave more like printf + added possibility to specify write function

test/logging_tests.c file | annotate | diff | comparison | revisions
ucx/buffer.h file | annotate | diff | comparison | revisions
ucx/logging.c file | annotate | diff | comparison | revisions
ucx/logging.h file | annotate | diff | comparison | revisions
--- a/test/logging_tests.c	Wed Feb 06 14:35:15 2013 +0100
+++ b/test/logging_tests.c	Fri Feb 08 10:37:24 2013 +0100
@@ -12,16 +12,16 @@
             UCX_LOGGER_INFO, UCX_LOGGER_SOURCE | UCX_LOGGER_LEVEL);
     
     UCX_TEST_BEGIN
-    ucx_logger_info(logger, ST("allright"));
-    ucx_logger_trace(logger, ST("dont log this!"));
-    ucx_logger_error(logger, ST("error!"));
+    ucx_logger_info(logger, "allright");
+    ucx_logger_trace(logger, "dont log this!");
+    ucx_logger_error(logger, "error %d!", 42);
     fseek(stream, 0, SEEK_SET);
     int r = fread(buffer, 1, 100, stream);
     
-    size_t expected_length = 73;
+    size_t expected_length = 76;
     UCX_TEST_ASSERT(r == expected_length && strncmp(buffer,
             "[INFO] logging_tests.c:15 - allright\n"
-            "[ERROR] logging_tests.c:17 - error!\n", expected_length) == 0, "incorrect logs");
+            "[ERROR] logging_tests.c:17 - error 42!\n", expected_length) == 0, "incorrect logs");
 
     UCX_TEST_END
 
--- a/ucx/buffer.h	Wed Feb 06 14:35:15 2013 +0100
+++ b/ucx/buffer.h	Fri Feb 08 10:37:24 2013 +0100
@@ -67,11 +67,6 @@
 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
         UcxBuffer *buffer);
 
-/* when autoextend is enabled, ensure you get the latest pointer to the data */
-//define ucx_buffer_write(data, itemsize, nitems, buffer) \
-//    ucx_bufio(data, itemsize, nitems, buffer, 0)
-//define ucx_buffer_read(data, itemsize, nitems, buffer) \
-//        ucx_bufio(data, itemsize, nitems, buffer, 1)
 int ucx_buffer_putc(UcxBuffer *b, int c);
 int ucx_buffer_getc(UcxBuffer *b);
 
--- a/ucx/logging.c	Wed Feb 06 14:35:15 2013 +0100
+++ b/ucx/logging.c	Fri Feb 08 10:37:24 2013 +0100
@@ -1,11 +1,13 @@
 #include "logging.h"
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 
 UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) {
     UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
     if (logger != NULL) {
         logger->stream = stream;
+        logger->writer = fwrite;
         logger->level = level;
         logger->mask = mask;
         logger->levels = ucx_map_new(8);
@@ -29,35 +31,50 @@
     free(logger);
 }
 
-void ucx_logger_log(UcxLogger *logger, unsigned int level,
-        const sstr_t message, const char* file, const unsigned int line) {
+void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
+        size_t(*writer)(const void*,size_t,size_t,FILE*)) {
+    if (stream) {
+        logger->stream = stream;
+    }
+    if (writer) {
+        logger->writer = writer;
+    }
+}
+
+void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
+        const unsigned int line, const char *format, ...) {
     if (level <= logger->level) {
-        size_t n = message.length;
-        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
-            n += strlen(file);
-            n += 10; // line
-        }
-        // TODO: add k bytes for timestamp
-        n += 16; // extra space for fill characters (:, -, etc.)
-        
-        char msg[n];
-        off_t k = 0;
+        const size_t max = 4096; // estimated maximum message length
+        char msg[max];
+        char *text;
+        size_t k = 0;
+        size_t n;
         
         if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
-            k += sprintf(msg+k, "%s ", (char*)
-                    ucx_map_int_get(logger->levels, level));
+            text = (char*) ucx_map_int_get(logger->levels, level);
+            n = strlen(text);
+            memcpy(msg+k, text, n);
+            k += n;
+            msg[k++] = ' ';
         }
         // TODO: timestamp
         if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
-            k += sprintf(msg+k, "%s:%d ", file, line);
+            n = strlen(file);
+            memcpy(msg+k, file, n);
+            k += n;
+            k += sprintf(msg+k, ":%d ", line);
         }
         
-        msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0;
-        strncat(msg, message.ptr, message.length);
-        k += message.length;
+        msg[k++] = '-'; msg[k++] = ' ';
+        
+        va_list args;
+        va_start (args, format);
+        k += vsnprintf(msg+k, max-k-1, format, args);
+        va_end (args);        
+        
         msg[k++] = '\n';
         
-        fwrite(msg, 1, k, logger->stream);
+        logger->writer(msg, 1, k, logger->stream);
         fflush(logger->stream);
     }
 }
--- a/ucx/logging.h	Wed Feb 06 14:35:15 2013 +0100
+++ b/ucx/logging.h	Fri Feb 08 10:37:24 2013 +0100
@@ -22,6 +22,7 @@
 
 typedef struct {
     FILE *stream;
+    size_t(*writer)(const void*, size_t, size_t, FILE*);
     unsigned int level;
     unsigned int mask;
     UcxMap* levels;
@@ -30,16 +31,30 @@
 UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask);
 void ucx_logger_free(UcxLogger* logger);
 
-void ucx_logger_log(UcxLogger *logger, unsigned int level,
-        const sstr_t message, const char* file, const unsigned int line);
-#define ucx_logger_error(l,m) \
-    ucx_logger_log(l, UCX_LOGGER_ERROR, m, __FILE__, __LINE__)
-#define ucx_logger_info(l,m) \
-    ucx_logger_log(l, UCX_LOGGER_INFO, m, __FILE__, __LINE__)
-#define ucx_logger_warn(l,m) \
-    ucx_logger_log(l, UCX_LOGGER_WARN, m, __FILE__, __LINE__)
-#define ucx_logger_trace(l,m) \
-    ucx_logger_log(l, UCX_LOGGER_TRACE, m, __FILE__, __LINE__)
+/**
+ * Sets the output stream and writer for this logger.
+ * The parameters stream and writer may be NULL, if they shall remain unchanged
+ * in the logger.
+ * l
+ * @param logger The logger
+ * @param stream The stream the logger shall log to
+ * @param writer A pointer to the write function
+ */
+void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
+        size_t(*writer)(const void*,size_t,size_t,FILE*));
+
+void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
+        const unsigned int line, const char* format, ...);
+#define ucx_logger_log(logger, level, format...) \
+    ucx_logger_logf(logger, level, __FILE__, __LINE__, format)
+#define ucx_logger_error(logger,format...) \
+    ucx_logger_log(logger, UCX_LOGGER_ERROR, format)
+#define ucx_logger_info(logger,format...) \
+    ucx_logger_log(logger, UCX_LOGGER_INFO, format)
+#define ucx_logger_warn(logger,format...) \
+    ucx_logger_log(logger, UCX_LOGGER_WARN, format)
+#define ucx_logger_trace(logger,format...) \
+    ucx_logger_log(logger, UCX_LOGGER_TRACE, format)
 
 #ifdef __cplusplus
 }

mercurial