From 6816ddaf7a280e292a3cebe202dc855776222565 Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 24 Jan 2023 15:16:47 -0500 Subject: [PATCH] Logging is now working with all types + formatting Can provide raw data types like ints, long, float, byte, double etc. Will be printed out as a full line. This cannot be avoided as writing requires the prefix, which cannot be calculated via discrete macro calls. At least not easily. Performance of the logging needs to be tested plus writing to filesystem is required. --- include/blt/std/logging.h | 76 ++++++++++---------- src/blt/std/logging.cpp | 148 ++++++++++++++++++-------------------- src/tests/main.cpp | 19 ++--- 3 files changed, 116 insertions(+), 127 deletions(-) diff --git a/include/blt/std/logging.h b/include/blt/std/logging.h index dbb0673..d050942 100644 --- a/include/blt/std/logging.h +++ b/include/blt/std/logging.h @@ -7,6 +7,8 @@ #ifndef BLT_TESTS_LOGGING_H #define BLT_TESTS_LOGGING_H +#include + namespace blt::logging { enum LOG_LEVEL { @@ -26,51 +28,47 @@ namespace blt::logging { }; void init(LOG_PROPERTIES properties); - void log(LOG_LEVEL level, bool auto_line, const char* format, ...); + void log(const std::string& format, LOG_LEVEL level, int auto_line, ...); + void log(int i, LOG_LEVEL level, int auto_line); + void log(long i, LOG_LEVEL level, int auto_line); + void log(unsigned int i, LOG_LEVEL level, int auto_line); + void log(unsigned long i, LOG_LEVEL level, int auto_line); + void log(char i, LOG_LEVEL level, int auto_line); + void log(unsigned char i, LOG_LEVEL level, int auto_line); + void log(short i, LOG_LEVEL level, int auto_line); + void log(unsigned short i, LOG_LEVEL level, int auto_line); + void log(float f, LOG_LEVEL level, int auto_line); + void log(double f, LOG_LEVEL level, int auto_line); } #ifdef BLT_DISABLE_LOGGING - #define BLT_TRACE(format) - #define BLT_DEBUG(format) - #define BLT_INFO(format) - #define BLT_WARN(format) - #define BLT_ERROR(format) - #define BLT_FATAL(format) + #define BLT_TRACE(format, args...) + #define BLT_DEBUG(format, args...) + #define BLT_INFO(format, args...) + #define BLT_WARN(format, args...) + #define BLT_ERROR(format, args...) + #define BLT_FATAL(format, args...) - #define BLT_TRACE_FMT(format, args...) - #define BLT_DEBUG_FMT(format, args...) - #define BLT_INFO_FMT(format, args...) - #define BLT_WARN_FMT(format, args...) - #define BLT_ERROR_FMT(format, args...) - #define BLT_FATAL_FMT(format, args...) + #define BLT_TRACE_LN(format, args...) + #define BLT_DEBUG_LN(format, args...) + #define BLT_INFO_LN(format, args...) + #define BLT_WARN_LN(format, args...) + #define BLT_ERROR_LN(format, args...) + #define BLT_FATAL_LN(format, args...) #else - #define BLT_TRACE(format) log(blt::logging::TRACE, false, format); - #define BLT_DEBUG(format) log(blt::logging::DEBUG, false, format); - #define BLT_INFO(format) log(blt::logging::INFO, false, format); - #define BLT_WARN(format) log(blt::logging::WARN, false, format); - #define BLT_ERROR(format) log(blt::logging::ERROR, false, format); - #define BLT_FATAL(format) log(blt::logging::FATAL, false, format); + #define BLT_TRACE(format, ...) log(format, blt::logging::TRACE, false, ##__VA_ARGS__); + #define BLT_DEBUG(format, ...) log(format, blt::logging::DEBUG, false, ##__VA_ARGS__); + #define BLT_INFO(format, ...) log(format, blt::logging::INFO, false, ##__VA_ARGS__); + #define BLT_WARN(format, ...) log(format, blt::logging::WARN, false, ##__VA_ARGS__); + #define BLT_ERROR(format, ...) log(format, blt::logging::ERROR, false, ##__VA_ARGS__); + #define BLT_FATAL(format, ...) log(format, blt::logging::FATAL, false, ##__VA_ARGS__); - #define BLT_TRACE_FMT(format, args...) log(blt::logging::TRACE, false, format, args); - #define BLT_DEBUG_FMT(format, args...) log(blt::logging::DEBUG, false, format, args); - #define BLT_INFO_FMT(format, args...) log(blt::logging::INFO, false, format, args); - #define BLT_WARN_FMT(format, args...) log(blt::logging::WARN, false, format, args); - #define BLT_ERROR_FMT(format, args...) log(blt::logging::ERROR, false, format, args); - #define BLT_FATAL_FMT(format, args...) log(blt::logging::FATAL, false, format, args); - - #define BLT_TRACE_LN(format) log(blt::logging::TRACE, true, format); - #define BLT_DEBUG_LN(format) log(blt::logging::DEBUG, true, format); - #define BLT_INFO_LN(format) log(blt::logging::INFO, true, format); - #define BLT_WARN_LN(format) log(blt::logging::WARN, true, format); - #define BLT_ERROR_LN(format) log(blt::logging::ERROR, true, format); - #define BLT_FATAL_LN(format) log(blt::logging::FATAL, true, format); - - #define BLT_TRACE_FMT_LN(format, args...) log(blt::logging::TRACE, true, format, args); - #define BLT_DEBUG_FMT_LN(format, args...) log(blt::logging::DEBUG, true, format, args); - #define BLT_INFO_FMT_LN(format, args...) log(blt::logging::INFO, true, format, args); - #define BLT_WARN_FMT_LN(format, args...) log(blt::logging::WARN, true, format, args); - #define BLT_ERROR_FMT_LN(format, args...) log(blt::logging::ERROR, true, format, args); - #define BLT_FATAL_FMT_LN(format, args...) log(blt::logging::FATAL, true, format, args); + #define BLT_TRACE_LN(format, ...) log(format, blt::logging::TRACE, true, ##__VA_ARGS__); + #define BLT_DEBUG_LN(format, ...) log(format, blt::logging::DEBUG, true, ##__VA_ARGS__); + #define BLT_INFO_LN(format, ...) log(format, blt::logging::INFO, true, ##__VA_ARGS__); + #define BLT_WARN_LN(format, ...) log(format, blt::logging::WARN, true, ##__VA_ARGS__); + #define BLT_ERROR_LN(format, ...) log(format, blt::logging::ERROR, true, ##__VA_ARGS__); + #define BLT_FATAL_LN(format, ...) log(format, blt::logging::FATAL, true, ##__VA_ARGS__); #endif #endif //BLT_TESTS_LOGGING_H diff --git a/src/blt/std/logging.cpp b/src/blt/std/logging.cpp index a9443c2..e7974b8 100644 --- a/src/blt/std/logging.cpp +++ b/src/blt/std/logging.cpp @@ -9,6 +9,7 @@ #include #include #include +#include "blt/std/string.h" // https://en.cppreference.com/w/cpp/utility/variadic // https://medium.com/swlh/variadic-functions-3419c287a0d2 @@ -18,69 +19,10 @@ namespace blt::logging { - inline std::string applyFormat(const char* format, va_list args) { - std::stringstream output; - char currentCharacter; - while ((currentCharacter = *format) != '\0') { - if (currentCharacter == '%') { - char nextCharacter = *(++format); - if (nextCharacter == '\0') - break; - switch (nextCharacter) { - case 'd': - case 'i': - output << static_cast(va_arg(args, int)); - break; - case 'u': - output << static_cast(va_arg(args, unsigned int)); - break; - case 'o': - // TODO octal - break; - case 'x': - case 'X': - // TODO hex - break; - case 'f': - case 'F': - output << va_arg(args, double); - case 'e': - case 'E': - // TODO: scientific notation - break; - case 'g': - case 'G': - // TODO: shortest representation - output << va_arg(args, double); - break; - case 'a': - case 'A': - output << va_arg(args, double); - break; - case 'c': - output << va_arg(args, int); - break; - case 's': - output << va_arg(args, const char*); - break; - case 'p': - output << va_arg(args, void*); - break; - case 'n': - va_arg(args, int*); - break; - case '%': - output << '%'; - break; - default: - output << nextCharacter; - break; - } - } else - output << currentCharacter; - ++format; - } - return output.str(); + void applyFormatting(const std::string& format, std::string& output, va_list& args){ + char formattedChars[format.length()]; + vsprintf(formattedChars, format.c_str(), args); + output = std::string(formattedChars); } const char* levelColors[6] = { @@ -108,38 +50,84 @@ namespace blt::logging { BLT_LOGGING_PROPERTIES = properties; } - void log(LOG_LEVEL level, bool auto_line, const char* format, ...) { - va_list args; - va_start(args, format); - - auto formattedString = applyFormat(format, args); - bool hasEndingLinefeed = formattedString[formattedString.length()-1] == '\n'; - - if (hasEndingLinefeed) - formattedString = formattedString.substr(0, formattedString.length()-1); - + inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, int auto_line){ std::string outputString = System::getTimeStringLog(); outputString += levelNames[level]; - - if (BLT_LOGGING_PROPERTIES.m_useColor) + outputString += str; + + if (BLT_LOGGING_PROPERTIES.m_useColor) { outputString = levelColors[level] + outputString; - - outputString += formattedString; - - if (BLT_LOGGING_PROPERTIES.m_useColor) outputString += "\033[0m"; + } + if (hasEndingLinefeed || auto_line) outputString += "\n"; - + if (BLT_LOGGING_PROPERTIES.m_logToConsole) { if (level > WARN) std::cerr << outputString; else std::cout << outputString; } + } + + void log(const std::string& format, LOG_LEVEL level, int auto_line, ...) { + va_list args; + va_start(args, auto_line); + + std::string formattedString; + applyFormatting(format, formattedString, args); + + bool hasEndingLinefeed = formattedString[formattedString.length()-1] == '\n'; + + if (hasEndingLinefeed) + formattedString = formattedString.substr(0, formattedString.length()-1); + + log(formattedString, hasEndingLinefeed, level, auto_line); va_end(args); } + + void log(int i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(long i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned int i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned long i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(char i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned char i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(short i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned short i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(float f, LOG_LEVEL level, int auto_line) { + log(std::to_string(f), false, level, true); + } + + void log(double f, LOG_LEVEL level, int auto_line) { + log(std::to_string(f), false, level, true); + } + } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index f76b899..45616b7 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -9,19 +9,22 @@ int main() { binaryTreeTest(); - BLT_TRACE("Hello World!\n"); - BLT_DEBUG("Hello World!\n"); + BLT_TRACE(10); + BLT_TRACE(10.5); + + BLT_TRACE("Hello %d World!\n", 50); + BLT_DEBUG("Hello %E World!\n", 1205200.0); BLT_INFO("Hello World!\n"); BLT_WARN("Hello World!\n"); BLT_ERROR("Hello World!\n"); BLT_FATAL("Hello World!\n"); - BLT_TRACE_LN("Hello World!\n"); - BLT_DEBUG_LN("Hello World!\n"); - BLT_INFO_LN("Hello World!\n"); - BLT_WARN_LN("Hello World!"); - BLT_ERROR_LN("Hello World!"); - BLT_FATAL_LN("Hello World!"); + BLT_TRACE_LN("Goodbye World!\n"); + BLT_DEBUG_LN("Goodbye World!\n"); + BLT_INFO_LN("Goodbye World!\n"); + BLT_WARN_LN("Goodbye World!"); + BLT_ERROR_LN("Goodbye World!"); + BLT_FATAL_LN("Goodbye World!"); std::string hello = "superSexyMax"; std::cout << "String starts with: " << blt::string::contains(hello, "superSexyMaxE") << "\n";