From 5d9b74f511147999c2dc26b1305a9831ee550f1e Mon Sep 17 00:00:00 2001 From: Christopher Dilks Date: Mon, 12 Aug 2024 13:24:35 -0400 Subject: [PATCH] feat: logger macros --- src/iguana/algorithms/Algorithm.cc | 58 ++++---- src/iguana/algorithms/Algorithm.h | 12 +- src/iguana/algorithms/AlgorithmSequence.cc | 9 +- src/iguana/algorithms/AlgorithmSequence.h | 3 +- .../clas12/EventBuilderFilter/Algorithm.cc | 13 +- .../clas12/FiducialFilter/Algorithm.cc | 5 +- .../clas12/FiducialFilter/Validator.cc | 3 +- .../clas12/LorentzTransformer/Algorithm.cc | 19 +-- .../clas12/MomentumCorrection/Validator.cc | 3 +- .../clas12/PhotonGBTFilter/Algorithm.cc | 3 +- .../clas12/PhotonGBTFilter/Validator.cc | 3 +- .../clas12/SectorFinder/Algorithm.cc | 3 +- .../clas12/SectorFinder/Validator.cc | 7 +- .../clas12/ZVertexFilter/Algorithm.cc | 7 +- .../clas12/ZVertexFilter/Validator.cc | 3 +- .../example/ExampleAlgorithm/Algorithm.cc | 3 +- .../physics/InclusiveKinematics/Algorithm.cc | 31 +++-- .../physics/InclusiveKinematics/Validator.cc | 9 +- src/iguana/services/ConfigFileReader.cc | 24 ++-- src/iguana/services/Logger.cc | 63 ++------- src/iguana/services/Logger.h | 131 ++++-------------- src/iguana/services/LoggerMacros.h | 94 +++++++++++++ src/iguana/services/NewLogger.h | 15 -- src/iguana/services/Object.cc | 32 +++-- src/iguana/services/Object.h | 62 ++------- src/iguana/services/YAMLReader.cc | 29 ++-- 26 files changed, 294 insertions(+), 350 deletions(-) create mode 100644 src/iguana/services/LoggerMacros.h delete mode 100644 src/iguana/services/NewLogger.h diff --git a/src/iguana/algorithms/Algorithm.cc b/src/iguana/algorithms/Algorithm.cc index 900e03eb..d4482269 100644 --- a/src/iguana/algorithms/Algorithm.cc +++ b/src/iguana/algorithms/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" #include @@ -22,12 +23,12 @@ namespace iguana { auto val = opt ? opt.value() : m_yaml_config->GetScalar(node_path); if(key != "") { m_option_cache[key] = val; - m_log->Debug("CACHED OPTION: {:>20} = {}", key, PrintOptionValue(key)); + DEBUG("CACHED OPTION: {:>20} = {}", key, PrintOptionValue(key)); } return val; } catch(std::runtime_error const& ex) { - m_log->Error("Failed to `GetOptionScalar` for key '{}'", key); + ERROR("Failed to `GetOptionScalar` for key '{}'", key); throw std::runtime_error("config file parsing issue"); } } @@ -46,12 +47,12 @@ namespace iguana { auto val = opt ? opt.value() : m_yaml_config->GetVector(node_path); if(key != "") { m_option_cache[key] = val; - m_log->Debug("CACHED OPTION: {:>20} = {}", key, PrintOptionValue(key)); + DEBUG("CACHED OPTION: {:>20} = {}", key, PrintOptionValue(key)); } return val; } catch(std::runtime_error const& ex) { - m_log->Error("Failed to `GetOptionVector` for key '{}'", key); + ERROR("Failed to `GetOptionVector` for key '{}'", key); throw std::runtime_error("config file parsing issue"); } } @@ -117,15 +118,15 @@ namespace iguana { if(!m_yaml_config) { o_user_config_file = GetCachedOption("config_file").value_or(""); o_user_config_dir = GetCachedOption("config_dir").value_or(""); - m_log->Debug("Instantiating `YAMLReader`"); + DEBUG("Instantiating `YAMLReader`"); m_yaml_config = std::make_unique("config|" + m_name); - m_yaml_config->SetLogLevel(m_log->GetLevel()); + m_yaml_config->SetLogLevel(GetLogLevel()); m_yaml_config->AddDirectory(o_user_config_dir); m_yaml_config->AddFile(m_default_config_file); m_yaml_config->AddFile(o_user_config_file); } else - m_log->Debug("`YAMLReader` already instantiated for this algorithm; using that"); + DEBUG("`YAMLReader` already instantiated for this algorithm; using that"); m_yaml_config->LoadFiles(); } @@ -141,14 +142,14 @@ namespace iguana { [&bank_name](auto& bank) { return bank.getSchema().getName() == bank_name; }); if(it == banks.end()) { - m_log->Error("required input bank '{}' not found; cannot `Start` algorithm '{}'", bank_name, m_class_name); + ERROR("required input bank '{}' not found; cannot `Start` algorithm '{}'", bank_name, m_class_name); auto creators = AlgorithmFactory::QueryNewBank(bank_name); if(creators) - m_log->Error(" -> this bank is created by algorithm(s) [{}]; please `Start` ONE of them BEFORE this algorithm", fmt::join(creators.value(), ", ")); + ERROR(" -> this bank is created by algorithm(s) [{}]; please `Start` ONE of them BEFORE this algorithm", fmt::join(creators.value(), ", ")); throw std::runtime_error("cannot cache bank index"); } auto idx = std::distance(banks.begin(), it); - m_log->Debug("cached index of bank '{}' is {}", bank_name, idx); + DEBUG("cached index of bank '{}' is {}", bank_name, idx); return idx; } @@ -175,12 +176,12 @@ namespace iguana { return fmt::format("({}) [{}]", fmt::join(valQuoted, ", "), "vector"); } else { - m_log->Error("option '{}' type has no printer defined in Algorithm::PrintOptionValue", key); + ERROR("option '{}' type has no printer defined in Algorithm::PrintOptionValue", key); return "UNKNOWN"; } } else - m_log->Error("option '{}' not found by Algorithm::PrintOptionValue", key); + ERROR("option '{}' not found by Algorithm::PrintOptionValue", key); return "UNKNOWN"; } @@ -189,21 +190,22 @@ namespace iguana { hipo::bank& Algorithm::GetBank(hipo::banklist& banks, hipo::banklist::size_type const idx, std::string const& expected_bank_name) const { if(m_rows_only) { - m_log->Error("algorithm is in 'rows only' mode; cannot call `Run` since banks are not cached; use action function(s) instead"); + ERROR("algorithm is in 'rows only' mode; cannot call `Run` since banks are not cached; use action function(s) instead"); } else { try { auto& result = banks.at(idx); - if(expected_bank_name != "" && result.getSchema().getName() != expected_bank_name) - m_log->Error("expected input bank '{}' at index={}; got bank named '{}'", expected_bank_name, idx, result.getSchema().getName()); + if(expected_bank_name != "" && result.getSchema().getName() != expected_bank_name) { + ERROR("expected input bank '{}' at index={}; got bank named '{}'", expected_bank_name, idx, result.getSchema().getName()); + } else return result; } catch(std::out_of_range const& o) { - m_log->Error("required input bank '{}' not found; cannot `Run` algorithm '{}'", expected_bank_name, m_class_name); + ERROR("required input bank '{}' not found; cannot `Run` algorithm '{}'", expected_bank_name, m_class_name); auto creators = AlgorithmFactory::QueryNewBank(expected_bank_name); if(creators) - m_log->Error(" -> this bank is created by algorithm(s) [{}]; please `Run` ONE of them BEFORE this algorithm", fmt::join(creators.value(), ", ")); + ERROR(" -> this bank is created by algorithm(s) [{}]; please `Run` ONE of them BEFORE this algorithm", fmt::join(creators.value(), ", ")); } } throw std::runtime_error("GetBank failed"); @@ -220,11 +222,11 @@ namespace iguana { int item_id) const { if(!AlgorithmFactory::QueryNewBank(bank_name)) { - m_log->Error("{:?} creates bank {:?}, which is not registered; new banks must be included in `REGISTER_IGUANA_ALGORITHM` arguments", m_class_name, bank_name); + ERROR("{:?} creates bank {:?}, which is not registered; new banks must be included in `REGISTER_IGUANA_ALGORITHM` arguments", m_class_name, bank_name); throw std::runtime_error("CreateBank failed"); } if(schema_def.empty()) { - m_log->Error("empty schema_def in CreateBank"); + ERROR("empty schema_def in CreateBank"); throw std::runtime_error("CreateBank failed"); } hipo::schema bank_schema(bank_name.c_str(), group_id, item_id); @@ -241,23 +243,11 @@ namespace iguana { /////////////////////////////////////////////////////////////////////////////// - void Algorithm::ShowBanks(hipo::banklist& banks, std::string_view message, Logger::Level const level) const - { - if(m_log->GetLevel() <= level) { - if(message != "") - m_log->Print(level, message); - for(auto& bank : banks) - bank.show(); - } - } - - /////////////////////////////////////////////////////////////////////////////// - void Algorithm::ShowBank(hipo::bank& bank, std::string_view message, Logger::Level const level) const { - if(m_log->GetLevel() <= level) { + if(GetLogLevel() <= level) { if(message != "") - m_log->Print(level, message); + PRINT_LOG(level, message); bank.show(); } } @@ -274,7 +264,7 @@ namespace iguana { return std::get(it->second); } catch(std::bad_variant_access const& ex) { - m_log->Warn("user called SetOption for option '{}' and set it to '{}', which is the wrong type; IGNORING", key, PrintOptionValue(key)); + WARN("user called SetOption for option '{}' and set it to '{}', which is the wrong type; IGNORING", key, PrintOptionValue(key)); } } return {}; diff --git a/src/iguana/algorithms/Algorithm.h b/src/iguana/algorithms/Algorithm.h index 7c198aa2..aacfb0a1 100644 --- a/src/iguana/algorithms/Algorithm.h +++ b/src/iguana/algorithms/Algorithm.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -82,13 +83,12 @@ namespace iguana { std::is_same, std::is_same, std::is_same>::value) - m_log->SetLevel(val); + SetLogLevel(val); else - m_log->Error("Option '{}' must be a string or a Logger::Level", key); + throw std::runtime_error(fmt::format("Option '{}' must be a string or a Logger::Level", key)); } else { m_option_cache[key] = val; - m_log->Debug(" USER OPTION: {:>20} = {}", key, PrintOptionValue(key)); } return val; } @@ -175,12 +175,6 @@ namespace iguana { int group_id, // FIXME: generalize group_id and item_id setting int item_id) const noexcept(false); - /// Dump all banks in a `hipo::banklist` - /// @param banks the banks to show - /// @param message if specified, print a header message - /// @param level the log level - void ShowBanks(hipo::banklist& banks, std::string_view message = "", Logger::Level const level = Logger::trace) const; - /// Dump a single bank /// @param bank the bank to show /// @param message if specified, print a header message diff --git a/src/iguana/algorithms/AlgorithmSequence.cc b/src/iguana/algorithms/AlgorithmSequence.cc index db75a9aa..21e8842d 100644 --- a/src/iguana/algorithms/AlgorithmSequence.cc +++ b/src/iguana/algorithms/AlgorithmSequence.cc @@ -1,4 +1,5 @@ #include "AlgorithmSequence.h" +#include "iguana/services/LoggerMacros.h" namespace iguana { @@ -24,7 +25,7 @@ namespace iguana { { auto algo = AlgorithmFactory::Create(class_name); if(algo == nullptr) { - m_log->Error("algorithm '{}' does not exist", class_name); + ERROR("algorithm '{}' does not exist", class_name); throw std::runtime_error("AlgorithmFactory cannot create non-existent algorithm"); } algo->SetName(instance_name == "" ? class_name : instance_name); @@ -41,7 +42,7 @@ namespace iguana { m_sequence.push_back(std::move(algo)); // check for duplicate algorithm name if(m_algo_names.size() < m_sequence.size()) { - m_log->Error("Duplicate algorithm name '{}' detected; please make sure all of your algorithms have unique names", algoName); + ERROR("Duplicate algorithm name '{}' detected; please make sure all of your algorithms have unique names", algoName); throw std::runtime_error("cannot Add algorithm"); } } @@ -62,9 +63,9 @@ namespace iguana { void AlgorithmSequence::PrintSequence(Logger::Level level) const { - m_log->Print(level, "algorithms in this sequence:"); + PRINT_LOG(level, "algorithms in this sequence:"); for(auto const& algo : m_sequence) - m_log->Print(level, " - {}", algo->GetName()); + PRINT_LOG(level, " - {}", algo->GetName()); } } diff --git a/src/iguana/algorithms/AlgorithmSequence.h b/src/iguana/algorithms/AlgorithmSequence.h index 5f620a75..dd090a14 100644 --- a/src/iguana/algorithms/AlgorithmSequence.h +++ b/src/iguana/algorithms/AlgorithmSequence.h @@ -70,8 +70,7 @@ namespace iguana { { if(auto it{m_algo_names.find(instance_name)}; it != m_algo_names.end()) return dynamic_cast(m_sequence[it->second].get()); - m_log->Error("cannot find algorithm '{}' in sequence", instance_name); - throw std::runtime_error("cannot Get algorithm"); + throw std::runtime_error(fmt::format("cannot find algorithm '{}' in sequence", instance_name)); } /// Set an algorithm option diff --git a/src/iguana/algorithms/clas12/EventBuilderFilter/Algorithm.cc b/src/iguana/algorithms/clas12/EventBuilderFilter/Algorithm.cc index 641cbecb..ffbe6481 100644 --- a/src/iguana/algorithms/clas12/EventBuilderFilter/Algorithm.cc +++ b/src/iguana/algorithms/clas12/EventBuilderFilter/Algorithm.cc @@ -1,5 +1,6 @@ #include "Algorithm.h" -#include "iguana/services/NewLogger.h" +#include "iguana/services/LoggerMacros.h" +#include "iguana/services/LoggerMacros.h" namespace iguana::clas12 { @@ -7,7 +8,7 @@ namespace iguana::clas12 { void EventBuilderFilter::Start(hipo::banklist& banks) { - m_level = LogLevel::trace; // FIXME + SetLogLevel(Logger::Level::trace); // FIXME: remove this after testing // define options, their default values, and cache them ParseYAMLConfig(); @@ -31,7 +32,7 @@ namespace iguana::clas12 { particleBank.getMutableRowList().filter([this](auto bank, auto row) { auto pid = bank.getInt("pid", row); auto accept = Filter(pid); - m_log->Debug("input PID {} -- accept = {}", pid, accept); + DEBUG("input PID {} -- accept = {}", pid, accept); return accept ? 1 : 0; }); @@ -55,7 +56,11 @@ namespace iguana::clas12 { void EventBuilderFilter::Stop() { - WARN("test newlog {}", 7); + TRACE("test TRACE {}", 7); + DEBUG("test DEBUG {}", 7); + INFO("test INFO {}", 7); + WARN("test WARN {}", 7); + ERROR("test ERROR {}", 7); } } diff --git a/src/iguana/algorithms/clas12/FiducialFilter/Algorithm.cc b/src/iguana/algorithms/clas12/FiducialFilter/Algorithm.cc index a4ff7ec2..37ff9d26 100644 --- a/src/iguana/algorithms/clas12/FiducialFilter/Algorithm.cc +++ b/src/iguana/algorithms/clas12/FiducialFilter/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" #include "Pass1CutData.h" namespace iguana::clas12 { @@ -16,7 +17,7 @@ namespace iguana::clas12 { o_pass = GetCachedOption("pass").value_or(1); if(o_pass!=1){ - m_log->Warn("FiducialFilter only contains fiducial cuts for pass1...we will default to using those..."); + WARN("FiducialFilter only contains fiducial cuts for pass1...we will default to using those...") } } @@ -55,7 +56,7 @@ void FiducialFilter::Run(hipo::banklist& banks) const { { if(torus!=1&&torus!=-1){ - m_log->Warn("torus={}...value must be either -1 or 1, otherwise fiducial cuts are not defined...filtering out all particles...",torus); + WARN("torus={}...value must be either -1 or 1, otherwise fiducial cuts are not defined...filtering out all particles...",torus); return false; } diff --git a/src/iguana/algorithms/clas12/FiducialFilter/Validator.cc b/src/iguana/algorithms/clas12/FiducialFilter/Validator.cc index 8f93c89c..e36451a0 100644 --- a/src/iguana/algorithms/clas12/FiducialFilter/Validator.cc +++ b/src/iguana/algorithms/clas12/FiducialFilter/Validator.cc @@ -1,5 +1,6 @@ #include "Validator.h" #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" #include #include @@ -175,7 +176,7 @@ namespace iguana::clas12 { canv->SaveAs(m_output_file_basename + "_after_DC" + std::to_string(r+1) + ".png"); } m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/algorithms/clas12/LorentzTransformer/Algorithm.cc b/src/iguana/algorithms/clas12/LorentzTransformer/Algorithm.cc index f4091ef3..d84f641a 100644 --- a/src/iguana/algorithms/clas12/LorentzTransformer/Algorithm.cc +++ b/src/iguana/algorithms/clas12/LorentzTransformer/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" // ROOT #include @@ -24,7 +25,7 @@ namespace iguana::clas12 { o_beam_energy = GetCachedOption("beam_energy").value_or(10.6); // FIXME } else { - m_log->Error("unknown frame '{}'", o_frame); + ERROR("unknown frame '{}'", o_frame); throw std::runtime_error("cannot Start LorentzTransformer algorithm"); } @@ -73,15 +74,15 @@ namespace iguana::clas12 { vector_element_t const beta_y, vector_element_t const beta_z) const { - m_log->Debug(fmt::format("{::<30}", "Boost ")); - m_log->Debug(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f}, {:10f})", "p_in", px, py, pz, E)); + DEBUG(fmt::format("{::<30}", "Boost ")); + DEBUG(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f}, {:10f})", "p_in", px, py, pz, E)); // check if |beta| <= 1 auto beta_mag = std::hypot(beta_x, beta_y, beta_z); if(beta_mag > 1) { - m_log->Error("attempt to boost with beta > 1 (faster than the speed of light); will NOT boost this momentum"); - m_log->Debug("{:>8} = {}", "|beta|", beta_mag); - m_log->Debug("{:>8} = ({:10f}, {:10f}, {:10f})", "beta", beta_x, beta_y, beta_z); + ERROR("attempt to boost with beta > 1 (faster than the speed of light); will NOT boost this momentum"); + DEBUG("{:>8} = {}", "|beta|", beta_mag); + DEBUG("{:>8} = ({:10f}, {:10f}, {:10f})", "beta", beta_x, beta_y, beta_z); return {px, py, pz, E}; } @@ -90,9 +91,9 @@ namespace iguana::clas12 { ROOT::Math::Boost beta(beta_x, beta_y, beta_z); auto p_out = beta(p_in); - if(m_log->GetLevel() <= Logger::Level::debug) { - m_log->Debug(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f})", "beta", beta.BetaVector().X(), beta.BetaVector().Y(), beta.BetaVector().Z())); - m_log->Debug(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f}, {:10f})", "p_out", p_out.Px(), p_out.Py(), p_out.Pz(), p_out.E())); + if(GetLogLevel() <= Logger::Level::debug) { + DEBUG(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f})", "beta", beta.BetaVector().X(), beta.BetaVector().Y(), beta.BetaVector().Z())); + DEBUG(fmt::format("{:>8} = ({:10f}, {:10f}, {:10f}, {:10f})", "p_out", p_out.Px(), p_out.Py(), p_out.Pz(), p_out.E())); } return {p_out.Px(), p_out.Py(), p_out.Pz(), p_out.E()}; } diff --git a/src/iguana/algorithms/clas12/MomentumCorrection/Validator.cc b/src/iguana/algorithms/clas12/MomentumCorrection/Validator.cc index 810ce932..f0d598b2 100644 --- a/src/iguana/algorithms/clas12/MomentumCorrection/Validator.cc +++ b/src/iguana/algorithms/clas12/MomentumCorrection/Validator.cc @@ -1,4 +1,5 @@ #include "Validator.h" +#include "iguana/services/LoggerMacros.h" #include #include @@ -114,7 +115,7 @@ namespace iguana::clas12 { canv->SaveAs(m_output_file_basename + "_" + std::to_string(pdg) + ".png"); } m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/algorithms/clas12/PhotonGBTFilter/Algorithm.cc b/src/iguana/algorithms/clas12/PhotonGBTFilter/Algorithm.cc index ec1a40e4..8aa52481 100644 --- a/src/iguana/algorithms/clas12/PhotonGBTFilter/Algorithm.cc +++ b/src/iguana/algorithms/clas12/PhotonGBTFilter/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" namespace iguana::clas12 { @@ -385,7 +386,7 @@ namespace iguana::clas12 { } // Default to RGA inbending pass1 if no match found - m_log->Warn("Run Number {} with pass {} has no matching PhotonGBT model...Defaulting to RGA inbending pass1...", runnum, o_pass); + WARN("Run Number {} with pass {} has no matching PhotonGBT model...Defaulting to RGA inbending pass1...", runnum, o_pass); return [](std::vector const &data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }; } diff --git a/src/iguana/algorithms/clas12/PhotonGBTFilter/Validator.cc b/src/iguana/algorithms/clas12/PhotonGBTFilter/Validator.cc index 001af21b..ebe77d3e 100644 --- a/src/iguana/algorithms/clas12/PhotonGBTFilter/Validator.cc +++ b/src/iguana/algorithms/clas12/PhotonGBTFilter/Validator.cc @@ -1,5 +1,6 @@ #include "Validator.h" #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" namespace iguana::clas12 { REGISTER_IGUANA_VALIDATOR(PhotonGBTFilterValidator); @@ -146,7 +147,7 @@ namespace iguana::clas12 { } canv->SaveAs(m_output_file_basename + "_plot.png"); m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/algorithms/clas12/SectorFinder/Algorithm.cc b/src/iguana/algorithms/clas12/SectorFinder/Algorithm.cc index e3ea605c..4241b492 100644 --- a/src/iguana/algorithms/clas12/SectorFinder/Algorithm.cc +++ b/src/iguana/algorithms/clas12/SectorFinder/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" namespace iguana::clas12 { @@ -134,7 +135,7 @@ namespace iguana::clas12 { break; } if(sect != -1) { - m_log->Trace("{} pindex {} sect {}", det_name, row, sect); + TRACE("{} pindex {} sect {}", det_name, row, sect); resultBank.putInt(i_sector, row, sect); resultBank.putInt(i_pindex, row, row); break; diff --git a/src/iguana/algorithms/clas12/SectorFinder/Validator.cc b/src/iguana/algorithms/clas12/SectorFinder/Validator.cc index b024e4a6..2df5588c 100644 --- a/src/iguana/algorithms/clas12/SectorFinder/Validator.cc +++ b/src/iguana/algorithms/clas12/SectorFinder/Validator.cc @@ -1,4 +1,5 @@ #include "Validator.h" +#include "iguana/services/LoggerMacros.h" #include #include @@ -91,7 +92,7 @@ namespace iguana::clas12 { if (Theta>6.5){ u_IsInFD->Fill(sector); if(sector==0){ - m_log->Trace("e' with theta={} and sector==0, this should not happen", Theta); + TRACE("e' with theta={} and sector==0, this should not happen", Theta) } } } @@ -99,7 +100,7 @@ namespace iguana::clas12 { // skip central particle, or unknown sector if(sector == 0) continue; - m_log->Trace("Filling SectorFinder Validator, pdg {} sector {} pindex {}", pdg, sector, row); + TRACE("Filling SectorFinder Validator, pdg {} sector {} pindex {}", pdg, sector, row); u_YvsX.at(pdg).at(sector - 1)->Fill(x, y); } @@ -134,7 +135,7 @@ namespace iguana::clas12 { canv1D->SaveAs(m_output_file_basename+"_elIsInFD.png"); m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/algorithms/clas12/ZVertexFilter/Algorithm.cc b/src/iguana/algorithms/clas12/ZVertexFilter/Algorithm.cc index 6e7f59ba..9964b75a 100644 --- a/src/iguana/algorithms/clas12/ZVertexFilter/Algorithm.cc +++ b/src/iguana/algorithms/clas12/ZVertexFilter/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" namespace iguana::clas12 { @@ -13,11 +14,11 @@ namespace iguana::clas12 { o_zcuts = GetOptionVector("cuts", {GetConfig()->InRange("runs", o_runnum), "cuts"}); o_pids = GetOptionSet("pids", {GetConfig()->InRange("runs", o_runnum), "pids"}); if(o_zcuts.size() != 2) { - m_log->Error("configuration option 'cuts' must be an array of size 2, but it is {}", PrintOptionValue("cuts")); + ERROR("configuration option 'cuts' must be an array of size 2, but it is {}", PrintOptionValue("cuts")); throw std::runtime_error("bad configuration"); } if(o_pids.size() < 1) { - m_log->Error("configuration option 'pids' must have at least one value"); + ERROR("configuration option 'pids' must have at least one value"); throw std::runtime_error("bad configuration"); } @@ -40,7 +41,7 @@ namespace iguana::clas12 { auto pid = bank.getInt("pid", row); auto status = bank.getShort("status", row); auto accept = Filter(zvertex,pid,status); - m_log->Debug("input vz {} pid {} status {} -- accept = {}", zvertex, pid, status, accept); + DEBUG("input vz {} pid {} status {} -- accept = {}", zvertex, pid, status, accept); return accept ? 1 : 0; }); diff --git a/src/iguana/algorithms/clas12/ZVertexFilter/Validator.cc b/src/iguana/algorithms/clas12/ZVertexFilter/Validator.cc index c22e2d44..f6797cf5 100644 --- a/src/iguana/algorithms/clas12/ZVertexFilter/Validator.cc +++ b/src/iguana/algorithms/clas12/ZVertexFilter/Validator.cc @@ -1,4 +1,5 @@ #include "Validator.h" +#include "iguana/services/LoggerMacros.h" #include #include @@ -103,7 +104,7 @@ namespace iguana::clas12 { canv->SaveAs(m_output_file_basename + "_" + std::to_string(pdg) + ".png"); } m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/algorithms/example/ExampleAlgorithm/Algorithm.cc b/src/iguana/algorithms/example/ExampleAlgorithm/Algorithm.cc index bab21861..7484b650 100644 --- a/src/iguana/algorithms/example/ExampleAlgorithm/Algorithm.cc +++ b/src/iguana/algorithms/example/ExampleAlgorithm/Algorithm.cc @@ -2,6 +2,7 @@ // # include the algorithm header // ############################################################################ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" // ############################################################################ // # namespace must match that in the header @@ -90,7 +91,7 @@ namespace iguana::example { // # print a useful debugging method (see `Logger.h` for details, or other // # algorithms for examples of how to use the logger) // ############################################################################ - m_log->Debug("input PID {} -- accept = {}", pid, accept); + DEBUG("input PID {} -- accept = {}", pid, accept); return accept ? 1 : 0; }); diff --git a/src/iguana/algorithms/physics/InclusiveKinematics/Algorithm.cc b/src/iguana/algorithms/physics/InclusiveKinematics/Algorithm.cc index 87938fcf..f61147e9 100644 --- a/src/iguana/algorithms/physics/InclusiveKinematics/Algorithm.cc +++ b/src/iguana/algorithms/physics/InclusiveKinematics/Algorithm.cc @@ -1,4 +1,5 @@ #include "Algorithm.h" +#include "iguana/services/LoggerMacros.h" // ROOT #include @@ -52,11 +53,11 @@ namespace iguana::physics { m_target.mass = particle::mass.at(pdg); } if(m_beam.pdg == 0) { - m_log->Error("Unknown beam particle {:?}", o_beam_particle); + ERROR("Unknown beam particle {:?}", o_beam_particle); throw std::runtime_error("Start failed"); } if(m_target.mass < 0.0) { - m_log->Error("Unknown target particle {:?}", o_target_particle); + ERROR("Unknown target particle {:?}", o_target_particle); throw std::runtime_error("Start failed"); } @@ -66,7 +67,7 @@ namespace iguana::physics { o_method_reconstruction = method_reconstruction::scattered_lepton; } else { - m_log->Error("Unknown reconstruction method {:?}", method_reconstruction_str); + ERROR("Unknown reconstruction method {:?}", method_reconstruction_str); throw std::runtime_error("Start failed"); } @@ -76,13 +77,13 @@ namespace iguana::physics { o_method_lepton_finder = method_lepton_finder::highest_energy_FD_trigger; } else { - m_log->Error("Unknown lepton finder method {:?}", method_lepton_finder_str); + ERROR("Unknown lepton finder method {:?}", method_lepton_finder_str); throw std::runtime_error("Start failed"); } // set the beam and target momenta if(o_beam_direction.size() != 3) { - m_log->Error("Beam direction is not a 3-vector; assuming it is (0, 0, 1) instead"); + ERROR("Beam direction is not a 3-vector; assuming it is (0, 0, 1) instead"); o_beam_direction = {0.0, 0.0, 1.0}; } auto dir_mag = std::hypot(o_beam_direction[0], o_beam_direction[1], o_beam_direction[2]); @@ -93,7 +94,7 @@ namespace iguana::physics { m_beam.pz = o_beam_direction[2] * beam_p / dir_mag; } else { - m_log->Error("Beam direction magnitude is not > 0"); + ERROR("Beam direction magnitude is not > 0"); throw ::std::runtime_error("Start failed"); } m_target.px = 0.0; @@ -101,12 +102,12 @@ namespace iguana::physics { m_target.pz = 0.0; // print the configuration - m_log->Debug(Logger::Header("CONFIGURATION")); - m_log->Debug("{:>30}: {}", "beam energy", o_beam_energy); - m_log->Debug("{:>30}: {}, mass = {}, p = ({}, {}, {})", "beam particle", o_beam_particle, m_beam.mass, m_beam.px, m_beam.py, m_beam.pz); - m_log->Debug("{:>30}: {}, mass = {}, p = ({}, {}, {})", "target particle", o_target_particle, m_target.mass, m_target.px, m_target.py, m_target.pz); - m_log->Debug("{:>30}: {}", "reconstruction method", method_reconstruction_str); - m_log->Debug("{:>30}: {}", "lepton finder method", method_lepton_finder_str); + DEBUG(Logger::Header("CONFIGURATION")); + DEBUG("{:>30}: {}", "beam energy", o_beam_energy); + DEBUG("{:>30}: {}, mass = {}, p = ({}, {}, {})", "beam particle", o_beam_particle, m_beam.mass, m_beam.px, m_beam.py, m_beam.pz); + DEBUG("{:>30}: {}, mass = {}, p = ({}, {}, {})", "target particle", o_target_particle, m_target.mass, m_target.px, m_target.py, m_target.pz); + DEBUG("{:>30}: {}", "reconstruction method", method_reconstruction_str); + DEBUG("{:>30}: {}", "lepton finder method", method_lepton_finder_str); } /////////////////////////////////////////////////////////////////////////////// @@ -175,9 +176,9 @@ namespace iguana::physics { } } if(lepton_row >= 0) - m_log->Debug("Found scattered lepton: row={}, energy={}", lepton_row, lepton_energy); + DEBUG("Found scattered lepton: row={}, energy={}", lepton_row, lepton_energy) else - m_log->Debug("Scattered lepton not found"); + DEBUG("Scattered lepton not found"); return lepton_row; } @@ -190,7 +191,7 @@ namespace iguana::physics { { InclusiveKinematicsVars result; - m_log->Trace("Reconstruct inclusive kinematics from lepton with p=({}, {}, {})", lepton_px, lepton_py, lepton_pz); + TRACE("Reconstruct inclusive kinematics from lepton with p=({}, {}, {})", lepton_px, lepton_py, lepton_pz); ROOT::Math::PxPyPzMVector vec_beam(m_beam.px, m_beam.py, m_beam.pz, m_beam.mass); ROOT::Math::PxPyPzMVector vec_target(m_target.px, m_target.py, m_target.pz, m_target.mass); diff --git a/src/iguana/algorithms/physics/InclusiveKinematics/Validator.cc b/src/iguana/algorithms/physics/InclusiveKinematics/Validator.cc index 45a8e1c4..bb7c6237 100644 --- a/src/iguana/algorithms/physics/InclusiveKinematics/Validator.cc +++ b/src/iguana/algorithms/physics/InclusiveKinematics/Validator.cc @@ -1,4 +1,5 @@ #include "Validator.h" +#include "iguana/services/LoggerMacros.h" #include #include @@ -12,7 +13,7 @@ namespace iguana::physics { // define the algorithm sequence m_algo_seq = std::make_unique(); m_algo_seq->Add("physics::InclusiveKinematics"); - m_algo_seq->SetOption("physics::InclusiveKinematics", "log", m_log->GetLevel()); + m_algo_seq->SetOption("physics::InclusiveKinematics", "log", GetLogLevel()); m_algo_seq->Start(banks); // get bank indices @@ -60,11 +61,11 @@ namespace iguana::physics { auto& result_bank = GetBank(banks, b_result, "physics::InclusiveKinematics"); if(result_bank.getRowList().size() == 0) { - m_log->Debug("skip this event, since it has no inclusive kinematics results"); + DEBUG("skip this event, since it has no inclusive kinematics results"); return; } if(result_bank.getRowList().size() > 1) { - m_log->Warn("found event with more than 1 inclusive kinematics bank rows; only the first row will be used"); + WARN("found event with more than 1 inclusive kinematics bank rows; only the first row will be used"); } auto pindex = result_bank.getShort("pindex", 0); @@ -145,7 +146,7 @@ namespace iguana::physics { } canv->SaveAs(m_output_file_basename + ".png"); m_output_file->Write(); - m_log->Info("Wrote output file {}", m_output_file->GetName()); + INFO("Wrote output file {}", m_output_file->GetName()); m_output_file->Close(); } } diff --git a/src/iguana/services/ConfigFileReader.cc b/src/iguana/services/ConfigFileReader.cc index a97fd0b9..946ec5cb 100644 --- a/src/iguana/services/ConfigFileReader.cc +++ b/src/iguana/services/ConfigFileReader.cc @@ -1,4 +1,5 @@ #include "ConfigFileReader.h" +#include "iguana/services/LoggerMacros.h" #include #include #include @@ -40,7 +41,7 @@ namespace iguana { { if(dir == "") return; // handle unset directory name - m_log->Trace("Add directory {}", dir); + TRACE("Add directory {}", dir); m_directories.push_front(dir); } @@ -49,18 +50,19 @@ namespace iguana { if(name == "") return; // handle unset file name auto full_name = FindFile(name); - m_log->Trace(" ===> Add file {}", full_name); + TRACE(" ===> Add file {}", full_name); m_files.push_front(full_name); } void ConfigFileReader::PrintDirectories(Logger::Level const level) { - if(m_log->GetLevel() <= level) { - m_log->Print(level, "{:=^60}", " Configuration file search path order: "); - m_log->Print(level, " - ./"); + if(GetLogLevel() <= level) { + PRINT_LOG(level, "{:=^60}", " Configuration file search path order: "); + PRINT_LOG(level, "{:=^60}", " Configuration file search path order: "); + PRINT_LOG(level, " - ./"); for(auto const& dir : m_directories) - m_log->Print(level, " - {}", dir); - m_log->Print(level, "{:=^60}", ""); + PRINT_LOG(level, " - {}", dir); + PRINT_LOG(level, "{:=^60}", ""); } } @@ -68,22 +70,22 @@ namespace iguana { { if(name == "") return ""; // handle unset file name - m_log->Trace("Searching for file '{}' in:", name); + TRACE("Searching for file '{}' in:", name); // first try `./` or assume `name` is a relative or absolute path + filename auto found_local = std::filesystem::exists(name); - m_log->Trace(" - ./{}", found_local ? " - FOUND" : ""); + TRACE(" - ./{}", found_local ? " - FOUND" : ""); if(found_local) return name; // then search each entry of `m_directories` for(auto const& dir : m_directories) { std::string filename = dir + "/" + name; auto found = std::filesystem::exists(filename); - m_log->Trace(" - {}{}", dir, found ? " - FOUND" : ""); + TRACE(" - {}{}", dir, found ? " - FOUND" : ""); if(found) return filename; } // throw exception if not found anywhere - m_log->Error("Cannot find configuration file named '{}'", name); + ERROR("Cannot find configuration file named '{}'", name); PrintDirectories(Logger::error); throw std::runtime_error("configuration file not found"); } diff --git a/src/iguana/services/Logger.cc b/src/iguana/services/Logger.cc index aad8c5ad..fe04fb24 100644 --- a/src/iguana/services/Logger.cc +++ b/src/iguana/services/Logger.cc @@ -2,63 +2,26 @@ namespace iguana { - Logger::Logger(std::string_view name, Level const lev, bool const enable_style) - : m_name(name) - , m_enable_style(enable_style) + Logger::Level Logger::NameToLevel(std::string_view level) { - m_level_names = { - {trace, "trace"}, - {debug, "debug"}, - {info, "info"}, - {quiet, "quiet"}, - {warn, "warn"}, - {error, "error"}, - {silent, "silent"}}; - SetLevel(lev); + if(level == "trace") return trace; + else if(level == "debug") return debug; + else if(level == "info") return info; + else if(level == "quiet") return quiet; + else if(level == "warn") return warn; + else if(level == "error") return error; + else if(level == "silent") return silent; + throw std::runtime_error(fmt::format("unkown log level {:?}", level)); } - void Logger::SetLevel(std::string_view lev) - { - for(auto& [lev_i, lev_n] : m_level_names) { - if(lev == lev_n) { - m_level = lev_i; - Debug("log level set to '{}'", lev); - return; - } - } - Error("Log level '{}' is not a known log level; the log level will remain at '{}'", lev, m_level_names.at(m_level)); - } - - void Logger::SetLevel(Level const lev) - { - try { - auto level_name = m_level_names.at(lev); - m_level = lev; - Debug("log level set to '{}'", level_name); - } - catch(std::out_of_range const& ex) { - Error("Log level '{}' is not a known log level; the log level will remain at '{}'", static_cast(lev), m_level_names.at(m_level)); - } - } - - Logger::Level Logger::GetLevel() - { - return m_level; - } - - void Logger::EnableStyle() - { - m_enable_style = true; - } - - void Logger::DisableStyle() + std::string Logger::Header(std::string_view message, int const width) { - m_enable_style = false; + return fmt::format("{:=^{}}", fmt::format(" {} ", message), width); } - std::string Logger::Header(std::string_view message, int const width) + void Logger::PrintLogV(FILE* out, std::string_view prefix, fmt::string_view fmt_str, fmt::format_args fmt_args) { - return fmt::format("{:=^{}}", fmt::format(" {} ", message), width); + fmt::print(out, "{} {}\n", prefix, fmt::vformat(fmt_str, fmt_args)); } } diff --git a/src/iguana/services/Logger.h b/src/iguana/services/Logger.h index 0f2ce863..eff3c8d0 100644 --- a/src/iguana/services/Logger.h +++ b/src/iguana/services/Logger.h @@ -1,22 +1,10 @@ -#pragma once - -#include #include +#include #include -#include -#include namespace iguana { - /// @brief Simple logger service - /// - /// - Each algorithm instance should own a `Logger` instance - /// - The user may control the log level of each `Logger`, thus the log level of each algorithm - /// - Errors and warnings print to `stderr`, whereas all other levels print to `stdout` - class Logger - { - - friend class Object; + class Logger { public: @@ -38,34 +26,21 @@ namespace iguana { silent }; - /// The default log level - static Level const DEFAULT_LEVEL = info; - - /// @param name the name of this logger instance, which will be include in all of its printouts - /// @param lev the log level - /// @param enable_style if true, certain printouts will be styled with color and emphasis - Logger(std::string_view name = "log", Level const lev = DEFAULT_LEVEL, bool const enable_style = true); - ~Logger() {} - - /// Set the log level to this level. Log messages with a lower level will not be printed. - /// @see `Logger::Level` for available levels. - /// @param lev the log level name - void SetLevel(std::string_view lev); - - /// Set the log level to this level. Log messages with a lower level will not be printed. - /// @see `Logger::Level` for available levels. - /// @param lev the log level - void SetLevel(Level const lev); - - /// Get the current log level - /// @returns the log level - Level GetLevel(); - - /// Enable styled log printouts, with color and emphasis - void EnableStyle(); - - /// Disable styled log printout color and emphasis - void DisableStyle(); + /// @brief convert a `Level` name to an integer representation + /// @param level the level name + /// @returns the `Level` integer + static Level NameToLevel(std::string_view level); + + /// @brief Print a log message + /// @param out the output stream, _e.g._, `stdout` or `stderr` + /// @param prefix a prefix in front of the log message, _e.g._, the log level or relevant file name + /// @param fmt_str the `fmt` format string + /// @param fmt_args the arguments for `fmt_str` + template + static void PrintLog(FILE* out, std::string_view prefix, fmt::format_string fmt_str, ARG_TYPES&&... fmt_args) + { + PrintLogV(out, prefix, fmt_str, fmt::make_format_args(fmt_args...)); + } /// Generate a header for a printout /// @param message the header message @@ -73,71 +48,17 @@ namespace iguana { /// @returns the header string static std::string Header(std::string_view message, int const width = 50); - /// Printout a log message at the `trace` level @see `Logger::Print` for more details - template - void Trace(std::string_view message, const VALUES... vals) const { Print(trace, message, vals...); } - /// Printout a log message at the `debug` level @see `Logger::Print` for more details - template - void Debug(std::string_view message, const VALUES... vals) const { Print(debug, message, vals...); } - /// Printout a log message at the `info` level @see `Logger::Print` for more details - template - void Info(std::string_view message, const VALUES... vals) const { Print(info, message, vals...); } - /// Printout a log message at the `warn` level @see `Logger::Print` for more details - template - void Warn(std::string_view message, const VALUES... vals) const { Print(warn, message, vals...); } - /// Printout a log message at the `error` level @see `Logger::Print` for more details - template - void Error(std::string_view message, const VALUES... vals) const { Print(error, message, vals...); } - - /// Printout a log message at the specified level. The message will only print if `lev` is at least as high as the current level of - /// this `Logger` instance, as set by `Logger::SetLevel`. - /// @param lev the log level for this message - /// @param message the message to print; this may be a format string, as in `fmt::format` - /// @param vals values for the format string `message` - template - void Print(Level const lev, std::string_view message, const VALUES... vals) const - { - if(lev >= m_level) { - if(auto it{m_level_names.find(lev)}; it != m_level_names.end()) { - std::function style = [](std::string s) - { return fmt::format("[{}]", s); }; - if(m_enable_style) { - switch(lev) { - case warn: - style = [](std::string s) - { return fmt::format("[{}]", fmt::styled(s, fmt::emphasis::bold | fmt::fg(fmt::terminal_color::magenta))); }; - break; - case error: - style = [](std::string s) - { return fmt::format("[{}]", fmt::styled(s, fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red))); }; - break; - default: - style = [](std::string s) - { return fmt::format("[{}]", fmt::styled(s, fmt::emphasis::bold)); }; - } - } - fmt::print( - lev >= warn ? stderr : stdout, - fmt::runtime(fmt::format("{} {} {}\n", style(it->second), style(m_name), message)), - vals...); - } - else - throw std::runtime_error("Logger::Print called with unknown log level"); - } - } - private: - /// The name of this logger, which is included in all printouts - std::string m_name; - - /// The current log level for this instance - Level m_level; - - /// Association of the log level to its name - std::unordered_map m_level_names; + static void PrintLogV(FILE* out, std::string_view prefix, fmt::string_view fmt_str, fmt::format_args fmt_args); + }; - /// If true, style the printouts - bool m_enable_style; + /// `Logger` configuration settings + struct LoggerSettings { + /// The current `Logger` log level + Logger::Level level{Logger::Level::info}; + /// Whether or not `Logger` printouts will be colored and formatted + bool styled{true}; }; + } diff --git a/src/iguana/services/LoggerMacros.h b/src/iguana/services/LoggerMacros.h new file mode 100644 index 00000000..02cdec85 --- /dev/null +++ b/src/iguana/services/LoggerMacros.h @@ -0,0 +1,94 @@ +/// @file +/// @brief `iguana::Logger` macros for printing log messages at different `iguana::Logger` levels. +/// +/// @see `iguana::Logger::Level` for the list of log levels; each `Object` instance has its own log level, +/// which controls which log messages are printed +/// +/// @warning These macros should: +/// - only be used in classes which inherit from `iguana::Object` +/// - only ever be included in `.cc` files and _NEVER_ in header `.h` files + +// clang-format off + +/// @brief print a detailed message at the most fine-grained log level; this is for things that are printed more frequently than by `DEBUG`, +/// for example, a printout of particle momenta for every particle +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define TRACE(fmt_str, ...) \ + { \ + if(m_log_settings.level <= Logger::Level::trace) \ + Logger::PrintLog( \ + stdout, \ + m_log_settings.styled ? fmt::format("{}", fmt::styled(fmt::format("[trace] [{}]", m_name), fmt::emphasis::bold)) : fmt::format("[trace] [{}]", m_name), \ + FMT_STRING(fmt_str), ##__VA_ARGS__); \ + } + +/// @brief print a message useful for debugging; this is for things that are less-frequently printed than by `TRACE`, +/// for example, a printout indicating the beginning of a new event +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define DEBUG(fmt_str, ...) \ + { \ + if(m_log_settings.level <= Logger::Level::debug) \ + Logger::PrintLog( \ + stdout, \ + m_log_settings.styled ? fmt::format("{}", fmt::styled(fmt::format("[debug] [{}]", m_name), fmt::emphasis::bold)) : fmt::format("[debug] [{}]", m_name), \ + FMT_STRING(fmt_str), ##__VA_ARGS__); \ + } + +/// @brief print an informational message; this is supposed to not be used for each event. For example, use this to indicate +/// an algorithm has been successfully configured +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define INFO(fmt_str, ...) \ + { \ + if(m_log_settings.level <= Logger::Level::info) \ + Logger::PrintLog( \ + stdout, \ + m_log_settings.styled ? fmt::format("{}", fmt::styled(fmt::format("[info] [{}]", m_name), fmt::emphasis::bold)) : fmt::format("[info] [{}]", m_name), \ + FMT_STRING(fmt_str), ##__VA_ARGS__); \ + } + +/// @brief print warning message; these are errors that are not necessarily show-stoppers, but the user should still be informed of them +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define WARN(fmt_str, ...) \ + { \ + if(m_log_settings.level <= Logger::Level::warn) \ + Logger::PrintLog( \ + stderr, \ + m_log_settings.styled ? fmt::format("{}", fmt::styled(fmt::format("[warn] [{}]", m_name), fmt::emphasis::bold | fmt::fg(fmt::terminal_color::magenta))) : fmt::format("[warn] [{}]", m_name), \ + FMT_STRING(fmt_str), ##__VA_ARGS__); \ + } + +/// @brief print an error message; this is for things that are truly issues and may cause failure of an algorithm +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define ERROR(fmt_str, ...) \ + { \ + if(m_log_settings.level <= Logger::Level::error) \ + Logger::PrintLog( \ + stderr, \ + m_log_settings.styled ? fmt::format("{}", fmt::styled(fmt::format("[error] [{}]", m_name), fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red))) : fmt::format("[error] [{}]", m_name), \ + FMT_STRING(fmt_str), ##__VA_ARGS__); \ + } + +/// @brief print a log message at a specific level +/// @param level the level to print at +/// @param fmt_str the format string +/// @param ... the arguments for `fmt_str` +#define PRINT_LOG(level, fmt_str, ...) \ + { \ + if(m_log_settings.level <= level) { \ + switch(level) { \ + case Logger::Level::trace: TRACE(fmt_str, ##__VA_ARGS__); break; \ + case Logger::Level::debug: DEBUG(fmt_str, ##__VA_ARGS__); break; \ + case Logger::Level::info: INFO(fmt_str, ##__VA_ARGS__); break; \ + case Logger::Level::warn: WARN(fmt_str, ##__VA_ARGS__); break; \ + case Logger::Level::error: ERROR(fmt_str, ##__VA_ARGS__); break; \ + default: throw std::runtime_error("called PRINT_LOG with bad log level"); \ + } \ + } \ + } + +// clang-format on diff --git a/src/iguana/services/NewLogger.h b/src/iguana/services/NewLogger.h deleted file mode 100644 index 25ec9556..00000000 --- a/src/iguana/services/NewLogger.h +++ /dev/null @@ -1,15 +0,0 @@ -#define WARN(fmt_str, ...) \ - if(m_level <= LogLevel::warn) \ - PrintLog( \ - stderr, \ - fmt::format("{}", fmt::styled(fmt::format("[warn] [{}]", m_name), fmt::emphasis::bold | fmt::fg(fmt::terminal_color::magenta))), \ - FMT_STRING(fmt_str), \ - __VA_ARGS__); - -#define ERROR(fmt_str, ...) \ - if(m_level <= LogLevel::error) \ - PrintLog( \ - stderr, \ - fmt::format("{}", fmt::styled(fmt::format("[error] [{}]", m_name), fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red))), \ - FMT_STRING(fmt_str), \ - __VA_ARGS__); diff --git a/src/iguana/services/Object.cc b/src/iguana/services/Object.cc index 0f1c24c2..635b647a 100644 --- a/src/iguana/services/Object.cc +++ b/src/iguana/services/Object.cc @@ -4,18 +4,11 @@ namespace iguana { Object::Object(std::string_view name) : m_name(name) - , m_log(std::make_unique(m_name)) {} - std::unique_ptr& Object::Log() - { - return m_log; - } - void Object::SetName(std::string_view name) { - m_name = name; - m_log->m_name = name; + m_name = name; } std::string Object::GetName() const @@ -23,14 +16,29 @@ namespace iguana { return m_name; } - void Object::SetLogLevel(std::string_view lev) + void Object::SetLogLevel(std::string_view level) + { + m_log_settings.level = Logger::NameToLevel(level); + } + + void Object::SetLogLevel(Logger::Level const level) + { + m_log_settings.level = level; + } + + Logger::Level Object::GetLogLevel() const + { + return m_log_settings.level; + } + + void Object::EnableLoggerStyle() { - m_log->SetLevel(lev); + m_log_settings.styled = true; } - void Object::SetLogLevel(Logger::Level const lev) + void Object::DisableLoggerStyle() { - m_log->SetLevel(lev); + m_log_settings.styled = false; } } diff --git a/src/iguana/services/Object.h b/src/iguana/services/Object.h index 433c1e52..542ae339 100644 --- a/src/iguana/services/Object.h +++ b/src/iguana/services/Object.h @@ -1,9 +1,5 @@ #pragma once -#include -#include - -#include #include "Logger.h" namespace iguana { @@ -14,32 +10,10 @@ namespace iguana { public: - /// These are the available log levels, from lowest to highest: - /// - `trace`: the most verbose level, used for fine-grained printouts for each event - /// - `debug`: less verbose printout, expected to be less frequent than `trace` - /// - `info`: the least verbose printout; this is the default level - /// - `quiet`: use this level to only allow warnings and errors, silencing all other printouts - /// - `warn`: an issue that may or may not be critical - /// - `error`: an issue that is likely critical - /// - `silent`: use this level to silence **all** printouts (use it at your own risk!) - enum LogLevel { - trace, - debug, - info, - quiet, - warn, - error, - silent - }; - /// @param name the name of this object Object(std::string_view name = ""); ~Object() {} - /// Get the logger - /// @return the logger used by this object - std::unique_ptr& Log(); - /// Change the name of this object /// @param name the new name void SetName(std::string_view name); @@ -49,36 +23,30 @@ namespace iguana { /// Set the log level to this level. Log messages with a lower level will not be printed. /// @see `Logger::Level` for available levels. - /// @param lev the log level name - void SetLogLevel(std::string_view lev); + /// @param level the log level name + void SetLogLevel(std::string_view level); /// Set the log level to this level. Log messages with a lower level will not be printed. /// @see `Logger::Level` for available levels. - /// @param lev the log level - void SetLogLevel(Logger::Level const lev); - + /// @param level the log level + void SetLogLevel(Logger::Level const level); - protected: + /// @returns the current log level + Logger::Level GetLogLevel() const; - /// The name of this object - std::string m_name; + /// Enable styled log printouts, with color and emphasis + void EnableLoggerStyle(); - /// The current log level for this instance - LogLevel m_level; + /// Disable styled log printout color and emphasis + void DisableLoggerStyle(); - /// `Logger` instance for this object - std::unique_ptr m_log; + protected: - void PrintLogV(FILE* out, std::string_view prefix, fmt::string_view fmt_str, fmt::format_args fmt_args) - { - fmt::print(out, "{} {}\n", prefix, fmt::vformat(fmt_str, fmt_args)); - } + /// The name of this `Object` + std::string m_name; - template - void PrintLog(FILE* out, std::string_view prefix, fmt::format_string fmt_str, ARG_TYPES&&... fmt_args) - { - PrintLogV(out, prefix, fmt_str, fmt::make_format_args(fmt_args...)); - } + /// `Logger` settings for this `Object` instance + LoggerSettings m_log_settings; }; } diff --git a/src/iguana/services/YAMLReader.cc b/src/iguana/services/YAMLReader.cc index 9c232e1e..56028d42 100644 --- a/src/iguana/services/YAMLReader.cc +++ b/src/iguana/services/YAMLReader.cc @@ -1,20 +1,21 @@ #include "YAMLReader.h" +#include "iguana/services/LoggerMacros.h" namespace iguana { void YAMLReader::LoadFiles() { - m_log->Debug("YAMLReader::LoadFiles():"); + DEBUG("YAMLReader::LoadFiles():"); for(auto const& file : m_files) { try { - m_log->Debug(" - load: {}", file); + DEBUG(" - load: {}", file); m_configs.push_back({YAML::LoadFile(file), file}); // m_config must be the same ordering as m_files, so `push_back` } catch(const YAML::Exception& e) { - m_log->Error(" - YAML Exception: {}", e.what()); + ERROR(" - YAML Exception: {}", e.what()); } catch(std::exception const& e) { - m_log->Error(" - Exception: {}", e.what()); + ERROR(" - Exception: {}", e.what()); } } } @@ -29,10 +30,10 @@ namespace iguana { return node.as(); } catch(const YAML::Exception& e) { - m_log->Error("YAML Parsing Exception: {}", e.what()); + ERROR("YAML Parsing Exception: {}", e.what()); } catch(std::exception const& e) { - m_log->Error("YAML Misc. Exception: {}", e.what()); + ERROR("YAML Misc. Exception: {}", e.what()); } } throw std::runtime_error("Failed `GetScalar`"); @@ -70,10 +71,10 @@ namespace iguana { return result; } catch(const YAML::Exception& e) { - m_log->Error("YAML Parsing Exception: {}", e.what()); + ERROR("YAML Parsing Exception: {}", e.what()); } catch(std::exception const& e) { - m_log->Error("YAML Misc. Exception: {}", e.what()); + ERROR("YAML Misc. Exception: {}", e.what()); } } throw std::runtime_error("Failed `GetVector`"); @@ -106,7 +107,7 @@ namespace iguana { return [this, key, val](YAML::Node node) -> YAML::Node { if(!node.IsSequence()) { - m_log->Error("YAML node path expected a sequence at current node"); + ERROR("YAML node path expected a sequence at current node"); throw std::runtime_error("Failed `InRange`"); } // search each sub-node for one with `val` with in the range at `key` @@ -124,7 +125,7 @@ namespace iguana { return sub_node; } // if no default found, return empty - m_log->Error("No default node for `InRange('{}',{})`", key, val); + ERROR("No default node for `InRange('{}',{})`", key, val); throw std::runtime_error("Failed `InRange`"); }; } @@ -138,22 +139,22 @@ namespace iguana { // if `node_path` is empty, we are likely at the end of the node path; end recursion and return `node` if(node_path.empty()) { - m_log->Trace("... found"); + TRACE("... found"); return node; } // find the next node using the first `node_id_t` in `node_path` - auto node_id_visitor = [&node, &m_log = this->m_log](auto&& arg) -> YAML::Node + auto node_id_visitor = [&node, &m_log_settings = this->m_log_settings](auto&& arg) -> YAML::Node { using arg_t = std::decay_t; // find a node by key name if constexpr(std::is_same_v) { - m_log->Trace("... by key '{}'", arg); + TRACE("... by key '{}'", arg); return node[arg]; } // find a node using a `node_finder_t` else { - m_log->Trace("... by node finder function"); + TRACE("... by node finder function"); return arg(node); } };