Fri, 08 Feb 2013 10:37:24 +0100
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 }