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
     1.1 --- a/test/logging_tests.c	Wed Feb 06 14:35:15 2013 +0100
     1.2 +++ b/test/logging_tests.c	Fri Feb 08 10:37:24 2013 +0100
     1.3 @@ -12,16 +12,16 @@
     1.4              UCX_LOGGER_INFO, UCX_LOGGER_SOURCE | UCX_LOGGER_LEVEL);
     1.5      
     1.6      UCX_TEST_BEGIN
     1.7 -    ucx_logger_info(logger, ST("allright"));
     1.8 -    ucx_logger_trace(logger, ST("dont log this!"));
     1.9 -    ucx_logger_error(logger, ST("error!"));
    1.10 +    ucx_logger_info(logger, "allright");
    1.11 +    ucx_logger_trace(logger, "dont log this!");
    1.12 +    ucx_logger_error(logger, "error %d!", 42);
    1.13      fseek(stream, 0, SEEK_SET);
    1.14      int r = fread(buffer, 1, 100, stream);
    1.15      
    1.16 -    size_t expected_length = 73;
    1.17 +    size_t expected_length = 76;
    1.18      UCX_TEST_ASSERT(r == expected_length && strncmp(buffer,
    1.19              "[INFO] logging_tests.c:15 - allright\n"
    1.20 -            "[ERROR] logging_tests.c:17 - error!\n", expected_length) == 0, "incorrect logs");
    1.21 +            "[ERROR] logging_tests.c:17 - error 42!\n", expected_length) == 0, "incorrect logs");
    1.22  
    1.23      UCX_TEST_END
    1.24  
     2.1 --- a/ucx/buffer.h	Wed Feb 06 14:35:15 2013 +0100
     2.2 +++ b/ucx/buffer.h	Fri Feb 08 10:37:24 2013 +0100
     2.3 @@ -67,11 +67,6 @@
     2.4  size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
     2.5          UcxBuffer *buffer);
     2.6  
     2.7 -/* when autoextend is enabled, ensure you get the latest pointer to the data */
     2.8 -//define ucx_buffer_write(data, itemsize, nitems, buffer) \
     2.9 -//    ucx_bufio(data, itemsize, nitems, buffer, 0)
    2.10 -//define ucx_buffer_read(data, itemsize, nitems, buffer) \
    2.11 -//        ucx_bufio(data, itemsize, nitems, buffer, 1)
    2.12  int ucx_buffer_putc(UcxBuffer *b, int c);
    2.13  int ucx_buffer_getc(UcxBuffer *b);
    2.14  
     3.1 --- a/ucx/logging.c	Wed Feb 06 14:35:15 2013 +0100
     3.2 +++ b/ucx/logging.c	Fri Feb 08 10:37:24 2013 +0100
     3.3 @@ -1,11 +1,13 @@
     3.4  #include "logging.h"
     3.5  #include <stdlib.h>
     3.6  #include <string.h>
     3.7 +#include <stdarg.h>
     3.8  
     3.9  UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) {
    3.10      UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
    3.11      if (logger != NULL) {
    3.12          logger->stream = stream;
    3.13 +        logger->writer = fwrite;
    3.14          logger->level = level;
    3.15          logger->mask = mask;
    3.16          logger->levels = ucx_map_new(8);
    3.17 @@ -29,35 +31,50 @@
    3.18      free(logger);
    3.19  }
    3.20  
    3.21 -void ucx_logger_log(UcxLogger *logger, unsigned int level,
    3.22 -        const sstr_t message, const char* file, const unsigned int line) {
    3.23 +void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
    3.24 +        size_t(*writer)(const void*,size_t,size_t,FILE*)) {
    3.25 +    if (stream) {
    3.26 +        logger->stream = stream;
    3.27 +    }
    3.28 +    if (writer) {
    3.29 +        logger->writer = writer;
    3.30 +    }
    3.31 +}
    3.32 +
    3.33 +void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
    3.34 +        const unsigned int line, const char *format, ...) {
    3.35      if (level <= logger->level) {
    3.36 -        size_t n = message.length;
    3.37 -        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
    3.38 -            n += strlen(file);
    3.39 -            n += 10; // line
    3.40 -        }
    3.41 -        // TODO: add k bytes for timestamp
    3.42 -        n += 16; // extra space for fill characters (:, -, etc.)
    3.43 -        
    3.44 -        char msg[n];
    3.45 -        off_t k = 0;
    3.46 +        const size_t max = 4096; // estimated maximum message length
    3.47 +        char msg[max];
    3.48 +        char *text;
    3.49 +        size_t k = 0;
    3.50 +        size_t n;
    3.51          
    3.52          if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
    3.53 -            k += sprintf(msg+k, "%s ", (char*)
    3.54 -                    ucx_map_int_get(logger->levels, level));
    3.55 +            text = (char*) ucx_map_int_get(logger->levels, level);
    3.56 +            n = strlen(text);
    3.57 +            memcpy(msg+k, text, n);
    3.58 +            k += n;
    3.59 +            msg[k++] = ' ';
    3.60          }
    3.61          // TODO: timestamp
    3.62          if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
    3.63 -            k += sprintf(msg+k, "%s:%d ", file, line);
    3.64 +            n = strlen(file);
    3.65 +            memcpy(msg+k, file, n);
    3.66 +            k += n;
    3.67 +            k += sprintf(msg+k, ":%d ", line);
    3.68          }
    3.69          
    3.70 -        msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0;
    3.71 -        strncat(msg, message.ptr, message.length);
    3.72 -        k += message.length;
    3.73 +        msg[k++] = '-'; msg[k++] = ' ';
    3.74 +        
    3.75 +        va_list args;
    3.76 +        va_start (args, format);
    3.77 +        k += vsnprintf(msg+k, max-k-1, format, args);
    3.78 +        va_end (args);        
    3.79 +        
    3.80          msg[k++] = '\n';
    3.81          
    3.82 -        fwrite(msg, 1, k, logger->stream);
    3.83 +        logger->writer(msg, 1, k, logger->stream);
    3.84          fflush(logger->stream);
    3.85      }
    3.86  }
     4.1 --- a/ucx/logging.h	Wed Feb 06 14:35:15 2013 +0100
     4.2 +++ b/ucx/logging.h	Fri Feb 08 10:37:24 2013 +0100
     4.3 @@ -22,6 +22,7 @@
     4.4  
     4.5  typedef struct {
     4.6      FILE *stream;
     4.7 +    size_t(*writer)(const void*, size_t, size_t, FILE*);
     4.8      unsigned int level;
     4.9      unsigned int mask;
    4.10      UcxMap* levels;
    4.11 @@ -30,16 +31,30 @@
    4.12  UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask);
    4.13  void ucx_logger_free(UcxLogger* logger);
    4.14  
    4.15 -void ucx_logger_log(UcxLogger *logger, unsigned int level,
    4.16 -        const sstr_t message, const char* file, const unsigned int line);
    4.17 -#define ucx_logger_error(l,m) \
    4.18 -    ucx_logger_log(l, UCX_LOGGER_ERROR, m, __FILE__, __LINE__)
    4.19 -#define ucx_logger_info(l,m) \
    4.20 -    ucx_logger_log(l, UCX_LOGGER_INFO, m, __FILE__, __LINE__)
    4.21 -#define ucx_logger_warn(l,m) \
    4.22 -    ucx_logger_log(l, UCX_LOGGER_WARN, m, __FILE__, __LINE__)
    4.23 -#define ucx_logger_trace(l,m) \
    4.24 -    ucx_logger_log(l, UCX_LOGGER_TRACE, m, __FILE__, __LINE__)
    4.25 +/**
    4.26 + * Sets the output stream and writer for this logger.
    4.27 + * The parameters stream and writer may be NULL, if they shall remain unchanged
    4.28 + * in the logger.
    4.29 + * l
    4.30 + * @param logger The logger
    4.31 + * @param stream The stream the logger shall log to
    4.32 + * @param writer A pointer to the write function
    4.33 + */
    4.34 +void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
    4.35 +        size_t(*writer)(const void*,size_t,size_t,FILE*));
    4.36 +
    4.37 +void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
    4.38 +        const unsigned int line, const char* format, ...);
    4.39 +#define ucx_logger_log(logger, level, format...) \
    4.40 +    ucx_logger_logf(logger, level, __FILE__, __LINE__, format)
    4.41 +#define ucx_logger_error(logger,format...) \
    4.42 +    ucx_logger_log(logger, UCX_LOGGER_ERROR, format)
    4.43 +#define ucx_logger_info(logger,format...) \
    4.44 +    ucx_logger_log(logger, UCX_LOGGER_INFO, format)
    4.45 +#define ucx_logger_warn(logger,format...) \
    4.46 +    ucx_logger_log(logger, UCX_LOGGER_WARN, format)
    4.47 +#define ucx_logger_trace(logger,format...) \
    4.48 +    ucx_logger_log(logger, UCX_LOGGER_TRACE, format)
    4.49  
    4.50  #ifdef __cplusplus
    4.51  }

mercurial