File indexing completed on 2025-01-18 09:55:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #pragma once
0013
0014 #include <boost/assign.hpp>
0015 #include <boost/bimap.hpp>
0016
0017 #include <regex>
0018
0019 #include <spdlog/spdlog.h>
0020 #include <spdlog/fmt/fmt.h>
0021
0022 #include <Acts/Utilities/Logger.hpp>
0023 #include <JANA/JException.h>
0024
0025 namespace eicrecon {
0026
0027 using namespace Acts::Logging;
0028
0029 using SpdlogToActsLevel_t = boost::bimap<spdlog::level::level_enum, Acts::Logging::Level>;
0030 static SpdlogToActsLevel_t kSpdlogToActsLevel = boost::assign::list_of<SpdlogToActsLevel_t::relation>
0031 (spdlog::level::trace, Acts::Logging::VERBOSE)
0032 (spdlog::level::debug, Acts::Logging::DEBUG)
0033 (spdlog::level::info, Acts::Logging::INFO)
0034 (spdlog::level::warn, Acts::Logging::WARNING)
0035 (spdlog::level::err, Acts::Logging::ERROR)
0036 (spdlog::level::critical, Acts::Logging::FATAL);
0037
0038 inline Acts::Logging::Level SpdlogToActsLevel(spdlog::level::level_enum input) {
0039 try {
0040 return kSpdlogToActsLevel.left.at(input);
0041 } catch (...) {
0042 auto err_msg = fmt::format("SpdlogToActsLevel don't know this log level: '{}'", fmt::underlying(input));
0043 throw JException(err_msg);
0044 }
0045 }
0046
0047 inline spdlog::level::level_enum ActsToSpdlogLevel(Acts::Logging::Level input) {
0048 try {
0049 return kSpdlogToActsLevel.right.at(input);
0050 } catch (...) {
0051 auto err_msg = fmt::format("ActsToSpdlogLevel don't know this log level: '{}'", fmt::underlying(input));
0052 throw JException(err_msg);
0053 }
0054 }
0055
0056
0057
0058
0059
0060 class SpdlogPrintPolicy final : public Acts::Logging::OutputPrintPolicy {
0061 public:
0062
0063
0064
0065
0066
0067 explicit SpdlogPrintPolicy(std::shared_ptr<spdlog::logger> out, std::vector<std::string> suppressions = {})
0068 : m_out(out) {
0069 std::transform(suppressions.begin(), suppressions.end(), std::back_inserter(m_suppressions),
0070 [](const std::string& supp_string) {
0071 return std::make_tuple(supp_string, std::regex(supp_string), 0, Acts::Logging::INFO);
0072 }
0073 );
0074 }
0075
0076
0077 ~SpdlogPrintPolicy() {
0078 for (const auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) {
0079 if (supp_count > 0) {
0080 m_out->log(ActsToSpdlogLevel(supp_level), "\"{}\" suppressed {} times", supp_string, supp_count);
0081 }
0082 }
0083 }
0084
0085
0086
0087
0088
0089 void flush(const Level& lvl, const std::string& input) final {
0090 for (auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) {
0091 if (std::regex_search(input, supp_regex)) {
0092 supp_count++;
0093 supp_level = std::max(lvl, supp_level);
0094 return;
0095 }
0096 }
0097 m_out->log(ActsToSpdlogLevel(lvl), input);
0098 if (lvl >= getFailureThreshold()) {
0099 throw ThresholdFailure(
0100 "Previous debug message exceeds the "
0101 "ACTS_LOG_FAILURE_THRESHOLD=" +
0102 std::string{levelName(getFailureThreshold())} +
0103 " configuration, bailing out. See "
0104 "https://acts.readthedocs.io/en/latest/core/"
0105 "logging.html#logging-thresholds");
0106 }
0107 }
0108
0109
0110
0111
0112
0113
0114
0115 const std::string& name() const override {
0116 throw std::runtime_error{
0117 "Default print policy doesn't have a name. Is there no named output in "
0118 "the decorator chain?"};
0119 };
0120
0121
0122
0123
0124 std::unique_ptr<OutputPrintPolicy> clone(
0125 const std::string& name) const override {
0126 (void)name;
0127 return std::make_unique<SpdlogPrintPolicy>(m_out);
0128 };
0129
0130 private:
0131
0132 std::shared_ptr<spdlog::logger> m_out;
0133
0134
0135 std::vector<std::tuple<std::string, std::regex, std::size_t, Acts::Logging::Level>> m_suppressions;
0136 };
0137
0138 inline std::unique_ptr<const Acts::Logger> getSpdlogLogger(
0139 const std::string& name,
0140 std::shared_ptr<spdlog::logger> log,
0141 std::vector<std::string> suppressions = {}) {
0142
0143 const Acts::Logging::Level lvl = SpdlogToActsLevel(log->level());
0144 auto output = std::make_unique<Acts::Logging::NamedOutputDecorator>(
0145 std::make_unique<SpdlogPrintPolicy>(log, suppressions),
0146 name);
0147 auto print = std::make_unique<DefaultFilterPolicy>(lvl);
0148 return std::make_unique<const Acts::Logger>(std::move(output), std::move(print));
0149 }
0150
0151
0152 }