mirror of
https://github.com/FairRootGroup/FairLogger.git
synced 2025-10-15 09:31:44 +00:00
Support user-defined verbosity formats
* Add `fair::Logger::DefineVerbosity(...)` API * Add documentation to README * Optionally support `BOOST_PRETTY_FUNCTION`
This commit is contained in:
committed by
Alexey Rybalchenko
parent
7d0411b939
commit
3e1de0a17b
@@ -143,16 +143,20 @@ const string Logger::fProcessName = "?";
|
||||
|
||||
const unordered_map<string, Verbosity> Logger::fVerbosityMap =
|
||||
{
|
||||
{ "veryhigh", Verbosity::veryhigh },
|
||||
{ "high", Verbosity::high },
|
||||
{ "medium", Verbosity::medium },
|
||||
{ "low", Verbosity::low },
|
||||
{ "verylow", Verbosity::verylow },
|
||||
{ "VERYHIGH", Verbosity::veryhigh },
|
||||
{ "HIGH", Verbosity::high },
|
||||
{ "MEDIUM", Verbosity::medium },
|
||||
{ "LOW", Verbosity::low },
|
||||
{ "VERYLOW", Verbosity::verylow }
|
||||
{ "veryhigh", Verbosity::veryhigh },
|
||||
{ "high", Verbosity::high },
|
||||
{ "medium", Verbosity::medium },
|
||||
{ "low", Verbosity::low },
|
||||
{ "verylow", Verbosity::verylow },
|
||||
{ "VERYHIGH", Verbosity::veryhigh },
|
||||
{ "HIGH", Verbosity::high },
|
||||
{ "MEDIUM", Verbosity::medium },
|
||||
{ "LOW", Verbosity::low },
|
||||
{ "VERYLOW", Verbosity::verylow },
|
||||
{ "user1", Verbosity::user1 },
|
||||
{ "user2", Verbosity::user2 },
|
||||
{ "user3", Verbosity::user3 },
|
||||
{ "user4", Verbosity::user4 }
|
||||
};
|
||||
|
||||
const unordered_map<string, Severity> Logger::fSeverityMap =
|
||||
@@ -212,6 +216,34 @@ const array<string, 5> Logger::fVerbosityNames =
|
||||
}
|
||||
};
|
||||
|
||||
std::map<Verbosity, VerbositySpec> Logger::fVerbosities =
|
||||
{
|
||||
{ Verbosity::verylow, VerbositySpec::Make()
|
||||
},
|
||||
{ Verbosity::low, VerbositySpec::Make(VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::medium, VerbositySpec::Make(VerbositySpec::Info::timestamp_s,
|
||||
VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::high, VerbositySpec::Make(VerbositySpec::Info::process_name,
|
||||
VerbositySpec::Info::timestamp_s,
|
||||
VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::veryhigh, VerbositySpec::Make(VerbositySpec::Info::process_name,
|
||||
VerbositySpec::Info::timestamp_s,
|
||||
VerbositySpec::Info::severity,
|
||||
VerbositySpec::Info::file_line_function)
|
||||
},
|
||||
{ Verbosity::user1, VerbositySpec::Make(VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::user2, VerbositySpec::Make(VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::user3, VerbositySpec::Make(VerbositySpec::Info::severity)
|
||||
},
|
||||
{ Verbosity::user4, VerbositySpec::Make(VerbositySpec::Info::severity)
|
||||
}
|
||||
};
|
||||
|
||||
string Logger::SeverityName(Severity severity)
|
||||
{
|
||||
return fSeverityNames.at(static_cast<size_t>(severity));
|
||||
@@ -440,6 +472,23 @@ Verbosity Logger::GetVerbosity()
|
||||
return fVerbosity;
|
||||
}
|
||||
|
||||
void Logger::DefineVerbosity(const Verbosity verbosity, const VerbositySpec spec)
|
||||
{
|
||||
fVerbosities[verbosity] = spec;
|
||||
}
|
||||
|
||||
void Logger::DefineVerbosity(const std::string& verbosityStr, const VerbositySpec spec)
|
||||
{
|
||||
if (fVerbosityMap.count(verbosityStr))
|
||||
{
|
||||
DefineVerbosity(fVerbosityMap.at(verbosityStr), spec);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "Unknown verbosity: '" << verbosityStr;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetConsoleColor(const bool colored)
|
||||
{
|
||||
fColored = colored;
|
||||
@@ -583,57 +632,99 @@ Logger& Logger::Log()
|
||||
}
|
||||
}
|
||||
|
||||
auto spec = fVerbosities[fVerbosity];
|
||||
|
||||
if ((!fColored && LoggingToConsole()) || LoggingToFile())
|
||||
{
|
||||
if (fVerbosity >= Verbosity::high)
|
||||
bool append_space = false;
|
||||
for (const auto info : spec.fOrder)
|
||||
{
|
||||
fBWOut << "[" << fMetaData.process_name << "]"
|
||||
<< "[" << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << "]";
|
||||
}
|
||||
else if (fVerbosity == Verbosity::medium)
|
||||
{
|
||||
fBWOut << "[" << tsstr << "]";
|
||||
switch (info)
|
||||
{
|
||||
case VerbositySpec::Info::process_name:
|
||||
fBWOut << "[" << fMetaData.process_name << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::timestamp_us:
|
||||
fBWOut << "[" << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::timestamp_s:
|
||||
fBWOut << "[" << tsstr << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::severity:
|
||||
fBWOut << "[" << fMetaData.severity_name << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file_line_function:
|
||||
fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << ":" << fMetaData.func << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file_line:
|
||||
fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file:
|
||||
fBWOut << "[" << fMetaData.file << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fVerbosity > Verbosity::verylow)
|
||||
{
|
||||
fBWOut << "[" << fMetaData.severity_name << "]";
|
||||
}
|
||||
|
||||
if (fVerbosity == Verbosity::veryhigh)
|
||||
{
|
||||
fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << ":" << fMetaData.func << "]";
|
||||
}
|
||||
|
||||
if (fVerbosity != Verbosity::verylow)
|
||||
if (append_space)
|
||||
{
|
||||
fBWOut << " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (fColored && (LoggingToConsole()))
|
||||
if (fColored && LoggingToConsole())
|
||||
{
|
||||
if (fVerbosity >= Verbosity::high)
|
||||
bool append_space = false;
|
||||
for (const auto info : spec.fOrder)
|
||||
{
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.process_name) << "]"
|
||||
<< "[" << startColor(Color::fgCyan) << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << endColor() << "]";
|
||||
}
|
||||
else if (fVerbosity == Verbosity::medium)
|
||||
{
|
||||
fColorOut << "[" << startColor(Color::fgCyan) << tsstr << endColor() << "]";
|
||||
switch (info)
|
||||
{
|
||||
case VerbositySpec::Info::process_name:
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.process_name) << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::timestamp_us:
|
||||
fColorOut << "[" << startColor(Color::fgCyan) << tsstr << "."
|
||||
<< setw(6) << setfill('0') << fMetaData.us.count() << endColor() << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::timestamp_s:
|
||||
fColorOut << "[" << startColor(Color::fgCyan) << tsstr << endColor() << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::severity:
|
||||
fColorOut << "[" << ColoredSeverityWriter(fMetaData.severity) << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file_line_function:
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":"
|
||||
<< ColorOut(Color::fgYellow, fMetaData.line) << ":"
|
||||
<< ColorOut(Color::fgBlue, fMetaData.func) << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file_line:
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":"
|
||||
<< ColorOut(Color::fgYellow, fMetaData.line) << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
case VerbositySpec::Info::file:
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << "]";
|
||||
append_space = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fVerbosity > Verbosity::verylow)
|
||||
{
|
||||
fColorOut << "[" << ColoredSeverityWriter(fMetaData.severity) << "]";
|
||||
}
|
||||
|
||||
if (fVerbosity == Verbosity::veryhigh)
|
||||
{
|
||||
fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":" << ColorOut(Color::fgYellow, fMetaData.line) << ":" << ColorOut(Color::fgBlue, fMetaData.func) << "]";
|
||||
}
|
||||
|
||||
if (fVerbosity != Verbosity::verylow)
|
||||
if (append_space)
|
||||
{
|
||||
fColorOut << " ";
|
||||
}
|
||||
|
@@ -18,11 +18,19 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <utility> // pair
|
||||
#include <time.h> // time_t
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef FAIRLOGGER_USE_BOOST_PRETTY_FUNCTION
|
||||
#include <boost/current_function.hpp>
|
||||
#endif
|
||||
|
||||
namespace fair
|
||||
{
|
||||
@@ -76,7 +84,64 @@ enum class Verbosity : int
|
||||
LOW = low,
|
||||
MEDIUM = medium,
|
||||
HIGH = high,
|
||||
VERYHIGH = veryhigh
|
||||
VERYHIGH = veryhigh,
|
||||
// extra slots for user-defined verbosities:
|
||||
user1,
|
||||
user2,
|
||||
user3,
|
||||
user4,
|
||||
};
|
||||
|
||||
struct VerbositySpec
|
||||
{
|
||||
enum class Info : int
|
||||
{
|
||||
__empty__ = 0, // used to initialize order array
|
||||
process_name, // [process name]
|
||||
timestamp_s, // [HH:MM:SS]
|
||||
timestamp_us, // [HH:MM:SS:µS]
|
||||
severity, // [severity]
|
||||
file, // [file]
|
||||
file_line, // [file:line]
|
||||
file_line_function, // [file:line:function]
|
||||
__max__ // needs to be last in enum
|
||||
};
|
||||
|
||||
std::array<Info, static_cast<int>(Info::__max__)> fOrder;
|
||||
|
||||
VerbositySpec() : fOrder({Info::__empty__}) {}
|
||||
|
||||
template<typename ... Ts>
|
||||
static VerbositySpec Make(Ts ... options)
|
||||
{
|
||||
static_assert(sizeof...(Ts) < static_cast<int>(Info::__max__),
|
||||
"Maximum number of VerbositySpec::Info parameters exceeded.");
|
||||
|
||||
return Make(VerbositySpec(), 0, options...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T, typename ... Ts>
|
||||
static VerbositySpec Make(VerbositySpec spec, int i, T option, Ts ... options)
|
||||
{
|
||||
static_assert(std::is_same<T, Info>::value,
|
||||
"Only arguments of type VerbositySpec::Info are allowed.");
|
||||
|
||||
assert(option > Info::__empty__);
|
||||
assert(option < Info::__max__);
|
||||
|
||||
if (std::find(spec.fOrder.begin(), spec.fOrder.end(), option) == spec.fOrder.end()) {
|
||||
spec.fOrder[i] = option;
|
||||
++i;
|
||||
}
|
||||
|
||||
return Make(spec, i, options ...);
|
||||
}
|
||||
|
||||
static VerbositySpec Make(VerbositySpec spec, int)
|
||||
{
|
||||
return spec;
|
||||
}
|
||||
};
|
||||
|
||||
// non-std exception to avoid undesirable catches - fatal should exit in a way we want.
|
||||
@@ -138,6 +203,8 @@ class Logger
|
||||
static void SetVerbosity(const Verbosity verbosity);
|
||||
static void SetVerbosity(const std::string& verbosityStr);
|
||||
static Verbosity GetVerbosity();
|
||||
static void DefineVerbosity(const Verbosity, VerbositySpec);
|
||||
static void DefineVerbosity(const std::string& verbosityStr, VerbositySpec);
|
||||
|
||||
static void SetConsoleColor(const bool colored = true);
|
||||
|
||||
@@ -217,6 +284,8 @@ class Logger
|
||||
bool LoggingCustom(const Severity) const;
|
||||
|
||||
static void UpdateMinSeverity();
|
||||
|
||||
static std::map<Verbosity, VerbositySpec> fVerbosities;
|
||||
};
|
||||
|
||||
} // namespace fair
|
||||
@@ -224,9 +293,15 @@ class Logger
|
||||
#define IMP_CONVERTTOSTRING(s) # s
|
||||
#define CONVERTTOSTRING(s) IMP_CONVERTTOSTRING(s)
|
||||
|
||||
#ifdef FAIRLOGGER_USE_BOOST_PRETTY_FUNCTION
|
||||
#define LOG(severity) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(fair::Severity::severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(fair::Severity::severity, __FILE__, CONVERTTOSTRING(__LINE__), BOOST_CURRENT_FUNCTION).Log()
|
||||
#else
|
||||
#define LOG(severity) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(fair::Severity::severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(fair::Severity::severity, __FILE__, CONVERTTOSTRING(__LINE__), __FUNCTION__).Log()
|
||||
#endif
|
||||
|
||||
// with custom file, line, function
|
||||
#define LOGD(severity, file, line, function) \
|
||||
|
Reference in New Issue
Block a user