From 3a875507d34c7bad3f550cd31f98ce17b1132838 Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Thu, 15 Aug 2019 12:02:49 +0200 Subject: [PATCH] Remove Log() function, do work in constructor --- logger/Logger.cxx | 321 +++++++++++++++++++++----------------------- logger/Logger.h | 45 +++---- test/loggerTest.cxx | 48 +++---- 3 files changed, 196 insertions(+), 218 deletions(-) diff --git a/logger/Logger.cxx b/logger/Logger.cxx index 8cc1aa1..8b37e6a 100644 --- a/logger/Logger.cxx +++ b/logger/Logger.cxx @@ -171,23 +171,17 @@ const array Logger::fVerbosityNames = } }; -std::map Logger::fVerbosities = +map 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) } + { 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) @@ -214,6 +208,146 @@ Logger::Logger(Severity severity, const string& file, const string& line, const fMetaData.func = func; fMetaData.severity_name = fSeverityNames.at(static_cast(severity)); fMetaData.severity = severity; + + char tsstr[32]; + { + lock_guard lock(fMtx); // localtime is not threadsafe, guard it + if (!strftime(tsstr, sizeof(tsstr), "%H:%M:%S", localtime(&(fMetaData.timestamp)))) { + tsstr[0] = 'u'; + } + } + + auto spec = fVerbosities[fVerbosity]; + + if ((!fColored && LoggingToConsole()) || LoggingToFile()) { + bool appendSpace = false; + for (const auto info : spec.fOrder) { + switch (info) { + case VerbositySpec::Info::process_name: + fBWOut << "[" << fMetaData.process_name << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::timestamp_us: + fBWOut << "[" << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::timestamp_s: + fBWOut << "[" << tsstr << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::severity: + fBWOut << "[" << fMetaData.severity_name << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file_line_function: + fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << ":" << fMetaData.func << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file_line: + fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file: + fBWOut << "[" << fMetaData.file << "]"; + appendSpace = true; + break; + default: + break; + } + } + + if (appendSpace) { + fBWOut << " "; + } + } + + if (fColored && LoggingToConsole()) { + bool appendSpace = false; + for (const auto info : spec.fOrder) { + switch (info) { + case VerbositySpec::Info::process_name: + fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.process_name) << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::timestamp_us: + fColorOut << "[" << startColor(Color::fgCyan) << tsstr << "." + << setw(6) << setfill('0') << fMetaData.us.count() << endColor() << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::timestamp_s: + fColorOut << "[" << startColor(Color::fgCyan) << tsstr << endColor() << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::severity: + fColorOut << "[" << ColoredSeverityWriter(fMetaData.severity) << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file_line_function: + fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":" + << ColorOut(Color::fgYellow, fMetaData.line) << ":" + << ColorOut(Color::fgBlue, fMetaData.func) << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file_line: + fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":" + << ColorOut(Color::fgYellow, fMetaData.line) << "]"; + appendSpace = true; + break; + case VerbositySpec::Info::file: + fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << "]"; + appendSpace = true; + break; + default: + break; + } + } + + if (appendSpace) { + fColorOut << " "; + } + } + + } +} + +Logger::~Logger() noexcept(false) +{ + if (fIsDestructed) { + printf("post-static destruction output: %s\n", fContent.str().c_str()); + return; + } + + for (auto& it : fCustomSinks) { + if (LoggingCustom(it.second.first)) { + lock_guard lock(fMtx); + it.second.second(fContent.str(), fMetaData); + } + } + + fContent << "\n"; // "\n" + flush instead of endl makes output thread safe. + + fBWOut << fContent.str(); + + if (LoggingToConsole()) { + if (fColored) { + fColorOut << fContent.str(); + cout << fColorOut.str() << flush; + } else { + cout << fBWOut.str() << flush; + } + } + + if (LoggingToFile()) { + lock_guard lock(fMtx); + if (fFileStream.is_open()) { + fFileStream << fBWOut.str() << flush; + } + } + + if (fMetaData.severity == Severity::fatal) { + if (fFatalCallback) { + fFatalCallback(); + } } } @@ -369,7 +503,7 @@ bool Logger::Logging(Severity severity) } } -bool Logger::Logging(const std::string& severityStr) +bool Logger::Logging(const string& severityStr) { if (fSeverityMap.count(severityStr)) { return Logging(fSeverityMap.at(severityStr)); @@ -404,7 +538,7 @@ void Logger::DefineVerbosity(const Verbosity verbosity, const VerbositySpec spec fVerbosities[verbosity] = spec; } -void Logger::DefineVerbosity(const std::string& verbosityStr, const VerbositySpec spec) +void Logger::DefineVerbosity(const string& verbosityStr, const VerbositySpec spec) { if (fVerbosityMap.count(verbosityStr)) { DefineVerbosity(fVerbosityMap.at(verbosityStr), spec); @@ -433,8 +567,7 @@ void Logger::InitFileSink(const Severity severity, const string& filename, bool stringstream ss; ss << "_"; char tsstr[32]; - if (strftime(tsstr, sizeof(tsstr), "%Y-%m-%d_%H_%M_%S", localtime(&now))) - { + if (strftime(tsstr, sizeof(tsstr), "%Y-%m-%d_%H_%M_%S", localtime(&now))) { ss << tsstr; } ss << ".log"; @@ -527,113 +660,6 @@ void Logger::RemoveCustomSink(const string& key) } } -Logger& Logger::Log() -{ - if (fIsDestructed) { - return *this; - } - - char tsstr[32]; - { - lock_guard lock(fMtx); // localtime is not threadsafe, guard it - if (!strftime(tsstr, sizeof(tsstr), "%H:%M:%S", localtime(&(fMetaData.timestamp)))) { - tsstr[0] = 'u'; - } - } - - auto spec = fVerbosities[fVerbosity]; - - if ((!fColored && LoggingToConsole()) || LoggingToFile()) { - bool appendSpace = false; - for (const auto info : spec.fOrder) { - switch (info) { - case VerbositySpec::Info::process_name: - fBWOut << "[" << fMetaData.process_name << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::timestamp_us: - fBWOut << "[" << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::timestamp_s: - fBWOut << "[" << tsstr << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::severity: - fBWOut << "[" << fMetaData.severity_name << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file_line_function: - fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << ":" << fMetaData.func << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file_line: - fBWOut << "[" << fMetaData.file << ":" << fMetaData.line << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file: - fBWOut << "[" << fMetaData.file << "]"; - appendSpace = true; - break; - default: - break; - } - } - - if (appendSpace) { - fBWOut << " "; - } - } - - if (fColored && LoggingToConsole()) { - bool appendSpace = false; - for (const auto info : spec.fOrder) { - switch (info) { - case VerbositySpec::Info::process_name: - fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.process_name) << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::timestamp_us: - fColorOut << "[" << startColor(Color::fgCyan) << tsstr << "." - << setw(6) << setfill('0') << fMetaData.us.count() << endColor() << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::timestamp_s: - fColorOut << "[" << startColor(Color::fgCyan) << tsstr << endColor() << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::severity: - fColorOut << "[" << ColoredSeverityWriter(fMetaData.severity) << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file_line_function: - fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":" - << ColorOut(Color::fgYellow, fMetaData.line) << ":" - << ColorOut(Color::fgBlue, fMetaData.func) << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file_line: - fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << ":" - << ColorOut(Color::fgYellow, fMetaData.line) << "]"; - appendSpace = true; - break; - case VerbositySpec::Info::file: - fColorOut << "[" << ColorOut(Color::fgBlue, fMetaData.file) << "]"; - appendSpace = true; - break; - default: - break; - } - } - - if (appendSpace) { - fColorOut << " "; - } - } - - return *this; -} - Logger& Logger::operator<<(ios_base& (*manip) (ios_base&)) { fContent << manip; @@ -646,45 +672,4 @@ Logger& Logger::operator<<(ostream& (*manip) (ostream&)) return *this; } -Logger::~Logger() noexcept(false) -{ - if (fIsDestructed) { - printf("post-static destruction output: %s\n", fContent.str().c_str()); - return; - } - - for (auto& it : fCustomSinks) { - if (LoggingCustom(it.second.first)) { - lock_guard lock(fMtx); - it.second.second(fContent.str(), fMetaData); - } - } - - fContent << "\n"; // "\n" + flush instead of endl makes output thread safe. - - fBWOut << fContent.str(); - - if (LoggingToConsole()) { - if (fColored) { - fColorOut << fContent.str(); - cout << fColorOut.str() << flush; - } else { - cout << fBWOut.str() << flush; - } - } - - if (LoggingToFile()) { - lock_guard lock(fMtx); - if (fFileStream.is_open()) { - fFileStream << fBWOut.str() << flush; - } - } - - if (fMetaData.severity == Severity::fatal) { - if (fFatalCallback) { - fFatalCallback(); - } - } -} - } // namespace fair diff --git a/logger/Logger.h b/logger/Logger.h index 2758740..ea4fcab 100644 --- a/logger/Logger.h +++ b/logger/Logger.h @@ -13,20 +13,22 @@ #warning "The symbol 'DEBUG' is used in FairRoot Logger. undefining..." #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include // pair -#include // time_t -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // time_t +#include +#include +#include // pair +#include #ifdef FAIRLOGGER_USE_BOOST_PRETTY_FUNCTION #include @@ -114,8 +116,7 @@ struct VerbositySpec template static VerbositySpec Make(Ts ... options) { - static_assert(sizeof...(Ts) < static_cast(Info::__max__), - "Maximum number of VerbositySpec::Info parameters exceeded."); + static_assert(sizeof...(Ts) < static_cast(Info::__max__), "Maximum number of VerbositySpec::Info parameters exceeded."); return Make(VerbositySpec(), 0, options...); } @@ -124,8 +125,7 @@ struct VerbositySpec template static VerbositySpec Make(VerbositySpec spec, int i, T option, Ts ... options) { - static_assert(std::is_same::value, - "Only arguments of type VerbositySpec::Info are allowed."); + static_assert(std::is_same::value, "Only arguments of type VerbositySpec::Info are allowed."); assert(option > Info::__empty__); assert(option < Info::__max__); @@ -181,6 +181,7 @@ class Logger { public: Logger(Severity severity, const std::string& file, const std::string& line, const std::string& func); + virtual ~Logger() noexcept(false); enum class Color : int { @@ -298,8 +299,6 @@ class Logger static void AddCustomSink(const std::string& key, const std::string& severityStr, std::function sink); static void RemoveCustomSink(const std::string& key); - Logger& Log(); - template Logger& operator<<(const T& t) { @@ -333,8 +332,6 @@ class Logger static const std::array fSeverityNames; static const std::array fVerbosityNames; - virtual ~Logger() noexcept(false); - // protection for use after static destruction took place static bool fIsDestructed; static struct DestructionHelper { ~DestructionHelper() { Logger::fIsDestructed = true; }} fDestructionHelper; @@ -376,17 +373,17 @@ class Logger #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__), static_cast(BOOST_CURRENT_FUNCTION)).Log() + fair::Logger(fair::Severity::severity, __FILE__, CONVERTTOSTRING(__LINE__), static_cast(BOOST_CURRENT_FUNCTION)) #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__), static_cast(__FUNCTION__)).Log() + fair::Logger(fair::Severity::severity, __FILE__, CONVERTTOSTRING(__LINE__), static_cast(__FUNCTION__)) #endif // with custom file, line, function #define LOGD(severity, file, line, function) \ for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \ - fair::Logger(severity, file, line, function).Log() + fair::Logger(severity, file, line, function) #define LOG_IF(severity, condition) \ for (bool fairLOggerunLikelyvariable2 = false; condition && !fairLOggerunLikelyvariable2; fairLOggerunLikelyvariable2 = true) \ diff --git a/test/loggerTest.cxx b/test/loggerTest.cxx index f53c3c5..3851eec 100644 --- a/test/loggerTest.cxx +++ b/test/loggerTest.cxx @@ -18,9 +18,6 @@ using namespace std; using namespace fair; -namespace test -{ - void printEverySeverity() { static int i = 1; @@ -38,39 +35,37 @@ void printEverySeverity() LOG(trace) << "trace message " << i++; } -} - void printAllVerbositiesWithSeverity(Severity sev) { Logger::SetConsoleSeverity(sev); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'verylow' verbosity..." << endl; Logger::SetVerbosity(Verbosity::verylow); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'low' verbosity..." << endl; Logger::SetVerbosity(Verbosity::low); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'medium' verbosity..." << endl; Logger::SetVerbosity(Verbosity::medium); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'high' verbosity..." << endl; Logger::SetVerbosity(Verbosity::high); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'veryhigh' verbosity..." << endl; Logger::SetVerbosity(Verbosity::veryhigh); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user1' verbosity..." << endl; Logger::SetVerbosity(Verbosity::user1); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user2' verbosity..." << endl; Logger::SetVerbosity(Verbosity::user2); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user3' verbosity..." << endl; Logger::SetVerbosity(Verbosity::user3); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user4' verbosity..." << endl; Logger::SetVerbosity(Verbosity::user4); - test::printEverySeverity(); + printEverySeverity(); } void silentlyPrintAllVerbositiesWithSeverity(Severity sev) @@ -78,23 +73,23 @@ void silentlyPrintAllVerbositiesWithSeverity(Severity sev) Logger::SetConsoleSeverity(sev); Logger::SetVerbosity(Verbosity::verylow); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::low); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::medium); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::high); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::veryhigh); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::user1); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::user2); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::user3); - test::printEverySeverity(); + printEverySeverity(); Logger::SetVerbosity(Verbosity::user4); - test::printEverySeverity(); + printEverySeverity(); } int main() @@ -102,7 +97,8 @@ int main() Logger::SetConsoleColor(true); auto spec = VerbositySpec::Make(VerbositySpec::Info::file_line_function, - VerbositySpec::Info::process_name,VerbositySpec::Info::process_name); + VerbositySpec::Info::process_name, + VerbositySpec::Info::process_name); cout << "Defining custom verbosity \"user2\"" << endl; Logger::DefineVerbosity(Verbosity::user2, spec); @@ -163,7 +159,7 @@ int main() cout << "cout: ----------------------------" << endl; cout << "cout: open log file with severity 'error'" << endl; Logger::InitFileSink(Severity::error, "test_log", true); - test::printEverySeverity(); + printEverySeverity(); cout << "cout: closing log file" << endl; Logger::RemoveFileSink(); @@ -188,7 +184,7 @@ int main() cout << "CustomSink: \tfair::Severity severity: " << static_cast(metadata.severity) << endl; }); - test::printEverySeverity(); + printEverySeverity(); cout << endl << "cout: removing custom sink with info severity" << endl;