/* * 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. */ /** * Logging API. * * @file logging.h * @author Mike Becker, Olaf Wintermann */ #ifndef UCX_LOGGING_H #define UCX_LOGGING_H #include "ucx.h" #include "map.h" #include "string.h" #include #ifdef __cplusplus extern "C" { #endif /* leave enough space for custom log levels */ /** Log level for error messages. */ #define UCX_LOGGER_ERROR 0x00 /** Log level for warning messages. */ #define UCX_LOGGER_WARN 0x10 /** Log level for information messages. */ #define UCX_LOGGER_INFO 0x20 /** Log level for debug messages. */ #define UCX_LOGGER_DEBUG 0x30 /** Log level for trace messages. */ #define UCX_LOGGER_TRACE 0x40 /** * Output flag for the log level. * If this flag is set, the log message will contain the log level. * @see UcxLogger.mask */ #define UCX_LOGGER_LEVEL 0x01 /** * Output flag for the timestmap. * If this flag is set, the log message will contain the timestmap. * @see UcxLogger.mask */ #define UCX_LOGGER_TIMESTAMP 0x02 /** * Output flag for the source. * If this flag is set, the log message will contain the source file and line * number. * @see UcxLogger.mask */ #define UCX_LOGGER_SOURCE 0x04 /** * The UCX Logger object. */ typedef struct { /** The stream this logger writes its messages to.*/ void *stream; /** * The write function that shall be used. * For standard file or stdout loggers this might be standard fwrite * (default). */ write_func writer; /** * The date format for timestamp outputs including the delimiter * (default: "%F %T %z "). * @see UCX_LOGGER_TIMESTAMP */ char *dateformat; /** * The level, this logger operates on. * If a log command is issued, the message will only be logged, if the log * level of the message is less or equal than the log level of the logger. */ unsigned int level; /** * A configuration mask for automatic output. * For each flag that is set, the logger automatically outputs some extra * information like the timestamp or the source file and line number. * See the documentation for the flags for details. */ unsigned int mask; /** * A map of valid log levels for this logger. * * The keys represent all valid log levels and the values provide string * representations, that are used, if the UCX_LOGGER_LEVEL flag is set. * * The exact data types are unsigned int for the key and * const char* for the value. * * @see UCX_LOGGER_LEVEL */ UcxMap* levels; } UcxLogger; /** * Creates a new logger. * @param stream the stream, which the logger shall write to * @param level the level on which the logger shall operate * @param mask configuration mask (cf. UcxLogger.mask) * @return a new logger object */ UcxLogger *ucx_logger_new(void *stream, unsigned int level, unsigned int mask); /** * Destroys the logger. * * The map containing the valid log levels is also automatically destroyed. * * @param logger the logger to destroy */ void ucx_logger_free(UcxLogger* logger); /** * Internal log function - use macros instead. * * This function uses the format and variadic arguments for a * printf()-style output of the log message. * * Dependent on the UcxLogger.mask some information is prepended. The complete * format is: * * [LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message * * The source file name is reduced to the actual file name. This is necessary to * get consistent behavior over different definitions of the __FILE__ macro. * * Attention: the message (including automatically generated information) * is limited to 4096 characters. The level description is limited to * 256 characters and the timestamp string is limited to 128 characters. * * @param logger the logger to use * @param level the level to log on * @param file information about the source file * @param line information about the source line number * @param format format string * @param ... arguments * @see ucx_logger_log() */ void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file, const unsigned int line, const char* format, ...); /** * Registers a custom log level. * @param logger the logger * @param level the log level as unsigned integer * @param name a string literal describing the level */ #define ucx_logger_register_level(logger, level, name) {\ unsigned int l; \ l = level; \ ucx_map_int_put(logger->levels, l, (void*) "[" name "]"); \ } while (0); /** * Logs a message at the specified level. * @param logger the logger to use * @param level the level to log the message on * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_log(logger, level, ...) \ ucx_logger_logf(logger, level, __FILE__, __LINE__, __VA_ARGS__) /** * Shortcut for logging an error message. * @param logger the logger to use * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_error(logger, ...) \ ucx_logger_log(logger, UCX_LOGGER_ERROR, __VA_ARGS__) /** * Shortcut for logging an information message. * @param logger the logger to use * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_info(logger, ...) \ ucx_logger_log(logger, UCX_LOGGER_INFO, __VA_ARGS__) /** * Shortcut for logging a warning message. * @param logger the logger to use * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_warn(logger, ...) \ ucx_logger_log(logger, UCX_LOGGER_WARN, __VA_ARGS__) /** * Shortcut for logging a debug message. * @param logger the logger to use * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_debug(logger, ...) \ ucx_logger_log(logger, UCX_LOGGER_DEBUG, __VA_ARGS__) /** * Shortcut for logging a trace message. * @param logger the logger to use * @param ... format string and arguments * @see ucx_logger_logf() */ #define ucx_logger_trace(logger, ...) \ ucx_logger_log(logger, UCX_LOGGER_TRACE, __VA_ARGS__) #ifdef __cplusplus } #endif #endif /* UCX_LOGGING_H */