From 8924a3aa70887a8497dbbff74241c29101a94b6a Mon Sep 17 00:00:00 2001 From: Joe Inman Date: Tue, 8 Oct 2024 22:45:05 +0100 Subject: [PATCH] Improved API --- include/EmbedLog/EmbedLog.hpp | 23 +++++----- src/EmbedLog.cpp | 86 +++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/include/EmbedLog/EmbedLog.hpp b/include/EmbedLog/EmbedLog.hpp index ffab0cc..634be22 100644 --- a/include/EmbedLog/EmbedLog.hpp +++ b/include/EmbedLog/EmbedLog.hpp @@ -43,14 +43,14 @@ namespace EmbedLog using MicrosecondFunction = std::function; // Log Levels - enum LogLevel { INFO, WARNING, ERROR, DEBUG }; + enum LogLevel { INFO, WARNING, ERROR, DEBUG, NONE }; /** * @class EmbedLog * @brief A minimal logging library designed for embedded systems. * * EmbedLog provides functionality to log messages at various levels of severity - * (INFO, WARNING, ERROR, DEBUG). It supports user-defined functions for opening + * (INFO, WARNING, ERROR, DEBUG, NONE). It supports user-defined functions for opening * and closing the log, printing messages, and fetching timestamps in microseconds. */ class EmbedLog @@ -64,18 +64,17 @@ namespace EmbedLog * @param printFunc Function to print log messages. * @param microsecondFunc Function to retrieve the current time in microseconds. * @param name Optional: A name for the log. Defaults to an empty string. - * @param format The desired format for the timestamp. + * @param format The desired format for the log messages. Defaults to "[%D:%H:%M:%S.%U %N %L] %T". * * @note It is important to provide valid open, close, and print functions * to enable proper operation of the log system. - * @note The default timestamp format is "%H:%M:%S.%U". */ EmbedLog(OpenFunction openFunc, CloseFunction closeFunc, PrintFunction printFunc, MicrosecondFunction microsecondFunc, std::string name = "", - std::string timestamp_format = "%H:%M:%S.%U"); + std::string format = "[%D:%H:%M:%S.%U %N %L] %T"); /** * @brief Destroys the EmbedLog object. @@ -129,7 +128,6 @@ namespace EmbedLog std::stringstream ss; ss << var1; (ss << ... << var2); // Variadic argument expansion. - ss << "\n"; print(level, ss.str()); } } @@ -140,10 +138,10 @@ namespace EmbedLog PrintFunction printFunc; // Function for printing log messages. MicrosecondFunction microsecondFunc; // Function for getting microsecond timestamps. - std::string timestamp_format = "%H:%M:%S.%U"; // Format for the timestamp. - bool isOpen = false; // Tracks whether the log is currently open. - std::string name = " "; // Optional log name. LogLevel logLevel = INFO; // Current log level. + bool isOpen = false; // Tracks whether the log is currently open. + std::string format; // Format for the timestamp. + std::string name; // Optional log name. /** * @brief Prints a message at a specified log level. @@ -157,10 +155,11 @@ namespace EmbedLog void print(LogLevel level, const std::string& message); /** - * @brief Retrieves the current timestamp as a formatted string. + * @brief Gets a string representation of the log level. * - * @return A string representing the timestamp in microseconds. + * @param level The log level to convert. + * @return A string representation of the log level. */ - std::string getTimestamp(); + std::string getLogLevelString(LogLevel level); }; } diff --git a/src/EmbedLog.cpp b/src/EmbedLog.cpp index 9166ad7..022add8 100644 --- a/src/EmbedLog.cpp +++ b/src/EmbedLog.cpp @@ -38,15 +38,14 @@ namespace EmbedLog PrintFunction printFunc, MicrosecondFunction microsecondFunc, std::string name, - std::string timestamp_format) + std::string format) : openFunc(openFunc), closeFunc(closeFunc), printFunc(printFunc), microsecondFunc(microsecondFunc), - timestamp_format(timestamp_format) + name(name), + format(format) { - if (!name.empty()) - this->name = " " + name + " "; } EmbedLog::~EmbedLog() @@ -70,33 +69,6 @@ namespace EmbedLog } void EmbedLog::print(LogLevel level, const std::string& message) - { - std::string logLevelString; - switch (level) - { - case LogLevel::INFO: - logLevelString = "INFO"; - break; - case LogLevel::WARNING: - logLevelString = "WARNING"; - break; - case LogLevel::ERROR: - logLevelString = "ERROR"; - break; - case LogLevel::DEBUG: - logLevelString = "DEBUG"; - break; - } - - printFunc("[" + getTimestamp() + name + logLevelString + "] " + message); - } - - void EmbedLog::setLogLevel(LogLevel level) - { - logLevel = level; - } - - std::string EmbedLog::getTimestamp() { uint64_t microseconds = microsecondFunc(); uint64_t totalSeconds = microseconds / 1000000; @@ -107,18 +79,27 @@ namespace EmbedLog uint64_t seconds = totalSeconds % 60; std::stringstream result; - for (size_t i = 0; i < timestamp_format.size(); ++i) + for (size_t i = 0; i < format.size(); ++i) { - if (timestamp_format[i] == '%') + if (format[i] == '%') { ++i; // Skip the '%' and check the next character - switch (timestamp_format[i]) + switch (format[i]) { - case 'D': // Interpret as days, which can be calculated from hours - result << (hours / 24); + case 'N': + result << name; // Name + break; + case 'L': + result << getLogLevelString(level); // Level + break; + case 'T': + result << message; // Text + break; + case 'D': + result << std::setfill('0') << std::setw(2) << (hours / 24); // Days break; case 'H': - result << std::setfill('0') << std::setw(2) << (hours % 24); // Hours within the day + result << std::setfill('0') << std::setw(2) << (hours % 24); // Hours break; case 'M': result << std::setfill('0') << std::setw(2) << minutes; // Minutes @@ -130,17 +111,42 @@ namespace EmbedLog result << std::setfill('0') << std::setw(6) << remainingMicroseconds; // Microseconds break; default: - result << '%' << timestamp_format[i]; // Unknown format specifier, output as is + result << '%' << format[i]; // Unknown break; } } else { - result << timestamp_format[i]; // Copy non-format characters directly + result << format[i]; // Normal character } } + result << "\n"; + + printFunc(result.str()); + } - return result.str(); + void EmbedLog::setLogLevel(LogLevel level) + { + logLevel = level; + } + + std::string EmbedLog::getLogLevelString(LogLevel level) + { + switch (level) + { + case INFO: + return "INFO"; + case WARNING: + return "WARNING"; + case ERROR: + return "ERROR"; + case DEBUG: + return "DEBUG"; + case NONE: + return "NONE"; + default: + return "UNKNOWN"; + } } } // namespace EmbedLog