Added more colors and background color support

This commit is contained in:
matthias@arch 2022-10-10 00:49:17 +02:00
parent b223c722fb
commit 26c2426b70
2 changed files with 113 additions and 28 deletions

View File

@ -10,30 +10,50 @@ namespace gz {
const char* COLORS[] = { const char* COLORS[] = {
"\033[0m", // RESET "\033[0m", // RESET
"\033[30m", // BLACK // normal
"\033[31m", // RED "\033[0;30m", // BLACK
"\033[32m", // GREEN "\033[0;31m", // RED
"\033[33m", // YELLOW "\033[0;32m", // GREEN
"\033[34m", // BLUE "\033[0;33m", // YELLOW
"\033[35m", // MAGENTA "\033[0;34m", // BLUE
"\033[36m", // CYAN "\033[0;35m", // MAGENTA
"\033[37m", // WHITE "\033[0;36m", // CYAN
"\033[1;30m", // BBLACK "\033[0;37m", // WHITE
"\033[1;31m", // BRED // bold
"\033[1;32m", // BGREEN "\033[0;1;30m", // BO_BLACK
"\033[1;33m", // BYELLOW "\033[0;1;31m", // BO_RED
"\033[1;34m", // BBLUE "\033[0;1;32m", // BO_GREEN
"\033[1;35m", // BMAGENTA "\033[0;1;33m", // BO_YELLOW
"\033[1;36m", // BCYAN "\033[0;1;34m", // BO_BLUE
"\033[1;37m", // BWHITE "\033[0;1;35m", // BO_MAGENTA
"\033[0;1;36m", // BO_CYAN
"\033[0;1;37m", // BO_WHITE
// background
"\033[0;40m", // BO_BLACK
"\033[0;41m", // BO_RED
"\033[0;42m", // BO_GREEN
"\033[0;30;43m", // BO_YELLOW
"\033[0;44m", // BO_BLUE
"\033[0;45m", // BO_MAGENTA
"\033[0;46m", // BO_CYAN
"\033[0;47m", // BO_WHITE
// light
"\033[0;38;5;9m", // LI_RED
"\033[0;38;5;10m", // LI_GREEN
"\033[0;38;5;11m", // LI_YELLOW
"\033[0;38;5;12m", // LI_BLUE
"\033[0;38;5;13m", // LI_MAGENTA
"\033[0;38;5;14m", // LI_CYAN
"\033[0;38;5;15m", // LI_WHITE
"\033[0;38;5;169m", // LI_BLACK
}; };
#ifdef LOG_MULTITHREAD #ifdef LOG_MULTITHREAD
std::mutex Log::mtx; std::mutex Log::mtx;
#endif #endif
Log::Log(std::string logfile, bool showLog, bool storeLog, std::string&& prefix_, Color prefixColor, bool clearLogfileOnRestart, unsigned int writeAfterLines) Log::Log(std::string logfile, bool showLog, bool storeLog, std::string&& prefix_, Color prefixColor, Color timeColor, bool clearLogfileOnRestart, unsigned int writeAfterLines)
: iter(0), writeToFileAfterLines(writeAfterLines), showLog(showLog), storeLog(storeLog), prefixColor(prefixColor), prefix(prefix_ + ": "), prefixLength(prefix.size() + LOG_TIMESTAMP_CHAR_COUNT - 1) { : iter(0), writeToFileAfterLines(writeAfterLines), showLog(showLog), storeLog(storeLog), prefixColor(prefixColor), prefix(prefix_ + ": "), prefixLength(prefix.size() + LOG_TIMESTAMP_CHAR_COUNT - 1), timeColor(timeColor) {
// get absolute path to the logfile // get absolute path to the logfile
fs::path logpath(logfile); fs::path logpath(logfile);
if (!logpath.is_absolute()) { if (!logpath.is_absolute()) {

View File

@ -26,7 +26,11 @@ namespace gz {
// //
/// Colors to be used in Log::clog /// Colors to be used in Log::clog
enum Color { enum Color {
RESET, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, BBLACK, BRED, BGREEN, BYELLOW, BBLUE, BMAGENTA, BCYAN, BWHITE RESET,
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE,
BO_BLACK, BO_RED, BO_GREEN, BO_YELLOW, BO_BLUE, BO_MAGENTA, BO_CYAN, BO_WHITE,
BG_BLACK, BG_RED, BG_GREEN, BG_YELLOW, BG_BLUE, BG_MAGENTA, BG_CYAN, BG_WHITE,
LI_RED, LI_GREEN, LI_YELLOW, LI_BLUE, LI_MAGENTA, LI_CYAN, LI_WHITE, LI_BLACK,
}; };
extern const char* COLORS[]; extern const char* COLORS[];
@ -103,7 +107,7 @@ class Log {
* *
* @note Colors will only be shown when written to stdout, not in the logfile. * @note Colors will only be shown when written to stdout, not in the logfile.
*/ */
Log(std::string logfile="log.log", bool showLog=true, bool storeLog=true, std::string&& prefix="", Color prefixColor=RESET, bool clearLogfileOnRestart=true, unsigned int writeAfterLines=100); Log(std::string logfile="log.log", bool showLog=true, bool storeLog=true, std::string&& prefix="", Color prefixColor=RESET, Color timeColor=RESET, bool clearLogfileOnRestart=true, unsigned int writeAfterLines=100);
~Log(); ~Log();
@ -127,9 +131,11 @@ class Log {
vlog(" ", std::forward<Args>(args)...); vlog(" ", std::forward<Args>(args)...);
logLines[iter] += "\n"; logLines[iter] += "\n";
std::cout << std::string_view(logLines[iter].c_str(), LOG_TIMESTAMP_CHAR_COUNT - 1) << if (showLog) {
COLORS[prefixColor] << prefix << COLORS[RESET] << std::cout << COLORS[timeColor] << std::string_view(logLines[iter].c_str(), LOG_TIMESTAMP_CHAR_COUNT - 1) <<
std::string_view(logLines[iter].begin() + prefixLength, logLines[iter].end()); COLORS[prefixColor] << prefix << COLORS[RESET] <<
std::string_view(logLines[iter].begin() + prefixLength, logLines[iter].end());
}
if (++iter >= writeToFileAfterLines) { if (++iter >= writeToFileAfterLines) {
iter = 0; iter = 0;
writeLog(); writeLog();
@ -188,14 +194,16 @@ class Log {
#endif #endif
getTime(); getTime();
logLines[iter] = std::string(time); logLines[iter] = std::string(time);
logLines[iter] += prefix + ": " + type + ": "; logLines[iter] += prefix + type + ": ";
vlog(" ", std::forward<Args>(args)...); vlog(" ", std::forward<Args>(args)...);
logLines[iter] += "\n"; logLines[iter] += "\n";
std::cout << std::string_view(logLines[iter].c_str(), LOG_TIMESTAMP_CHAR_COUNT - 1) << if (showLog) {
COLORS[prefixColor] << prefix << COLORS[typeColor] << std::cout << COLORS[timeColor] << std::string_view(logLines[iter].c_str(), LOG_TIMESTAMP_CHAR_COUNT - 1) <<
std::string_view(logLines[iter].begin() + prefixLength + LOG_POSTPREFIX_CHAR_COUNT, logLines[iter].begin() + prefixLength + type.size() + 2 * LOG_POSTPREFIX_CHAR_COUNT) << COLORS[prefixColor] << prefix << COLORS[typeColor] <<
COLORS[messageColor] << std::string_view(logLines[iter].begin() + prefixLength + type.size() + 2 * LOG_POSTPREFIX_CHAR_COUNT, logLines[iter].end()) << COLORS[RESET]; std::string_view(logLines[iter].begin() + prefixLength + LOG_POSTPREFIX_CHAR_COUNT, logLines[iter].begin() + prefixLength + type.size() + 2 * LOG_POSTPREFIX_CHAR_COUNT) <<
COLORS[messageColor] << std::string_view(logLines[iter].begin() + prefixLength + type.size() + 2 * LOG_POSTPREFIX_CHAR_COUNT, logLines[iter].end()) << COLORS[RESET];
}
if (++iter >= writeToFileAfterLines) { if (++iter >= writeToFileAfterLines) {
iter = 0; iter = 0;
writeLog(); writeLog();
@ -205,11 +213,64 @@ class Log {
#endif #endif
} }
/**
* @brief Log a message in a certain color
* @details
* The message will look like this:
* <time>: <prefix>: <message0>, <message1>...
* where time will be white, prefix in prefixColor, and messageI in colors[I].
* If there are less colors than message arguments, the last color is used for all remaining messages.
* @param args Any number of arguments that satisfy concept Logable
* @param colors Vector of colors, where the nth color refers to the nth arg
*/
template<Logable... Args>
void clog(const std::vector<Color>& colors, Args&&... args) {
#ifdef LOG_MULTITHREAD
mtx.lock();
#endif
argsBegin.clear();
argsBegin.emplace_back(0);
getTime();
logLines[iter] = std::string(time);
argsBegin.emplace_back(logLines[iter].size());
logLines[iter] += prefix;
vlog(" ", std::forward<Args>(args)...);
logLines[iter] += "\n";
argsBegin.emplace_back(logLines[iter].size());
/* std::cout << "Log has Views:\n"; */
/* for (auto& view : argsBegin) { */
/* std::cout << "\t" << view << "\n"; */
/* } */
if (showLog) {
// log prefix
std::cout << COLORS[timeColor] <<
std::string_view(logLines[iter].begin() + argsBegin[0], logLines[iter].begin() + argsBegin[1]) << COLORS[prefixColor] <<
std::string_view(logLines[iter].begin() + argsBegin[1], logLines[iter].begin() + argsBegin[2]) << COLORS[RESET];
// max index where i can be used for colors and i+3 can be used for currentViews
size_t maxI = std::min(colors.size(), argsBegin.size() - 3);
for (size_t i = 0; i < maxI; i++) {
std::cout << COLORS[colors[i]] << std::string_view(logLines[iter].begin() + argsBegin[i+2], logLines[iter].begin() + argsBegin[i+3]);
}
// log the rest, maxI is now <= argsBegin.size() - 3
std::cout << std::string_view(logLines[iter].begin() + argsBegin[maxI+2], logLines[iter].end()) << COLORS[RESET];
}
if (++iter >= writeToFileAfterLines) {
iter = 0;
writeLog();
}
#ifdef LOG_MULTITHREAD
mtx.unlock();
#endif
};
private: private:
// vlog for variadic log // vlog for variadic log
/// Log anything that can be appendend to std::string /// Log anything that can be appendend to std::string
template<util::Stringy T, Logable... Args> template<util::Stringy T, Logable... Args>
void vlog(const char* appendChars, T&& t, Args&&... args) { void vlog(const char* appendChars, T&& t, Args&&... args) {
argsBegin.emplace_back(logLines[iter].size());
logLines[iter] += t; logLines[iter] += t;
logLines[iter] += appendChars; logLines[iter] += appendChars;
vlog(" ", std::forward< Args>(args)...); vlog(" ", std::forward< Args>(args)...);
@ -217,6 +278,7 @@ class Log {
/// Log anything where toString exists /// Log anything where toString exists
template<ConvertibleToString T, Logable... Args> template<ConvertibleToString T, Logable... Args>
void vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy<T>) { void vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy<T>) {
argsBegin.emplace_back(logLines[iter].size());
logLines[iter] += toString(t); logLines[iter] += toString(t);
logLines[iter] += appendChars; logLines[iter] += appendChars;
vlog(" ", std::forward< Args>(args)...); vlog(" ", std::forward< Args>(args)...);
@ -227,6 +289,8 @@ class Log {
private: private:
/// Where the lines are stored /// Where the lines are stored
std::vector<std::string> logLines; std::vector<std::string> logLines;
/// Used during log: string views into the single substrings in logLines[currentLine]
std::vector<std::string::size_type> argsBegin;
/// The current position in logLines /// The current position in logLines
size_t iter = 0; size_t iter = 0;
/// When iter reaches writeToFileAfterLines, write log to file /// When iter reaches writeToFileAfterLines, write log to file
@ -240,6 +304,7 @@ class Log {
Color prefixColor; Color prefixColor;
std::string prefix; std::string prefix;
std::string::size_type prefixLength; std::string::size_type prefixLength;
Color timeColor;
/// Stores the current time in yyyy-mm-dd hh:mm:ss format /// Stores the current time in yyyy-mm-dd hh:mm:ss format
char time[LOG_TIMESTAMP_CHAR_COUNT]; char time[LOG_TIMESTAMP_CHAR_COUNT];