|
|
|
@ -11,7 +11,6 @@
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <blt/config.h>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
namespace blt::logging {
|
|
|
|
|
|
|
|
|
@ -68,9 +67,33 @@ namespace blt::logging {
|
|
|
|
|
* - ${{RAW_STR}} // raw user string without formatting applied (NOTE: format args are not provided!)
|
|
|
|
|
* - ${{STR}} // the user supplied string (format applied!)
|
|
|
|
|
*/
|
|
|
|
|
std::string logOutputFormat = "[${{HOUR}}:${{MINUTE}}:${{SECOND}] ${{LF}}[${{LOG_LEVEL}}]${{R}} ${{CNR}}${{STR}}";
|
|
|
|
|
std::string levelNames[10] = {"STDOUT", "TRACE0, TRACE1, TRACE2", "TRACE3", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
|
|
|
|
|
std::string levelColors[10] = {"\033[0m", "\033[22;97m", "\033[97m", "\033[97m", "\033[97m", "\033[36m", "\033[92m", "\033[93m", "\033[91m", "\033[97;41m"};
|
|
|
|
|
std::string logOutputFormat = "\033[94m[${{TIME}}]${{RC}} ${{LF}}[${{LOG_LEVEL}}]${{RC}} \033[35m(${{FILE}}:${{LINE}})${{RC}} ${{CNR}}${{STR}}${{RC}}\n";
|
|
|
|
|
std::string levelNames[11] = {"STDOUT", "TRACE0", "TRACE1", "TRACE2", "TRACE3", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
|
|
|
|
|
std::string levelColors[11] = {"\033[0m", "\033[22;97m", "\033[97m", "\033[97m", "\033[97m", "\033[97m", "\033[36m", "\033[92m", "\033[93m", "\033[91m", "\033[97;41m"};
|
|
|
|
|
// if true prints the whole path to the file (eg /home/user/.../.../project/src/source.cpp:line#)
|
|
|
|
|
bool printFullFileName = false;
|
|
|
|
|
// the logging lib will keep track of the largest line found so far and try to keep the spacing accordingly
|
|
|
|
|
// this is not thread safe!
|
|
|
|
|
bool ensureAlignment = false;
|
|
|
|
|
// should we log to file?
|
|
|
|
|
bool logToFile = true;
|
|
|
|
|
// should we log to console?
|
|
|
|
|
bool logToConsole = true;
|
|
|
|
|
// where should we log? (empty for current binary directory) should end in a / if not empty!
|
|
|
|
|
std::string logFilePath;
|
|
|
|
|
// logs to a file called $fileName_$count.log where count is the number of rollover files
|
|
|
|
|
// this accepts any of the macros above, using level names and colors should work but isn't supported.
|
|
|
|
|
std::string logFileName = "${{ISO_YEAR}}";
|
|
|
|
|
// default limit on file size: 10mb;
|
|
|
|
|
size_t logMaxFileSize = 1024 * 1024 * 10;
|
|
|
|
|
/**
|
|
|
|
|
* Variables below this line should never be changed by the user!
|
|
|
|
|
*/
|
|
|
|
|
// the current alignment width found (you shouldn't chance this variable!)
|
|
|
|
|
size_t currentWidth = 0;
|
|
|
|
|
// current number of file roll-overs. you shouldn't change this either.
|
|
|
|
|
size_t currentRollover = 0;
|
|
|
|
|
std::string lastFile;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct logger {
|
|
|
|
@ -119,9 +142,18 @@ namespace blt::logging {
|
|
|
|
|
void flush();
|
|
|
|
|
|
|
|
|
|
void setThreadName(const std::string& name);
|
|
|
|
|
void setLogFormat(const log_format& format);
|
|
|
|
|
void setLogColor(log_level level, const std::string& newFormat);
|
|
|
|
|
void setLogName(log_level level, const std::string& newFormat);
|
|
|
|
|
void setLogOutputFormat(const std::string& newFormat);
|
|
|
|
|
void setLogToFile(bool shouldLogToFile);
|
|
|
|
|
void setLogToConsole(bool shouldLogToConsole);
|
|
|
|
|
void setLogPath(const std::string& path);
|
|
|
|
|
void setLogFileName(const std::string& fileName);
|
|
|
|
|
void setMaxFileSize(size_t fileSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define BLT_LOGGING_IMPLEMENTATION
|
|
|
|
|
//#define BLT_LOGGING_IMPLEMENTATION
|
|
|
|
|
#ifdef BLT_LOGGING_IMPLEMENTATION
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
@ -130,6 +162,10 @@ namespace blt::logging {
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <cstdarg>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <filesystem>
|
|
|
|
|
#include <ios>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
namespace blt::logging {
|
|
|
|
|
|
|
|
|
@ -141,7 +177,7 @@ namespace blt::logging {
|
|
|
|
|
tag* tags;
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] inline size_t hash(const tag& t) const {
|
|
|
|
|
[[nodiscard]] static inline size_t hash(const tag& t) {
|
|
|
|
|
size_t h = t.tag[0]+ t.tag[1] * 3;
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
@ -172,7 +208,7 @@ namespace blt::logging {
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tag& operator[](const std::string& name){
|
|
|
|
|
tag& operator[](const std::string& name) const {
|
|
|
|
|
auto h = hash(tag{name, nullptr});
|
|
|
|
|
if (h > size)
|
|
|
|
|
std::cerr << "Tag out of bounds";
|
|
|
|
@ -184,17 +220,57 @@ namespace blt::logging {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class LogFileWriter {
|
|
|
|
|
private:
|
|
|
|
|
std::string m_path;
|
|
|
|
|
std::fstream* output = nullptr;
|
|
|
|
|
public:
|
|
|
|
|
explicit LogFileWriter() = default;
|
|
|
|
|
|
|
|
|
|
void writeLine(const std::string& path, const std::string& line){
|
|
|
|
|
if (path != m_path || output == nullptr){
|
|
|
|
|
clear();
|
|
|
|
|
delete output;
|
|
|
|
|
output = new std::fstream(path, std::ios::out | std::ios::app);
|
|
|
|
|
if (!output->good()){
|
|
|
|
|
throw std::runtime_error("Unable to open console filestream!\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!output->good()){
|
|
|
|
|
std::cerr << "There has been an error in the logging file stream!\n";
|
|
|
|
|
output->clear();
|
|
|
|
|
}
|
|
|
|
|
*output << line;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear(){
|
|
|
|
|
if (output != nullptr) {
|
|
|
|
|
try {
|
|
|
|
|
output->flush();
|
|
|
|
|
output->close();
|
|
|
|
|
} catch (std::exception& e){
|
|
|
|
|
std::cerr << e.what() << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~LogFileWriter() {
|
|
|
|
|
clear();
|
|
|
|
|
delete(output);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define BLT_NOW() auto t = std::time(nullptr); auto now = std::localtime(&t)
|
|
|
|
|
#define BLT_ISO_YEAR(S) auto S = std::to_string(now->tm_year); \
|
|
|
|
|
#define BLT_ISO_YEAR(S) auto S = std::to_string(now->tm_year + 1900); \
|
|
|
|
|
S += '-'; \
|
|
|
|
|
S += std::to_string(now->tm_mon); \
|
|
|
|
|
S += ensureHasDigits(now->tm_mon, 2); \
|
|
|
|
|
S += '-'; \
|
|
|
|
|
S += std::to_string(now->tm_mday);
|
|
|
|
|
#define BLT_CUR_TIME(S) auto S = std::to_string(now->tm_hour); \
|
|
|
|
|
S += '-'; \
|
|
|
|
|
S += std::to_string(now->tm_min); \
|
|
|
|
|
S += '-'; \
|
|
|
|
|
S += std::to_string(now->tm_sec);
|
|
|
|
|
S += ensureHasDigits(now->tm_mday, 2);
|
|
|
|
|
#define BLT_CUR_TIME(S) auto S = ensureHasDigits(now->tm_hour, 2); \
|
|
|
|
|
S += ':'; \
|
|
|
|
|
S += ensureHasDigits(now->tm_min, 2); \
|
|
|
|
|
S += ':'; \
|
|
|
|
|
S += ensureHasDigits(now->tm_sec, 2);
|
|
|
|
|
|
|
|
|
|
static inline std::string ensureHasDigits(int current, int digits) {
|
|
|
|
|
std::string asString = std::to_string(current);
|
|
|
|
@ -212,6 +288,7 @@ namespace blt::logging {
|
|
|
|
|
log_format loggingFormat {};
|
|
|
|
|
hashmap<std::thread::id, std::string> loggingThreadNames;
|
|
|
|
|
hashmap<std::thread::id, hashmap<blt::logging::log_level, std::string>> loggingStreamLines;
|
|
|
|
|
LogFileWriter writer;
|
|
|
|
|
|
|
|
|
|
const tag_map tagMap = {
|
|
|
|
|
{"YEAR", [](const tag_func_param&) -> std::string {
|
|
|
|
@ -313,8 +390,8 @@ namespace blt::logging {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline std::string filename(const std::string& path){
|
|
|
|
|
// if (BLT_LOGGING_PROPERTIES.m_logFullPath)
|
|
|
|
|
// return path;
|
|
|
|
|
if (loggingFormat.printFullFileName)
|
|
|
|
|
return path;
|
|
|
|
|
auto paths = split(path, "/");
|
|
|
|
|
auto final = paths[paths.size()-1];
|
|
|
|
|
if (final == "/")
|
|
|
|
@ -338,20 +415,150 @@ namespace blt::logging {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string applyFormatString(const std::string& str){
|
|
|
|
|
return str;
|
|
|
|
|
std::string stripANSI(const std::string& str){
|
|
|
|
|
string_parser parser(str);
|
|
|
|
|
std::string out;
|
|
|
|
|
while (parser.has_next()){
|
|
|
|
|
char c = parser.next();
|
|
|
|
|
if (c == '\033'){
|
|
|
|
|
while (parser.has_next() && parser.next() != 'm');
|
|
|
|
|
} else
|
|
|
|
|
out += c;
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void applyCFormatting(const std::string& format, std::string& output, va_list& args){
|
|
|
|
|
// args must be copied because they will be consumed by the first vsnprintf
|
|
|
|
|
va_list args_copy;
|
|
|
|
|
va_copy(args_copy, args);
|
|
|
|
|
|
|
|
|
|
auto buffer_size = std::vsnprintf(nullptr, 0, format.c_str(), args_copy) + 1;
|
|
|
|
|
auto* buffer = new char[static_cast<unsigned long>(buffer_size)];
|
|
|
|
|
|
|
|
|
|
vsnprintf(buffer, buffer_size, format.c_str(), args);
|
|
|
|
|
output = std::string(buffer);
|
|
|
|
|
|
|
|
|
|
delete[] buffer;
|
|
|
|
|
|
|
|
|
|
va_end(args_copy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if the next character in the parser is a tag opening, if not output the chars to the out string
|
|
|
|
|
*/
|
|
|
|
|
inline bool tagOpening(string_parser& parser, std::string& out){
|
|
|
|
|
char c;
|
|
|
|
|
if (parser.has_next() && (c = parser.next()) == '{')
|
|
|
|
|
if (parser.has_next() && (c = parser.next()) == '{')
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
out += c;
|
|
|
|
|
else
|
|
|
|
|
out += c;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void parseString(string_parser& parser, std::string& out, const std::string& userStr, log_level level, const char* file, int line){
|
|
|
|
|
while (parser.has_next()){
|
|
|
|
|
char c = parser.next();
|
|
|
|
|
std::string nonTag;
|
|
|
|
|
if (c == '$' && tagOpening(parser, nonTag)){
|
|
|
|
|
std::string tag;
|
|
|
|
|
while (parser.has_next()){
|
|
|
|
|
c = parser.next();
|
|
|
|
|
if (c == '}')
|
|
|
|
|
break;
|
|
|
|
|
tag += c;
|
|
|
|
|
}
|
|
|
|
|
c = parser.next();
|
|
|
|
|
if (parser.has_next() && c != '}') {
|
|
|
|
|
std::cerr << "Error processing tag, is not closed with two '}'!\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (loggingFormat.ensureAlignment && tag == "STR") {
|
|
|
|
|
auto currentOutputWidth = out.size();
|
|
|
|
|
auto& longestWidth = loggingFormat.currentWidth;
|
|
|
|
|
longestWidth = std::max(longestWidth, currentOutputWidth);
|
|
|
|
|
// pad with spaces
|
|
|
|
|
if (currentOutputWidth != longestWidth){
|
|
|
|
|
for (size_t i = currentOutputWidth; i < longestWidth; i++)
|
|
|
|
|
out += ' ';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tag_func_param param{
|
|
|
|
|
level, filename({file}), std::to_string(line), userStr, userStr
|
|
|
|
|
};
|
|
|
|
|
out += tagMap[tag].func(param);
|
|
|
|
|
} else {
|
|
|
|
|
out += c;
|
|
|
|
|
out += nonTag;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string applyFormatString(const std::string& str, log_level level, const char* file, int line){
|
|
|
|
|
// this can be speedup by preprocessing the string into an easily callable class
|
|
|
|
|
// where all the variables are ready to be substituted in one step
|
|
|
|
|
// and all static information already entered
|
|
|
|
|
string_parser parser(loggingFormat.logOutputFormat);
|
|
|
|
|
std::string out;
|
|
|
|
|
parseString(parser, out, str, level, file, line);
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void log(const std::string& format, log_level level, const char* file, int line, ...) {
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, line);
|
|
|
|
|
|
|
|
|
|
std::string out = format;
|
|
|
|
|
std::string withoutLn = format;
|
|
|
|
|
auto len = withoutLn.length();
|
|
|
|
|
|
|
|
|
|
if (out.length() > 0 && out[out.length() - 1] == '\n')
|
|
|
|
|
out = out.substr(0, out.length()-1);
|
|
|
|
|
if (len > 0 && withoutLn[len - 1] == '\n')
|
|
|
|
|
withoutLn = withoutLn.substr(0, len-1);
|
|
|
|
|
|
|
|
|
|
std::string out;
|
|
|
|
|
|
|
|
|
|
applyCFormatting(withoutLn, out, args);
|
|
|
|
|
|
|
|
|
|
std::string finalFormattedOutput = applyFormatString(out, level, file, line);
|
|
|
|
|
|
|
|
|
|
if (loggingFormat.logToConsole)
|
|
|
|
|
std::cout << finalFormattedOutput;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loggingFormat.logToFile){
|
|
|
|
|
string_parser parser(loggingFormat.logFileName);
|
|
|
|
|
std::string fileName;
|
|
|
|
|
parseString(parser, fileName, withoutLn, level, file, line);
|
|
|
|
|
|
|
|
|
|
auto path = loggingFormat.logFilePath;
|
|
|
|
|
if (!path.empty() && path[path.length()-1] != '/')
|
|
|
|
|
path += '/';
|
|
|
|
|
|
|
|
|
|
// if the file has changed (new day in default case) we should reset the rollover count
|
|
|
|
|
if (loggingFormat.lastFile != fileName){
|
|
|
|
|
loggingFormat.currentRollover = 0;
|
|
|
|
|
loggingFormat.lastFile = fileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
path += fileName;
|
|
|
|
|
path += '-';
|
|
|
|
|
path += std::to_string(loggingFormat.currentRollover);
|
|
|
|
|
path += ".log";
|
|
|
|
|
|
|
|
|
|
if (std::filesystem::exists(path)) {
|
|
|
|
|
auto fileSize = std::filesystem::file_size(path);
|
|
|
|
|
|
|
|
|
|
// will start on next file
|
|
|
|
|
if (fileSize > loggingFormat.logMaxFileSize)
|
|
|
|
|
loggingFormat.currentRollover++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writer.writeLine(path, stripANSI(finalFormattedOutput));
|
|
|
|
|
}
|
|
|
|
|
//std::cout.flush();
|
|
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
@ -371,6 +578,34 @@ namespace blt::logging {
|
|
|
|
|
loggingThreadNames[std::this_thread::get_id()] = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setLogFormat(const log_format& format){
|
|
|
|
|
loggingFormat = format;
|
|
|
|
|
}
|
|
|
|
|
void setLogColor(log_level level, const std::string& newFormat){
|
|
|
|
|
loggingFormat.levelColors[(int)level] = newFormat;
|
|
|
|
|
}
|
|
|
|
|
void setLogName(log_level level, const std::string& newFormat){
|
|
|
|
|
loggingFormat.levelNames[(int)level] = newFormat;
|
|
|
|
|
}
|
|
|
|
|
void setLogOutputFormat(const std::string& newFormat){
|
|
|
|
|
loggingFormat.logOutputFormat = newFormat;
|
|
|
|
|
}
|
|
|
|
|
void setLogToFile(bool shouldLogToFile){
|
|
|
|
|
loggingFormat.logToFile = shouldLogToFile;
|
|
|
|
|
}
|
|
|
|
|
void setLogToConsole(bool shouldLogToConsole){
|
|
|
|
|
loggingFormat.logToConsole = shouldLogToConsole;
|
|
|
|
|
}
|
|
|
|
|
void setLogPath(const std::string& path){
|
|
|
|
|
loggingFormat.logFilePath = path;
|
|
|
|
|
}
|
|
|
|
|
void setLogFileName(const std::string& fileName){
|
|
|
|
|
loggingFormat.logFileName = fileName;
|
|
|
|
|
}
|
|
|
|
|
void setMaxFileSize(size_t fileSize) {
|
|
|
|
|
loggingFormat.logMaxFileSize = fileSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void flush() {
|
|
|
|
|
std::cerr.flush();
|
|
|
|
|
std::cout.flush();
|
|
|
|
@ -390,6 +625,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_FATAL(format, ...)
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_LOG(format, level, ...) log(format, level, __FILE__, __LINE__, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_LOG_STREAM(level) blt::logging::logger{level, __FILE__, __LINE__}
|
|
|
|
|
#ifndef BLT_ENABLE_TRACE
|
|
|
|
|
#define BLT_TRACE(format, ...)
|
|
|
|
|
#define BLT_TRACE0_STREAM blt::logging::empty_logger{}
|
|
|
|
@ -399,11 +635,11 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_TRACE_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_TRACE(format, ...) BLT_LOG(format, blt::logging::log_level::TRACE, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_TRACE0_STREAM blt::logging::logger{blt::logging::log_level::TRACE0, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_TRACE1_STREAM blt::logging::logger{blt::logging::log_level::TRACE1, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_TRACE2_STREAM blt::logging::logger{blt::logging::log_level::TRACE2, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_TRACE3_STREAM blt::logging::logger{blt::logging::log_level::TRACE3, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_TRACE_STREAM blt::logging::logger{blt::logging::log_level::TRACE, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_TRACE0_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE0)
|
|
|
|
|
#define BLT_TRACE1_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE1)
|
|
|
|
|
#define BLT_TRACE2_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE2)
|
|
|
|
|
#define BLT_TRACE3_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE3)
|
|
|
|
|
#define BLT_TRACE_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef BLT_ENABLE_DEBUG
|
|
|
|
@ -411,7 +647,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_DEBUG_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_DEBUG(format, ...) BLT_LOG(format, blt::logging::log_level::DEBUG, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_DEBUG_STREAM blt::logging::logger{blt::logging::log_level::DEBUG, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_DEBUG_STREAM BLT_LOG_STREAM(blt::logging::log_level::DEBUG)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef BLT_ENABLE_INFO
|
|
|
|
@ -419,7 +655,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_INFO_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_INFO(format, ...) BLT_LOG(format, blt::logging::log_level::INFO, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_INFO_STREAM blt::logging::logger{blt::logging::log_level::INFO, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_INFO_STREAM BLT_LOG_STREAM(blt::logging::log_level::INFO)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef BLT_ENABLE_WARN
|
|
|
|
@ -427,7 +663,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_WARN_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_WARN(format, ...) BLT_LOG(format, blt::logging::log_level::WARN, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_WARN_STREAM blt::logging::logger{blt::logging::log_level::WARN, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_WARN_STREAM BLT_LOG_STREAM(blt::logging::log_level::WARN)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef BLT_ENABLE_ERROR
|
|
|
|
@ -435,7 +671,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_ERROR_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_ERROR(format, ...) BLT_LOG(format, blt::logging::log_level::ERROR, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_ERROR_STREAM blt::logging::logger{blt::logging::log_level::ERROR, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_ERROR_STREAM BLT_LOG_STREAM(blt::logging::log_level::ERROR)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef BLT_ENABLE_FATAL
|
|
|
|
@ -443,7 +679,7 @@ namespace blt::logging {
|
|
|
|
|
#define BLT_FATAL_STREAM blt::logging::empty_logger{}
|
|
|
|
|
#else
|
|
|
|
|
#define BLT_FATAL(format, ...) BLT_LOG(format, blt::logging::log_level::FATAL, ##__VA_ARGS__)
|
|
|
|
|
#define BLT_FATAL_STREAM blt::logging::logger{blt::logging::log_level::FATAL, __FILE__, __LINE__}
|
|
|
|
|
#define BLT_FATAL_STREAM BLT_LOG_STREAM(blt::logging::log_level::FATAL)
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|