Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:15:21

0001 // SPDX-License-Identifier: MPL-2.0
0002 //
0003 // Copyright (C) 2016-2018 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 //
0009 // Based on code from Acts at Core/include/Acts/Utilities/Logger.hpp
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 =
0031     boost::assign::list_of<SpdlogToActsLevel_t::relation>(
0032         spdlog::level::trace, Acts::Logging::VERBOSE)(spdlog::level::debug, Acts::Logging::DEBUG)(
0033         spdlog::level::info, Acts::Logging::INFO)(spdlog::level::warn, Acts::Logging::WARNING)(
0034         spdlog::level::err, Acts::Logging::ERROR)(spdlog::level::critical, Acts::Logging::FATAL);
0035 
0036 inline Acts::Logging::Level SpdlogToActsLevel(spdlog::level::level_enum input) {
0037   try {
0038     return kSpdlogToActsLevel.left.at(input);
0039   } catch (...) {
0040     auto err_msg =
0041         fmt::format("SpdlogToActsLevel don't know this log level: '{}'", fmt::underlying(input));
0042     throw JException(err_msg);
0043   }
0044 }
0045 
0046 inline spdlog::level::level_enum ActsToSpdlogLevel(Acts::Logging::Level input) {
0047   try {
0048     return kSpdlogToActsLevel.right.at(input);
0049   } catch (...) {
0050     auto err_msg =
0051         fmt::format("ActsToSpdlogLevel don't know this log level: '{}'", fmt::underlying(input));
0052     throw JException(err_msg);
0053   }
0054 }
0055 
0056 /// @brief default print policy for debug messages
0057 ///
0058 /// This class allows to print debug messages without further modifications to
0059 /// a specified output stream.
0060 class SpdlogPrintPolicy final : public Acts::Logging::OutputPrintPolicy {
0061 public:
0062   /// @brief constructor
0063   ///
0064   /// @param [in] out pointer to output stream object
0065   ///
0066   /// @pre @p out is non-zero
0067   explicit SpdlogPrintPolicy(std::shared_ptr<spdlog::logger> out,
0068                              std::vector<std::string> suppressions = {})
0069       : m_out(out) {
0070     std::transform(suppressions.begin(), suppressions.end(), std::back_inserter(m_suppressions),
0071                    [](const std::string& supp_string) {
0072                      return std::make_tuple(supp_string, std::regex(supp_string), 0,
0073                                             Acts::Logging::INFO);
0074                    });
0075   }
0076 
0077   /// @brief destructor
0078   ~SpdlogPrintPolicy() {
0079     for (const auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) {
0080       if (supp_count > 0) {
0081         m_out->log(ActsToSpdlogLevel(supp_level), "\"{}\" suppressed {} times", supp_string,
0082                    supp_count);
0083       }
0084     }
0085   }
0086 
0087   /// @brief flush the debug message to the destination stream
0088   ///
0089   /// @param [in] lvl   debug level of debug message
0090   /// @param [in] input text of debug message
0091   void flush(const Level& lvl, const std::string& input) final {
0092     for (auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) {
0093       if (std::regex_search(input, supp_regex)) {
0094         supp_count++;
0095         supp_level = std::max(lvl, supp_level);
0096         return;
0097       }
0098     }
0099     m_out->log(ActsToSpdlogLevel(lvl), input);
0100     if (lvl >= getFailureThreshold()) {
0101       throw ThresholdFailure("Previous debug message exceeds the "
0102                              "ACTS_LOG_FAILURE_THRESHOLD=" +
0103                              std::string{levelName(getFailureThreshold())} +
0104                              " configuration, bailing out. See "
0105                              "https://acts.readthedocs.io/en/latest/core/"
0106                              "logging.html#logging-thresholds");
0107     }
0108   }
0109 
0110   /// Fulfill @c OutputPrintPolicy interface. This policy doesn't actually have a
0111   /// name, so the assumption is that somewhere in the decorator hierarchy,
0112   /// there is something that returns a name without delegating to a wrappee,
0113   /// before reaching this overload.
0114   /// @note This method will throw an exception
0115   /// @return the name, but it never returns
0116   const std::string& name() const override {
0117     throw std::runtime_error{
0118         "Default print policy doesn't have a name. Is there no named output in "
0119         "the decorator chain?"};
0120   };
0121 
0122   /// Make a copy of this print policy with a new name
0123   /// @param name the new name
0124   /// @return the copy
0125   std::unique_ptr<OutputPrintPolicy> clone(const std::string& name) const override {
0126     (void)name;
0127     return std::make_unique<SpdlogPrintPolicy>(m_out);
0128   };
0129 
0130 private:
0131   /// pointer to destination output stream
0132   std::shared_ptr<spdlog::logger> m_out;
0133 
0134   /// regexes for messages to be suppressed
0135   std::vector<std::tuple<std::string, std::regex, std::size_t, Acts::Logging::Level>>
0136       m_suppressions;
0137 };
0138 
0139 inline std::unique_ptr<const Acts::Logger>
0140 getSpdlogLogger(const std::string& name, 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), name);
0146   auto print = std::make_unique<DefaultFilterPolicy>(lvl);
0147   return std::make_unique<const Acts::Logger>(std::move(output), std::move(print));
0148 }
0149 
0150 } // namespace eicrecon