/** * \file * * * \defgroup logging Logging facilities * \ingroup core * \{ * \brief Logging system module. * * This module implement a simple interface to use the multi level logging system. * The log message have the priority order, like this: * * - error message (highest) * - warning message * - info message (lowest) * * With this priority system we log only the messages that have priority higher * or equal to the log level that has been configurated; messages below the * selected log level are not included at compile time, so no time and space * is wasted on unused functions. * * Furthermore you can define different log levels for each module. To do this * you just need to define LOG_LEVEL in the configuration file for the * selected module. * * This module provides two types of macros: * * - LOG_* macros: these macros allow formatted output, using the same format * as kprintf * - LOG_*B macros: these macros allow to optionally compile a block of code * depending on the logging level chosen * * To use the logging system you should include this module in your driver * and use one of the LOG_ERR, LOG_WARN and LOG_INFO macros to output error * messages. * Then you should define a LOG_LEVEL and LOG_VERBOSE costant in your * \c cfg/cfg_\.h using the follow policy: * * - in your file \c cfg/cfg_\.h, define the logging * level and verbosity mode for your specific module: * * \code * /// Module logging level. * #define _LOG_LEVEL LOG_LVL_INFO * * /// Module logging format. * #define _LOG_FORMAT LOG_FMT_VERBOSE * \endcode * * - then, in the module where you use the logging macros you should define * the macros LOG_LEVEL and LOG_FORMAT and you should include cfg/log.h * module, as demonstrated in the following example: * * \code * // Define log settings for cfg/log.h. * #define LOG_LEVEL _LOG_LEVEL * #define LOG_FORMAT _LOG_FORMAT * #include * \endcode * * if you include a log.h module without defining the LOG_LEVEL and LOG_VERBOSE * macros, the module uses the default settings. * * WARNING: when using the log.h module make sure to include this module after * a \c cfg_.h, because the LOG_LEVEL and LOG_VERBOSE macros * must be defined before including the log module. Otherwise the log module * will use the default settings. * * \author Daniele Basile * * $WIZ$ */ #ifndef CFG_LOG_H #define CFG_LOG_H #include // Use a default setting if nobody defined a log level #ifndef LOG_LEVEL #define LOG_LEVEL LOG_LVL_ERR #endif // Use a default setting if nobody defined a log format #ifndef LOG_FORMAT #define LOG_FORMAT LOG_FMT_TERSE #endif /** * \name Logging level definition * * When you choose a log level messages you choose * also which print function are linked. * When using a log level, you link all log functions that have a priority * higher or equal than the level you chose. * The priority level go from error (highest) to info (lowest). * * $WIZ$ log_level = "LOG_LVL_NONE", "LOG_LVL_ERR", "LOG_LVL_WARN", "LOG_LVL_INFO" * \{ */ #define LOG_LVL_NONE 0 #define LOG_LVL_ERR 1 #define LOG_LVL_WARN 2 #define LOG_LVL_INFO 3 /** \} */ /** * \name Logging format * * There are two logging format: terse and verbose. The latter prepends * function names and line number information to each log entry. * * $WIZ$ log_format = "LOG_FMT_VERBOSE", "LOG_FMT_TERSE" * \{ */ #define LOG_FMT_VERBOSE 1 #define LOG_FMT_TERSE 0 /** \} */ #if LOG_FORMAT == LOG_FMT_VERBOSE #define LOG_PRINT(str_level, str,...) kprintf("%s():%d:%s: " str, __func__, __LINE__, str_level, ## __VA_ARGS__) #elif LOG_FORMAT == LOG_FMT_TERSE #define LOG_PRINT(str_level, str,...) kprintf("%s: " str, str_level, ## __VA_ARGS__) #else #error No LOG_FORMAT defined #endif #if LOG_LEVEL >= LOG_LVL_ERR /** * Output an error message */ #define LOG_ERR(str,...) LOG_PRINT("ERR", str, ## __VA_ARGS__) /** * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_ERR */ #define LOG_ERRB(x) x #else INLINE void LOG_ERR(UNUSED_ARG(const char *, fmt), ...) { /* nop */ } #define LOG_ERRB(x) /* Nothing */ #endif #if LOG_LEVEL >= LOG_LVL_WARN /** * Output a warning message */ #define LOG_WARN(str,...) LOG_PRINT("WARN", str, ## __VA_ARGS__) /** * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_WARN */ #define LOG_WARNB(x) x #else INLINE void LOG_WARN(UNUSED_ARG(const char *, fmt), ...) { /* nop */ } #define LOG_WARNB(x) /* Nothing */ #endif #if LOG_LEVEL >= LOG_LVL_INFO /** * Output an informative message */ #define LOG_INFO(str,...) LOG_PRINT("INFO", str, ## __VA_ARGS__) /** * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_INFO */ #define LOG_INFOB(x) x #else INLINE void LOG_INFO(UNUSED_ARG(const char *, fmt), ...) { /* nop */ } #define LOG_INFOB(x) /* Nothing */ #endif /** \} */ #endif /* CFG_LOG_H */