/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "ucx/logging.h" #include #include #include #include UcxLogger *ucx_logger_new(void *stream, unsigned int level, unsigned int mask) { UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger)); if (logger != NULL) { logger->stream = stream; logger->writer = (write_func)fwrite; logger->dateformat = (char*) "%F %T %z "; logger->level = level; logger->mask = mask; logger->levels = ucx_map_new(8); unsigned int l; l = UCX_LOGGER_ERROR; ucx_map_int_put(logger->levels, l, (void*) "[ERROR]"); l = UCX_LOGGER_WARN; ucx_map_int_put(logger->levels, l, (void*) "[WARNING]"); l = UCX_LOGGER_INFO; ucx_map_int_put(logger->levels, l, (void*) "[INFO]"); l = UCX_LOGGER_DEBUG; ucx_map_int_put(logger->levels, l, (void*) "[DEBUG]"); l = UCX_LOGGER_TRACE; ucx_map_int_put(logger->levels, l, (void*) "[TRACE]"); } return logger; } void ucx_logger_free(UcxLogger *logger) { ucx_map_free(logger->levels); free(logger); } // estimated max. message length (documented) #define UCX_LOGGER_MSGMAX 4096 void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file, const unsigned int line, const char *format, ...) { if (level <= logger->level) { char msg[UCX_LOGGER_MSGMAX]; const char *text; size_t k = 0; size_t n; if ((logger->mask & UCX_LOGGER_LEVEL) > 0) { text = (const char*) ucx_map_int_get(logger->levels, level); if (!text) { text = "[UNKNOWN]"; } n = strlen(text); n = n > 256 ? 256 : n; memcpy(msg+k, text, n); k += n; msg[k++] = ' '; } if ((logger->mask & UCX_LOGGER_TIMESTAMP) > 0) { time_t now = time(NULL); k += strftime(msg+k, 128, logger->dateformat, localtime(&now)); } if ((logger->mask & UCX_LOGGER_SOURCE) > 0) { char *fpart = strrchr(file, '/'); if (fpart) file = fpart+1; fpart = strrchr(file, '\\'); if (fpart) file = fpart+1; n = strlen(file); memcpy(msg+k, file, n); k += n; k += sprintf(msg+k, ":%u ", line); } if (k > 0) { msg[k++] = '-'; msg[k++] = ' '; } va_list args; va_start (args, format); k += vsnprintf(msg+k, UCX_LOGGER_MSGMAX-k-1, format, args); va_end (args); msg[k++] = '\n'; logger->writer(msg, 1, k, logger->stream); } }