Added constructor with create info struct
This commit is contained in:
parent
2b1c034a55
commit
a58e324d7a
58
src/log.cpp
58
src/log.cpp
@ -5,7 +5,6 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
namespace gz {
|
namespace gz {
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
const char* COLORS[] = {
|
const char* COLORS[] = {
|
||||||
@ -52,8 +51,8 @@ namespace gz {
|
|||||||
#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, Color timeColor, bool clearLogfileOnRestart, unsigned int writeAfterLines)
|
Log::Log(std::string logfile, bool showLog, bool storeLog, std::string&& prefix_, Color prefixColor, bool showTime, 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), timeColor(timeColor) {
|
: iter(0), writeToFileAfterLines(writeAfterLines), storeLog(storeLog), showLog(showLog), 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()) {
|
||||||
@ -80,6 +79,59 @@ namespace gz {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showTime) {
|
||||||
|
prefixLength = prefix.size() + LOG_TIMESTAMP_CHAR_COUNT - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefixLength = prefix.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log("Initialising log with settings: logFile: " + logFile + */
|
||||||
|
/* ", showLog - " + boolToString(showLog) + ", storeLog - " + boolToString(storeLog)); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Log::Log(LogCreateInfo&& ci)
|
||||||
|
: iter(0),
|
||||||
|
writeToFileAfterLines(ci.writeAfterLines), storeLog(ci.storeLog),
|
||||||
|
showLog(ci.showLog),
|
||||||
|
prefixColor(ci.prefixColor),
|
||||||
|
prefix(std::move(ci.prefix) + ": "),
|
||||||
|
showTime(ci.showTime), timeColor(ci.timeColor)
|
||||||
|
{
|
||||||
|
// get absolute path to the logfile
|
||||||
|
fs::path logpath(ci.logfile);
|
||||||
|
if (!logpath.is_absolute()) {
|
||||||
|
logpath = fs::current_path() / logpath;
|
||||||
|
}
|
||||||
|
// create directory of logfile
|
||||||
|
if (!fs::is_directory(logpath.parent_path())) {
|
||||||
|
fs::create_directory(logpath.parent_path());
|
||||||
|
}
|
||||||
|
logFile = logpath.string();
|
||||||
|
|
||||||
|
// if clearLogfileOnRestart, open the file to clear it
|
||||||
|
if (ci.clearLogfileOnRestart and fs::is_regular_file(logpath)) {
|
||||||
|
std::ofstream file(logFile, std::ofstream::trunc);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeToFileAfterLines == 0) { writeToFileAfterLines = 1; }
|
||||||
|
logLines.resize(writeToFileAfterLines);
|
||||||
|
// reserve memory for strings
|
||||||
|
if (LOG_RESERVE_STRING_SIZE > 0) {
|
||||||
|
for (size_t i = 0; i < logLines.size(); i++) {
|
||||||
|
logLines[i].reserve(LOG_RESERVE_STRING_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showTime) {
|
||||||
|
prefixLength = prefix.size() + LOG_TIMESTAMP_CHAR_COUNT - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefixLength = prefix.size();
|
||||||
|
}
|
||||||
|
|
||||||
/* log("Initialising log with settings: logFile: " + logFile + */
|
/* log("Initialising log with settings: logFile: " + logFile + */
|
||||||
/* ", showLog - " + boolToString(showLog) + ", storeLog - " + boolToString(storeLog)); */
|
/* ", showLog - " + boolToString(showLog) + ", storeLog - " + boolToString(storeLog)); */
|
||||||
}
|
}
|
||||||
|
165
src/log.hpp
165
src/log.hpp
@ -63,6 +63,30 @@ namespace gz {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Logable = ConvertibleToString<T>;
|
concept Logable = ConvertibleToString<T>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create info for a Log object
|
||||||
|
*/
|
||||||
|
struct LogCreateInfo {
|
||||||
|
/// @brief Absolute or relative path to the logfile
|
||||||
|
std::string logfile = "log.log";
|
||||||
|
/// @brief Wether to print the messages to stdout
|
||||||
|
bool showLog = true;
|
||||||
|
/// @brief Wether to save the messages to the logfile
|
||||||
|
bool storeLog = true;
|
||||||
|
/// @brief A prefix that comes between the timestamp and the message. ": " is automatically appended to the prefix
|
||||||
|
std::string prefix = "";
|
||||||
|
/// @brief The color of the prefix
|
||||||
|
Color prefixColor = RESET;
|
||||||
|
/// @brief Wether to prepend a timestamp to the message
|
||||||
|
bool showTime = true;
|
||||||
|
/// @brief The color of the timestamp
|
||||||
|
Color timeColor = RESET;
|
||||||
|
/// @brief If true, clear the logfile when initializing the log. That means only the log of most recent run is stored
|
||||||
|
bool clearLogfileOnRestart = true;
|
||||||
|
/// @brief Actually write the log to the logfile after so many lines. Must be at least 1
|
||||||
|
unsigned int writeAfterLines = 100;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Manages printing messages to stdout and to logfiles.
|
* @brief Manages printing messages to stdout and to logfiles.
|
||||||
* @details
|
* @details
|
||||||
@ -94,23 +118,27 @@ class Log {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Creates a log object, which can print messages to stdout and/or write them to a log file
|
* @brief Creates a log object, which can print messages to stdout and/or write them to a log file
|
||||||
* @details By creating multiple instances with different parameters, logs can be easily turned on/off for different usages.
|
* @details
|
||||||
* If not existent, the parent directory of the logfile and the file itself will be created when initializing a log.
|
* By creating multiple instances with different parameters, logs can be easily turned on/off for different usages.
|
||||||
*
|
|
||||||
* @param logfile: Absolute or relative path to the logfile
|
|
||||||
* @param showLog: Wether to print the messages to stdout
|
|
||||||
* @param storeLog: Wether to save the messages to the logfile
|
|
||||||
* @param prefix: A prefix that comes between the timestamp and the message. ": " is automatically appended to the prefix
|
|
||||||
* @param prefixColor: The color of the prefix
|
|
||||||
* @param clearLogfileOnRestart: If true, clear the logfile when initializing the log. That means only the log of most recent run is stored
|
|
||||||
* @param writeAfterLines: Actually write the log to the logfile after so many lines. Must be at least 1
|
|
||||||
*
|
*
|
||||||
|
* The overload using LogCreateInfo might be more clear, so I recommend using that.
|
||||||
* @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.
|
||||||
|
* @deprecated Use the overload using the LogCreateInfo struct
|
||||||
*/
|
*/
|
||||||
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(std::string logfile="log.log", bool showLog=true, bool storeLog=true, std::string&& prefix="", Color prefixColor=RESET, bool showTime=true, Color timeColor=RESET, bool clearLogfileOnRestart=true, unsigned int writeAfterLines=100);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a log object, which can print messages to stdout and/or write them to a log file
|
||||||
|
* @details
|
||||||
|
* By creating multiple instances with different parameters, logs can be easily turned on/off for different usages.
|
||||||
|
*/
|
||||||
|
Log(LogCreateInfo&& createInfo);
|
||||||
|
|
||||||
~Log();
|
~Log();
|
||||||
|
|
||||||
|
//
|
||||||
|
// ACTUAL LOGGING
|
||||||
|
//
|
||||||
/**
|
/**
|
||||||
* @brief Logs a message
|
* @brief Logs a message
|
||||||
* @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile.
|
* @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile.
|
||||||
@ -125,8 +153,13 @@ class Log {
|
|||||||
#ifdef LOG_MULTITHREAD
|
#ifdef LOG_MULTITHREAD
|
||||||
mtx.lock();
|
mtx.lock();
|
||||||
#endif
|
#endif
|
||||||
getTime();
|
if (showTime) {
|
||||||
logLines[iter] = time;
|
getTime();
|
||||||
|
logLines[iter] = time;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logLines[iter].clear();
|
||||||
|
}
|
||||||
logLines[iter] += prefix;
|
logLines[iter] += prefix;
|
||||||
vlog(" ", std::forward<Args>(args)...);
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
logLines[iter] += "\n";
|
logLines[iter] += "\n";
|
||||||
@ -145,40 +178,6 @@ class Log {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Logs a message. Overload for convenience, same behavior as log()
|
|
||||||
*/
|
|
||||||
template<Logable... Args>
|
|
||||||
void operator() (Args&&... args) {
|
|
||||||
log(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Log an error
|
|
||||||
* @details Prints the message with a red "Error: " prefix.
|
|
||||||
* The message will look like this:
|
|
||||||
* <time>: <prefix>: Error: <message>
|
|
||||||
* where time will be white, prefix in prefixColor, Error in red and message white.
|
|
||||||
* @param args Any number of arguments that satisfy concept Logable
|
|
||||||
*/
|
|
||||||
template<Logable... Args>
|
|
||||||
void error(Args&&... args) {
|
|
||||||
clog(RED, "Error", WHITE, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Log a warnign
|
|
||||||
* @details Prints the message with a yellow "Warning: " prefix.
|
|
||||||
* The message will look like this:
|
|
||||||
* <time>: <prefix>: Warning: <message>
|
|
||||||
* where time will be white, prefix in prefixColor, Warning in yellow and message white.
|
|
||||||
* @param args Any number of arguments that satisfy concept Logable
|
|
||||||
*/
|
|
||||||
template<Logable... Args>
|
|
||||||
void warning(Args&&... args) {
|
|
||||||
clog(YELLOW, "Warning", WHITE, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Log a message in a certain color and with a colored type
|
* @brief Log a message in a certain color and with a colored type
|
||||||
* @details
|
* @details
|
||||||
@ -192,8 +191,13 @@ class Log {
|
|||||||
#ifdef LOG_MULTITHREAD
|
#ifdef LOG_MULTITHREAD
|
||||||
mtx.lock();
|
mtx.lock();
|
||||||
#endif
|
#endif
|
||||||
getTime();
|
if (showTime) {
|
||||||
logLines[iter] = std::string(time);
|
getTime();
|
||||||
|
logLines[iter] = std::string(time);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logLines[iter].clear();
|
||||||
|
}
|
||||||
logLines[iter] += prefix + type + ": ";
|
logLines[iter] += prefix + type + ": ";
|
||||||
vlog(" ", std::forward<Args>(args)...);
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
logLines[iter] += "\n";
|
logLines[iter] += "\n";
|
||||||
@ -230,8 +234,13 @@ class Log {
|
|||||||
#endif
|
#endif
|
||||||
argsBegin.clear();
|
argsBegin.clear();
|
||||||
argsBegin.emplace_back(0);
|
argsBegin.emplace_back(0);
|
||||||
getTime();
|
if (showTime) {
|
||||||
logLines[iter] = std::string(time);
|
getTime();
|
||||||
|
logLines[iter] = std::string(time);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logLines.clear();
|
||||||
|
}
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
logLines[iter] += prefix;
|
logLines[iter] += prefix;
|
||||||
|
|
||||||
@ -265,6 +274,44 @@ class Log {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CONVENCIENCE
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* @brief Logs a message. Overload for convenience, same behavior as log()
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
void operator() (Args&&... args) {
|
||||||
|
log(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log an error
|
||||||
|
* @details Prints the message with a red "Error: " prefix.
|
||||||
|
* The message will look like this:
|
||||||
|
* <time>: <prefix>: Error: <message>
|
||||||
|
* where time will be white, prefix in prefixColor, Error in red and message white.
|
||||||
|
* @param args Any number of arguments that satisfy concept Logable
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
void error(Args&&... args) {
|
||||||
|
clog(RED, "Error", WHITE, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Log a warnign
|
||||||
|
* @details Prints the message with a yellow "Warning: " prefix.
|
||||||
|
* The message will look like this:
|
||||||
|
* <time>: <prefix>: Warning: <message>
|
||||||
|
* where time will be white, prefix in prefixColor, Warning in yellow and message white.
|
||||||
|
* @param args Any number of arguments that satisfy concept Logable
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
void warning(Args&&... args) {
|
||||||
|
clog(YELLOW, "Warning", WHITE, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -293,23 +340,35 @@ class Log {
|
|||||||
std::vector<std::string::size_type> argsBegin;
|
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;
|
||||||
|
/**
|
||||||
|
* @name Writing to file
|
||||||
|
*/
|
||||||
|
/// @{
|
||||||
/// When iter reaches writeToFileAfterLines, write log to file
|
/// When iter reaches writeToFileAfterLines, write log to file
|
||||||
unsigned int writeToFileAfterLines;
|
unsigned int writeToFileAfterLines;
|
||||||
/// Absolute path to the logfile
|
/// Absolute path to the logfile
|
||||||
std::string logFile;
|
std::string logFile;
|
||||||
bool showLog;
|
|
||||||
bool storeLog;
|
bool storeLog;
|
||||||
void writeLog();
|
void writeLog();
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
bool showLog;
|
||||||
Color prefixColor;
|
Color prefixColor;
|
||||||
std::string prefix;
|
std::string prefix;
|
||||||
std::string::size_type prefixLength;
|
std::string::size_type prefixLength;
|
||||||
Color timeColor;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Time
|
||||||
|
*/
|
||||||
|
/// @{
|
||||||
|
bool showTime;
|
||||||
|
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];
|
||||||
/// Store the current time in yyyy-mm-dd hh:mm:ss format in time member
|
/// Store the current time in yyyy-mm-dd hh:mm:ss format in time member
|
||||||
void getTime();
|
void getTime();
|
||||||
|
/// @}
|
||||||
|
|
||||||
#ifdef LOG_MULTITHREAD
|
#ifdef LOG_MULTITHREAD
|
||||||
/// Lock for std::cout
|
/// Lock for std::cout
|
||||||
static std::mutex mtx;
|
static std::mutex mtx;
|
||||||
|
Loading…
Reference in New Issue
Block a user