ucx/logging.c

changeset 81
86a23238d8a1
parent 80
0125e4089f88
child 82
6068d965328b
     1.1 --- a/ucx/logging.c	Wed Feb 06 14:35:15 2013 +0100
     1.2 +++ b/ucx/logging.c	Fri Feb 08 10:37:24 2013 +0100
     1.3 @@ -1,11 +1,13 @@
     1.4  #include "logging.h"
     1.5  #include <stdlib.h>
     1.6  #include <string.h>
     1.7 +#include <stdarg.h>
     1.8  
     1.9  UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) {
    1.10      UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
    1.11      if (logger != NULL) {
    1.12          logger->stream = stream;
    1.13 +        logger->writer = fwrite;
    1.14          logger->level = level;
    1.15          logger->mask = mask;
    1.16          logger->levels = ucx_map_new(8);
    1.17 @@ -29,35 +31,50 @@
    1.18      free(logger);
    1.19  }
    1.20  
    1.21 -void ucx_logger_log(UcxLogger *logger, unsigned int level,
    1.22 -        const sstr_t message, const char* file, const unsigned int line) {
    1.23 +void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
    1.24 +        size_t(*writer)(const void*,size_t,size_t,FILE*)) {
    1.25 +    if (stream) {
    1.26 +        logger->stream = stream;
    1.27 +    }
    1.28 +    if (writer) {
    1.29 +        logger->writer = writer;
    1.30 +    }
    1.31 +}
    1.32 +
    1.33 +void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
    1.34 +        const unsigned int line, const char *format, ...) {
    1.35      if (level <= logger->level) {
    1.36 -        size_t n = message.length;
    1.37 -        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
    1.38 -            n += strlen(file);
    1.39 -            n += 10; // line
    1.40 -        }
    1.41 -        // TODO: add k bytes for timestamp
    1.42 -        n += 16; // extra space for fill characters (:, -, etc.)
    1.43 -        
    1.44 -        char msg[n];
    1.45 -        off_t k = 0;
    1.46 +        const size_t max = 4096; // estimated maximum message length
    1.47 +        char msg[max];
    1.48 +        char *text;
    1.49 +        size_t k = 0;
    1.50 +        size_t n;
    1.51          
    1.52          if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
    1.53 -            k += sprintf(msg+k, "%s ", (char*)
    1.54 -                    ucx_map_int_get(logger->levels, level));
    1.55 +            text = (char*) ucx_map_int_get(logger->levels, level);
    1.56 +            n = strlen(text);
    1.57 +            memcpy(msg+k, text, n);
    1.58 +            k += n;
    1.59 +            msg[k++] = ' ';
    1.60          }
    1.61          // TODO: timestamp
    1.62          if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
    1.63 -            k += sprintf(msg+k, "%s:%d ", file, line);
    1.64 +            n = strlen(file);
    1.65 +            memcpy(msg+k, file, n);
    1.66 +            k += n;
    1.67 +            k += sprintf(msg+k, ":%d ", line);
    1.68          }
    1.69          
    1.70 -        msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0;
    1.71 -        strncat(msg, message.ptr, message.length);
    1.72 -        k += message.length;
    1.73 +        msg[k++] = '-'; msg[k++] = ' ';
    1.74 +        
    1.75 +        va_list args;
    1.76 +        va_start (args, format);
    1.77 +        k += vsnprintf(msg+k, max-k-1, format, args);
    1.78 +        va_end (args);        
    1.79 +        
    1.80          msg[k++] = '\n';
    1.81          
    1.82 -        fwrite(msg, 1, k, logger->stream);
    1.83 +        logger->writer(msg, 1, k, logger->stream);
    1.84          fflush(logger->stream);
    1.85      }
    1.86  }

mercurial