119 lines
4.0 KiB
C
119 lines
4.0 KiB
C
/**
|
|
* @file log.h
|
|
* @brief Logger header
|
|
* @author Lorenz C.
|
|
*
|
|
* This logging library provides a simple logging interface with different verbosity levels.
|
|
* Each tag can have its own log level.
|
|
* Only messages with a log level greater or equal to the log level of the tag and the global log level will be printed.
|
|
*/
|
|
|
|
#ifndef LOG_H
|
|
#define LOG_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/**
|
|
* @brief Log levels
|
|
*/
|
|
typedef enum {
|
|
LOG_LEVEL_DEBUG,
|
|
LOG_LEVEL_INFO,
|
|
LOG_LEVEL_WARN,
|
|
LOG_LEVEL_ERROR,
|
|
} log_level_t;
|
|
|
|
/* For internal use only.
|
|
* Use the LOG_* macros instead e.g., LOG_DEBUG(TAG, "Debug message");
|
|
*/
|
|
uint32_t logger_get_timestamp(void);
|
|
void logger_write(const char* format, ...);
|
|
|
|
/**
|
|
* @brief Set the log level for a tag
|
|
* If the tag is not already in the list, it will be added.
|
|
*
|
|
* @param[in] tag The tag to set the log level for
|
|
* @param[in] level The log level to set (member of @ref log_level_t)
|
|
*/
|
|
void logger_set_log_level(const char* tag, log_level_t level);
|
|
|
|
/**
|
|
* @brief Get the log level for a tag
|
|
*
|
|
* @param[in] tag The tag to get the log level for
|
|
* @return The log level for the tag (member of @ref log_level_t)
|
|
*/
|
|
log_level_t logger_get_log_level(const char* tag);
|
|
|
|
/**
|
|
* @brief The global minimum log level.
|
|
* Messages with a log level lower than this will not be logged.
|
|
* And log statements with a log level lower than this will optimized away by the compiler.
|
|
*/
|
|
#define LOGGER_MIN_LOG_LEVEL LOG_LEVEL_DEBUG
|
|
|
|
/**
|
|
* @brief The maximum number of tags that can be used.
|
|
*/
|
|
#define LOGGER_MAX_TAG_ENTRIES 20
|
|
|
|
/**
|
|
* @brief Whether to use color in the log output.
|
|
* This is only supported in terminals that support ANSI escape codes.
|
|
*/
|
|
#define LOGGER_USE_COLOR 0
|
|
|
|
#if LOGGER_USE_COLOR
|
|
#define LOG_RESET_COLOR "\033[0m"
|
|
#define LOG_COLOR_E "\033[0;31m" // Red
|
|
#define LOG_COLOR_W "\033[0;33m" // Brown
|
|
#define LOG_COLOR_I "\033[0;32m" // Green
|
|
#define LOG_COLOR_D
|
|
#else
|
|
#define LOG_RESET_COLOR
|
|
#define LOG_COLOR_E
|
|
#define LOG_COLOR_W
|
|
#define LOG_COLOR_I
|
|
#define LOG_COLOR_D
|
|
#endif
|
|
|
|
#define LOG_FORMAT(letter, format) LOG_COLOR_##letter #letter " (%lu) %s: " format LOG_RESET_COLOR "\r\n"
|
|
|
|
#define LOGGER_LOG(level, tag, format, ...) \
|
|
do { \
|
|
if (level >= LOGGER_MIN_LOG_LEVEL && level >= logger_get_log_level(tag)) { \
|
|
if (level == LOG_LEVEL_DEBUG) { \
|
|
logger_write(LOG_FORMAT(D, format), logger_get_timestamp(), tag, ##__VA_ARGS__); \
|
|
} else if (level == LOG_LEVEL_INFO) { \
|
|
logger_write(LOG_FORMAT(I, format), logger_get_timestamp(), tag, ##__VA_ARGS__); \
|
|
} else if (level == LOG_LEVEL_WARN) { \
|
|
logger_write(LOG_FORMAT(W, format), logger_get_timestamp(), tag, ##__VA_ARGS__); \
|
|
} else if (level == LOG_LEVEL_ERROR) { \
|
|
logger_write(LOG_FORMAT(E, format), logger_get_timestamp(), tag, ##__VA_ARGS__); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
/**
|
|
* @brief Macro to log a debug message (LOG_LEVEL_DEBUG)
|
|
*/
|
|
#define LOG_DEBUG(tag, format, ...) LOGGER_LOG(LOG_LEVEL_DEBUG, tag, format, ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Macro to log an info message (LOG_LEVEL_INFO)
|
|
*/
|
|
#define LOG_INFO(tag, format, ...) LOGGER_LOG(LOG_LEVEL_INFO, tag, format, ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Macro to log a warning message (LOG_LEVEL_WARN)
|
|
*/
|
|
#define LOG_WARN(tag, format, ...) LOGGER_LOG(LOG_LEVEL_WARN, tag, format, ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief Macro to log an error message (LOG_LEVEL_ERROR)
|
|
*/
|
|
#define LOG_ERROR(tag, format, ...) LOGGER_LOG(LOG_LEVEL_ERROR, tag, format, ##__VA_ARGS__)
|
|
|
|
#endif // LOG_H
|