Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:56:34

0001 // Copyright 2022, Dmitry Romanov
0002 // Subject to the terms in the LICENSE file found in the top-level directory.
0003 //
0004 //
0005 #include "Log_service.h"
0006 
0007 #include <JANA/JApplication.h>
0008 #include <JANA/JException.h>
0009 #include <spdlog/details/log_msg.h>
0010 #include <spdlog/formatter.h>
0011 #include <spdlog/pattern_formatter.h>
0012 #include <spdlog/spdlog.h>
0013 #include <spdlog/version.h>
0014 #if SPDLOG_VERSION >= 11400 && (!defined(SPDLOG_NO_TLS) || !SPDLOG_NO_TLS)
0015 #include <spdlog/mdc.h>
0016 #endif
0017 #include <ctime>
0018 #include <exception>
0019 #include <map>
0020 #include <string_view>
0021 #include <utility>
0022 
0023 #include "extensions/spdlog/SpdlogExtensions.h"
0024 
0025 #if SPDLOG_VERSION >= 11400 && (!defined(SPDLOG_NO_TLS) || !SPDLOG_NO_TLS)
0026 
0027 // Define our own MDC formatter since the one in libspdlog.so does not
0028 // function correctly under some compilers
0029 class mdc_formatter_flag : public spdlog::custom_flag_formatter {
0030 public:
0031   void format(const spdlog::details::log_msg& /*msg*/, const std::tm& /*tm_time*/,
0032               spdlog::memory_buf_t& dest) override {
0033     auto& mdc_map = spdlog::mdc::get_context();
0034     if (mdc_map.empty()) {
0035       return;
0036     }
0037     format_mdc(mdc_map, dest);
0038   }
0039 
0040   static void format_mdc(const spdlog::mdc::mdc_map_t& mdc_map, spdlog::memory_buf_t& dest) {
0041     auto last_element = --mdc_map.end();
0042     for (auto it = mdc_map.begin(); it != mdc_map.end(); ++it) {
0043       const auto& pair  = *it;
0044       const auto& key   = pair.first;
0045       const auto& value = pair.second;
0046       dest.append(std::string_view{key});
0047       dest.append(std::string_view{":"});
0048       dest.append(std::string_view{value});
0049       if (it != last_element) {
0050         dest.append(std::string_view{" "});
0051       }
0052     }
0053   }
0054 
0055   std::unique_ptr<custom_flag_formatter> clone() const override {
0056     return spdlog::details::make_unique<mdc_formatter_flag>();
0057   }
0058 };
0059 
0060 #endif
0061 
0062 Log_service::Log_service(JApplication* app) : m_application(app), m_log_level_str("info") {
0063   // Here one could add centralized documentation for spdlog::default_logger()
0064   // All subsequent loggers are cloned from the spdlog::default_logger()
0065 
0066   m_application->SetDefaultParameter("eicrecon:LogLevel", m_log_level_str,
0067                                      "log_level: trace, debug, info, warn, error, critical, off");
0068   spdlog::default_logger()->set_level(eicrecon::ParseLogLevel(m_log_level_str));
0069 
0070   auto formatter = std::make_unique<spdlog::pattern_formatter>();
0071 #if SPDLOG_VERSION >= 11400 && (!defined(SPDLOG_NO_TLS) || !SPDLOG_NO_TLS)
0072   formatter->add_flag<mdc_formatter_flag>('&').set_pattern("[%&] [%n] [%^%l%$] %v");
0073 #else
0074   formatter->set_pattern("[%n] [%^%l%$] %v");
0075 #endif
0076   m_application->SetDefaultParameter("eicrecon:LogFormat", m_log_level_str,
0077                                      "spdlog pattern string");
0078   spdlog::set_formatter(std::move(formatter));
0079 }
0080 
0081 // Virtual destructor implementation to pin vtable and typeinfo to this
0082 // translation unit
0083 Log_service::~Log_service() = default;
0084 
0085 std::shared_ptr<spdlog::logger> Log_service::logger(const std::string& name,
0086                                                     const std::optional<level> default_level) {
0087 
0088   try {
0089     std::lock_guard<std::recursive_mutex> locker(m_lock);
0090 
0091     // Try to get existing logger
0092     auto logger = spdlog::get(name);
0093     if (!logger) {
0094       // or create a new one with current configuration
0095       logger = spdlog::default_logger()->clone(name);
0096 
0097       // Set log level for this named logger allowing user to specify as config. parameter
0098       // e.g. EcalEndcapPRecHits:LogLevel
0099       std::string log_level_str =
0100           default_level ? eicrecon::LogLevelToString(default_level.value()) : m_log_level_str;
0101       m_application->SetDefaultParameter(name + ":LogLevel", log_level_str,
0102                                          "log_level for " + name +
0103                                              ": trace, debug, info, warn, error, critical, off");
0104       logger->set_level(eicrecon::ParseLogLevel(log_level_str));
0105     }
0106     return logger;
0107   } catch (const std::exception& exception) {
0108     throw JException(exception.what());
0109   }
0110 }
0111 
0112 Log_service::level Log_service::getDefaultLevel() { return spdlog::default_logger()->level(); }
0113 
0114 std::string Log_service::getDefaultLevelStr() {
0115   return eicrecon::LogLevelToString(getDefaultLevel());
0116 }