ucx/logging.c

changeset 81
86a23238d8a1
parent 80
0125e4089f88
child 82
6068d965328b
equal deleted inserted replaced
80:0125e4089f88 81:86a23238d8a1
1 #include "logging.h" 1 #include "logging.h"
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include <stdarg.h>
4 5
5 UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) { 6 UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) {
6 UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger)); 7 UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
7 if (logger != NULL) { 8 if (logger != NULL) {
8 logger->stream = stream; 9 logger->stream = stream;
10 logger->writer = fwrite;
9 logger->level = level; 11 logger->level = level;
10 logger->mask = mask; 12 logger->mask = mask;
11 logger->levels = ucx_map_new(8); 13 logger->levels = ucx_map_new(8);
12 14
13 unsigned int l; 15 unsigned int l;
27 void ucx_logger_free(UcxLogger *logger) { 29 void ucx_logger_free(UcxLogger *logger) {
28 ucx_map_free(logger->levels); 30 ucx_map_free(logger->levels);
29 free(logger); 31 free(logger);
30 } 32 }
31 33
32 void ucx_logger_log(UcxLogger *logger, unsigned int level, 34 void ucx_logger_setoutput(UcxLogger *logger, FILE *stream,
33 const sstr_t message, const char* file, const unsigned int line) { 35 size_t(*writer)(const void*,size_t,size_t,FILE*)) {
36 if (stream) {
37 logger->stream = stream;
38 }
39 if (writer) {
40 logger->writer = writer;
41 }
42 }
43
44 void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
45 const unsigned int line, const char *format, ...) {
34 if (level <= logger->level) { 46 if (level <= logger->level) {
35 size_t n = message.length; 47 const size_t max = 4096; // estimated maximum message length
36 if ((logger->mask & UCX_LOGGER_SOURCE) > 0) { 48 char msg[max];
37 n += strlen(file); 49 char *text;
38 n += 10; // line 50 size_t k = 0;
39 } 51 size_t n;
40 // TODO: add k bytes for timestamp
41 n += 16; // extra space for fill characters (:, -, etc.)
42
43 char msg[n];
44 off_t k = 0;
45 52
46 if ((logger->mask & UCX_LOGGER_LEVEL) > 0) { 53 if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
47 k += sprintf(msg+k, "%s ", (char*) 54 text = (char*) ucx_map_int_get(logger->levels, level);
48 ucx_map_int_get(logger->levels, level)); 55 n = strlen(text);
56 memcpy(msg+k, text, n);
57 k += n;
58 msg[k++] = ' ';
49 } 59 }
50 // TODO: timestamp 60 // TODO: timestamp
51 if ((logger->mask & UCX_LOGGER_SOURCE) > 0) { 61 if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
52 k += sprintf(msg+k, "%s:%d ", file, line); 62 n = strlen(file);
63 memcpy(msg+k, file, n);
64 k += n;
65 k += sprintf(msg+k, ":%d ", line);
53 } 66 }
54 67
55 msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0; 68 msg[k++] = '-'; msg[k++] = ' ';
56 strncat(msg, message.ptr, message.length); 69
57 k += message.length; 70 va_list args;
71 va_start (args, format);
72 k += vsnprintf(msg+k, max-k-1, format, args);
73 va_end (args);
74
58 msg[k++] = '\n'; 75 msg[k++] = '\n';
59 76
60 fwrite(msg, 1, k, logger->stream); 77 logger->writer(msg, 1, k, logger->stream);
61 fflush(logger->stream); 78 fflush(logger->stream);
62 } 79 }
63 } 80 }

mercurial