Skip to content
Snippets Groups Projects
Commit 83706085 authored by Maxence Naud's avatar Maxence Naud Committed by Maxence Naud
Browse files

Enhance: logging format with constant width and default log level to Notice or...

Enhance: logging format with constant width and default log level to Notice or Debug (compilation mode dependent)

- add a helper function to wrap text to a specified width, respecting explicit line breaks (\n) and accounting for ANSI escape sequences.
- set default logging level to Log::Level::Notice in RELEASE compilation mode and Log::Level::Debug in DEBUG compilation mode
parent a5db0d10
No related branches found
No related tags found
2 merge requests!318[Upd] release verision 0.5.0,!313[UPD] add some logging informations
...@@ -21,18 +21,25 @@ ...@@ -21,18 +21,25 @@
namespace Aidge { namespace Aidge {
/** /**
* @brief Initialize console level from environment or default to Info * @brief Initialize console log level from environment. If compile mode is
* DEBUG, then the default level is Log::Level::Debug, else it is
* Log::Level::Notice.
*/ */
Log::Level Log::mConsoleLevel = []() { Log::Level Log::mConsoleLevel = []() {
#ifdef NDEBUG
constexpr Level defaultLevel = Level::Debug;
#else
constexpr Log::Level defaultLevel = Level::Notice;
#endif
if (const char* level = std::getenv("AIDGE_LOGLEVEL_CONSOLE")) { if (const char* level = std::getenv("AIDGE_LOGLEVEL_CONSOLE")) {
return level[0] == 'D' ? Debug : return level[0] == 'D' ? Debug :
level[0] == 'I' ? Info : level[0] == 'I' ? Info :
level[0] == 'N' ? Notice : level[0] == 'N' ? Notice :
level[0] == 'W' ? Warn : level[0] == 'W' ? Warn :
level[0] == 'E' ? Error : level[0] == 'E' ? Error :
level[0] == 'F' ? Fatal : Info; level[0] == 'F' ? Fatal : defaultLevel;
} }
return Info; return defaultLevel;
}(); }();
/** /**
...@@ -46,18 +53,24 @@ bool Log::mConsoleColor = []() { ...@@ -46,18 +53,24 @@ bool Log::mConsoleColor = []() {
}(); }();
/** /**
* @brief Initialize file level from environment or default to Debug * @brief Initialize file log level from environment. If compile mode is DEBUG,
* then the default level is Log::Level::Debug, else it is Log::Level::Notice.
*/ */
Log::Level Log::mFileLevel = []() { Log::Level Log::mFileLevel = []() {
#ifdef NDEBUG
constexpr Level defaultLevel = Level::Debug;
#else
constexpr Log::Level defaultLevel = Level::Notice;
#endif
if (const char* level = std::getenv("AIDGE_LOGLEVEL_FILE")) { if (const char* level = std::getenv("AIDGE_LOGLEVEL_FILE")) {
return level[0] == 'D' ? Debug : return level[0] == 'D' ? Debug :
level[0] == 'I' ? Info : level[0] == 'I' ? Info :
level[0] == 'N' ? Notice : level[0] == 'N' ? Notice :
level[0] == 'W' ? Warn : level[0] == 'W' ? Warn :
level[0] == 'E' ? Error : level[0] == 'E' ? Error :
level[0] == 'F' ? Fatal : Debug; level[0] == 'F' ? Fatal : defaultLevel;
} }
return Debug; return defaultLevel;
}(); }();
/** /**
...@@ -79,8 +92,65 @@ int Log::mFloatingPointPrecision = 5; ...@@ -79,8 +92,65 @@ int Log::mFloatingPointPrecision = 5;
*/ */
void Log::log(Level level, const std::string& msg) { void Log::log(Level level, const std::string& msg) {
/** /**
* @brief Get the terminal color for a log level * @brief Helper function to wrap text to a specified width, respecting
* explicit line breaks (\n) and accounting for ANSI escape sequences.
*/ */
const auto wrapText = [](const std::string& text, const std::size_t width) -> std::vector<std::string> {
std::vector<std::string> wrappedLines;
std::size_t start = 0;
while (start < text.size()) {
std::size_t lineWidth = 0;
std::size_t current = start;
while (current < text.size() && lineWidth < width) {
if (text[current] == '\033') {
// Found ANSI escape sequence, skip until 'm'
std::size_t ansiEnd = text.find('m', current);
if (ansiEnd != std::string::npos) {
// Add the length of the ANSI sequence to the width allowance
// width += (ansiEnd - current + 1);
current = ansiEnd + 1;
} else {
// Malformed sequence, treat as normal characters
++current;
}
} else if (text[current] == '\n') {
// Handle explicit line break
break;
} else {
// Normal character, increase line width
++lineWidth;
++current;
}
}
// Find the end of the current line
std::size_t lineEnd = current;
// Adjust for spaces if needed
if (lineEnd < text.size() && text[lineEnd] != '\n') {
std::size_t lastSpace = text.rfind(' ', lineEnd);
if (lastSpace != std::string::npos && lastSpace > start) {
lineEnd = lastSpace;
}
}
// Add the wrapped line to the result
wrappedLines.push_back(text.substr(start, lineEnd - start));
// Move to the next segment, skipping spaces
start = lineEnd;
while (start < text.size() && (text[start] == ' ' || text[start] == '\n')) {
++start;
}
}
return wrappedLines;
};
// Get the terminal color for the log level
const auto getColor = [](Level lvl) { const auto getColor = [](Level lvl) {
switch (lvl) { switch (lvl) {
case Debug: return fmt::terminal_color::green; case Debug: return fmt::terminal_color::green;
...@@ -93,24 +163,36 @@ void Log::log(Level level, const std::string& msg) { ...@@ -93,24 +163,36 @@ void Log::log(Level level, const std::string& msg) {
} }
}; };
/** // Get the string representation of the log level
* @brief Get the string representation of a log level
*/
const auto levelStr = EnumStrings<Level>::data[static_cast<std::size_t>(level)]; const auto levelStr = EnumStrings<Level>::data[static_cast<std::size_t>(level)];
const std::size_t levelIndentSizes[6] = {10, 9, 11, 12, 10, 10};
const std::size_t width = 80 - levelIndentSizes[static_cast<std::size_t>(level)];
if (level >= mConsoleLevel) { if (level >= mConsoleLevel) {
// Print active contexts
for (const auto& context : mContext) { for (const auto& context : mContext) {
fmt::println("Context: {}", context); fmt::println("Context: {}", context);
} }
// Print message with colored level // Wrap the message and print each line
if (mConsoleColor) { auto wrappedLines = wrapText(msg, width);
fmt::print("["); for (std::size_t i = 0; i < wrappedLines.size(); ++i) {
fmt::print(fg(getColor(level)), "{}", levelStr); if (mConsoleColor) {
fmt::print("] - {}\n", msg); if (i == 0) {
} else { fmt::print("[");
fmt::print("[{}] - {}\n", levelStr, msg); fmt::print(fg(getColor(level)), "{}", levelStr);
fmt::print("] - {}\n", wrappedLines[i]);
} else {
fmt::print("[");
fmt::print(fg(getColor(level)), "{}", levelStr);
fmt::print("] {}\n", wrappedLines[i]);
}
} else {
if (i == 0) {
fmt::print("[{}] - {}\n", levelStr, wrappedLines[i]);
} else {
fmt::print("[{}] {}\n", levelStr, wrappedLines[i]);
}
}
} }
} }
...@@ -118,14 +200,24 @@ void Log::log(Level level, const std::string& msg) { ...@@ -118,14 +200,24 @@ void Log::log(Level level, const std::string& msg) {
if (!mFile) { if (!mFile) {
initFile(mFileName); initFile(mFileName);
} }
// Write contexts and message to file
for (const auto& context : mContext) { for (const auto& context : mContext) {
fmt::println(mFile.get(), "Context: {}", context); fmt::println(mFile.get(), "Context: {}", context);
} }
fmt::println(mFile.get(), "{}: {}", levelStr, msg);
auto wrappedLines = wrapText(msg, width);
for (std::size_t i = 0; i < wrappedLines.size(); ++i) {
if (i == 0) {
fmt::println(mFile.get(), "{}: {}", levelStr, wrappedLines[i]);
} else {
fmt::println(mFile.get(), "{} {}", levelStr, wrappedLines[i]);
}
}
} }
} }
/** /**
* @brief Initialize or re-initialize the log file * @brief Initialize or re-initialize the log file
* @param fileName Path to the log file * @param fileName Path to the log file
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment