#ifndef LOGGING_H #define LOGGING_H #define MAX_LOG_BUF_LEN 1024 #define MAX_LOG_FILE_NAME_LEN 400 // define severity levels for log message highlighting #define LOG_DEBUG 0 #define LOG_INFO 1 #define LOG_WARN 2 #define LOG_ERR 3 // Macros for verbosity level #define LOG_VERBOSE 1 #define LOG_QUIET 0 // Macros for colour console printing #define PRINT_COLOUR 1 #define NO_COLOUR 0 #define DEBUG_PREFIX "(DEBUG) | " #define INFO_PREFIX "(INFO) | " #define WARN_PREFIX "(WARNING) | " #define ERR_PREFIX "(ERROR) | " // \x1b[31m ERROR \x1b[0m : \x1b[31m sets string to red, we then print 'ERROR', then reset terminal so it doesn stay red! // ANSI escape code colouring for highlighting different messages #define COLOUR_INFO_PREFIX "(\x1b[36mINFO\x1b[0m) | " #define COLOUR_WARN_PREFIX "(\x1b[33mWARNING\x1b[0m) | " #define COLOUR_ERR_PREFIX "(\x1b[31mERROR\x1b[0m) | " // Define the timstamp format strings and function caller ID string #define STD_TIMESTAMP_SEC "[ 2025-06-04 12:52:11." #define STD_TIMESTAMP_WHOLE "[ 2025-06-04 12:52:11.999 ]" #define FUNC_STR " in function: (): " // Enum for use in determining current output stream typedef enum { notSet = 0, standardOut = 1, standardErr = 2, logFile = 3 }T_LogOutput; //*============================================================================*/ // Macros for initialisation function //*----------------------------------------------------------------------------*/ #define LOGGING_INIT_STDOUT Logging_Init(standardOut, NULL); #define LOGGING_INIT_STDERR Logging_Init(standardErr, NULL); #define LOGGING_INIT_FILE(FileName) Logging_Init(logFile, FileName); /*============================================================================*/ /*============================================================================*/ // Useful variadic macros for logging functions - see https://gcc.gnu.org/onlinedocs/gcc-15.1.0/gcc/Variadic-Macros.html //*----------------------------------------------------------------------------*/ // Timestamped logging with file and func preprocessors used to define 'where' and 'caller' //*----------------------------------------------------------------------------*/ #define LOGMSG_TS_DBG(message, ...) if(Verbose == LOG_VERBOSE) { Logging_LogMsgTS(__FILE__, __func__, LOG_DEBUG, message, ##__VA_ARGS__);} #define LOGMSG_TS_INFO(message, ...) Logging_LogMsgTS(__FILE__, __func__, LOG_INFO, message, ##__VA_ARGS__); #define LOGMSG_TS_WARN(message, ...) Logging_LogMsgTS(__FILE__, __func__, LOG_WARN, message, ##__VA_ARGS__); #define LOGMSG_TS_ERR(message, ...) Logging_LogMsgTS(__FILE__, __func__, LOG_ERR, message, ##__VA_ARGS__); //*----------------------------------------------------------------------------*/ // Basic logging with file and func preprocessors used to define 'where' and 'caller' //*----------------------------------------------------------------------------*/ #define LOGMSG_DBG(message, ...) if(Verbose == LOG_VERBOSE) { Logging_LogMsg(__FILE__, __func__, LOG_DEBUG, message, ##__VA_ARGS__);} #define LOGMSG_INFO(message, ...) Logging_LogMsg(__FILE__, __func__, LOG_INFO, message, ##__VA_ARGS__); #define LOGMSG_WARN(message, ...) Logging_LogMsg(__FILE__, __func__, LOG_WARN, message, ##__VA_ARGS__); #define LOGMSG_ERR(message, ...) Logging_LogMsg(__FILE__, __func__, LOG_ERR, message, ##__VA_ARGS__); //*----------------------------------------------------------------------------*/ // Timestamped logging with arguments used to define 'where' and 'caller' (N = name) //*----------------------------------------------------------------------------*/ #define LOGMSG_TS_N_DBG(what, who, message, ...) if(Verbose == LOG_VERBOSE) {Logging_LogMsgTS(what, who, LOG_DEBUG, message, ##__VA_ARGS__);} #define LOGMSG_TS_N_INFO(what, who, message, ...) Logging_LogMsgTS(what, who, LOG_INFO, message, ##__VA_ARGS__); #define LOGMSG_TS_N_WARN(what, who, message, ...) Logging_LogMsgTS(what, who, LOG_WARN, message, ##__VA_ARGS__); #define LOGMSG_TS_N_ERR(what, who, message, ...) Logging_LogMsgTS(what, who, LOG_ERR, message, ##__VA_ARGS__); //*----------------------------------------------------------------------------*/ // Basic logging with arguments used to define 'where' and 'caller' (N = name) //*----------------------------------------------------------------------------*/ #define LOGMSG_N_DBG(what, who, message, ...) if(Verbose == LOG_VERBOSE) { Logging_LogMsg(what, who, LOG_DEBUG, message, ##__VA_ARGS__);} #define LOGMSG_N_INFO(what, who, message, ...) Logging_LogMsg(what, who, LOG_INFO, message, ##__VA_ARGS__); #define LOGMSG_N_WARN(what, who, message, ...) Logging_LogMsg(what, who, LOG_WARN, message, ##__VA_ARGS__); #define LOGMSG_N_ERR(what, who, message, ...) Logging_LogMsg(what, who, LOG_ERR, message, ##__VA_ARGS__); //*============================================================================*/ //*============================================================================*/ // Prototypes for logging functions //*----------------------------------------------------------------------------*/ void Logging_LogMsgTS( const char * where , const char * caller , int severity , const char * message, ... ); void Logging_LogMsg( const char * where , const char * caller , int severity , const char * message, ... ); int Logging_Init(T_LogOutput output, char * fileName); void Logging_Term( void ); //*============================================================================*/ #endif //LOGGING_H