![]() |
|
|||
File indexing completed on 2025-07-03 07:52:17
0001 // This file is part of the ACTS project. 0002 // 0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. 0008 0009 #pragma once 0010 0011 // STL include(s) 0012 #include <ctime> 0013 #include <iomanip> 0014 #include <iostream> 0015 #include <memory> 0016 #include <mutex> 0017 #include <optional> 0018 #include <sstream> 0019 #include <stdexcept> 0020 #include <string> 0021 #include <string_view> 0022 #include <thread> 0023 #include <utility> 0024 0025 /// @defgroup Logging Logging 0026 0027 // clang-format off 0028 /// @brief macro to use a local Acts::Logger object 0029 /// @ingroup Logging 0030 /// 0031 /// @param log_object logger instance of type 0032 // <tt>std::unique_ptr<const Acts::Logger></tt> 0033 /// 0034 /// @pre In the current scope, the symbol @c logger is not yet defined. 0035 /// @post The ownership of the given @c log_object is transferred and 0036 /// @c log_object should not be used directly any more. 0037 /// 0038 /// This macro allows to use a locally defined logging object with the ACTS_* 0039 /// logging macros. The envisaged usage is the following: 0040 /// 0041 /// @code{.cpp} 0042 /// void myFunction() { 0043 /// std::unique_ptr<const Acts::Logger> myLogger 0044 /// = /* .. your initialization .. */; 0045 /// ACTS_LOCAL_LOGGER(std::move(myLogger)); 0046 /// 0047 /// ACTS_VERBOSE("hello world!"); 0048 /// } 0049 /// @endcode 0050 #define ACTS_LOCAL_LOGGER(log_object) \ 0051 struct __local_acts_logger \ 0052 { \ 0053 explicit __local_acts_logger(std::unique_ptr<const ::Acts::Logger> logger): \ 0054 m_logger(std::move(logger)) \ 0055 {} \ 0056 \ 0057 const ::Acts::Logger& operator()() const \ 0058 { \ 0059 return *m_logger; \ 0060 } \ 0061 \ 0062 std::unique_ptr<const ::Acts::Logger> m_logger; \ 0063 }; \ 0064 __local_acts_logger logger(log_object); 0065 0066 // Debug level agnostic implementation of the ACTS_XYZ logging macros 0067 #define ACTS_LOG(level, x) \ 0068 do { \ 0069 if (logger().doPrint(level)) { \ 0070 std::ostringstream os; \ 0071 os << x; \ 0072 logger().log(level, os.str()); \ 0073 } \ 0074 } \ 0075 while(0) 0076 0077 /// @brief macro for verbose debug output 0078 /// @ingroup Logging 0079 /// 0080 /// @param x debug message 0081 /// 0082 /// @pre @c logger() must be a valid expression in the scope where this 0083 /// macro is used and it must return a Acts::Logger object. 0084 /// 0085 /// The debug message is printed if the current Acts::Logging::Level <= 0086 /// Acts::Logging::VERBOSE. 0087 #define ACTS_VERBOSE(x) ACTS_LOG(Acts::Logging::VERBOSE, x) 0088 0089 /// @brief macro for debug debug output 0090 /// @ingroup Logging 0091 /// 0092 /// @param x debug message 0093 /// 0094 /// @pre @c logger() must be a valid expression in the scope where this 0095 /// macro is used and it must return a Acts::Logger object. 0096 /// 0097 /// The debug message is printed if the current Acts::Logging::Level <= 0098 /// Acts::Logging::DEBUG. 0099 #define ACTS_DEBUG(x) ACTS_LOG(Acts::Logging::DEBUG, x) 0100 0101 /// @brief macro for info debug output 0102 /// @ingroup Logging 0103 /// 0104 /// @param x debug message 0105 /// 0106 /// @pre @c logger() must be a valid expression in the scope where this 0107 /// macro is used and it must return a Acts::Logger object. 0108 /// 0109 /// The debug message is printed if the current Acts::Logging::Level <= 0110 /// Acts::Logging::INFO. 0111 #define ACTS_INFO(x) ACTS_LOG(Acts::Logging::INFO, x) 0112 0113 /// @brief macro for warning debug output 0114 /// @ingroup Logging 0115 /// 0116 /// @param x debug message 0117 /// 0118 /// @pre @c logger() must be a valid expression in the scope where this 0119 /// macro is used and it must return a Acts::Logger object. 0120 /// 0121 /// The debug message is printed if the current Acts::Logging::Level <= 0122 /// Acts::Logging::WARNING. 0123 #define ACTS_WARNING(x) ACTS_LOG(Acts::Logging::WARNING, x) 0124 0125 /// @brief macro for error debug output 0126 /// @ingroup Logging 0127 /// 0128 /// @param x debug message 0129 /// 0130 /// @pre @c logger() must be a valid expression in the scope where this 0131 /// macro is used and it must return a Acts::Logger object. 0132 /// 0133 /// The debug message is printed if the current Acts::Logging::Level <= 0134 /// Acts::Logging::ERROR. 0135 #define ACTS_ERROR(x) ACTS_LOG(Acts::Logging::ERROR, x) 0136 0137 /// @brief macro for fatal debug output 0138 /// @ingroup Logging 0139 /// 0140 /// @param x debug message 0141 /// 0142 /// @pre @c logger() must be a valid expression in the scope where this 0143 /// macro is used and it must return a Acts::Logger object. 0144 /// 0145 /// The debug message is printed if the current Acts::Logging::Level <= 0146 /// Acts::Logging::FATAL. 0147 #define ACTS_FATAL(x) ACTS_LOG(Acts::Logging::FATAL, x) 0148 // clang-format on 0149 0150 namespace Acts { 0151 0152 /// @brief debug output related helper classes and functions 0153 /// @ingroup Logging 0154 namespace Logging { 0155 /// @brief constants steering the debug output 0156 /// 0157 /// All messages with a debug level equal or higher than the currently set 0158 /// debug output level will be printed. 0159 enum Level { 0160 VERBOSE = 0, ///< VERBOSE level 0161 DEBUG, ///< DEBUG level 0162 INFO, ///< INFO level 0163 WARNING, ///< WARNING level 0164 ERROR, ///< ERROR level 0165 FATAL, ///< FATAL level 0166 MAX ///< Must be kept above the maximum supported debug level 0167 }; 0168 0169 inline std::string_view levelName(Level level) { 0170 switch (level) { 0171 case Level::VERBOSE: 0172 return "VERBOSE"; 0173 case Level::DEBUG: 0174 return "DEBUG"; 0175 case Level::INFO: 0176 return "INFO"; 0177 case Level::WARNING: 0178 return "WARNING"; 0179 case Level::ERROR: 0180 return "ERROR"; 0181 case Level::FATAL: 0182 return "FATAL"; 0183 case Level::MAX: 0184 return "MAX"; 0185 default: 0186 throw std::invalid_argument{"Unknown level"}; 0187 } 0188 } 0189 0190 #ifdef DOXYGEN 0191 /// @brief Get debug level above which an exception will be thrown after logging 0192 /// 0193 /// All messages with a debug level equal or higher than the return value of 0194 /// this function will cause an exception to be thrown after log emission. 0195 /// 0196 /// @note Depending on preprocessor settings @c ACTS_ENABLE_LOG_FAILURE_THRESHOLD 0197 /// and @c ACTS_LOG_FAILURE_THRESHOLD, this operations is either constexpr 0198 /// or a runtime operation. 0199 Level getFailureThreshold(); 0200 0201 #else 0202 0203 #ifdef ACTS_ENABLE_LOG_FAILURE_THRESHOLD 0204 #ifdef ACTS_LOG_FAILURE_THRESHOLD 0205 // We have a fixed compile time log failure threshold 0206 constexpr Level getFailureThreshold() { 0207 return Level::ACTS_LOG_FAILURE_THRESHOLD; 0208 } 0209 #else 0210 Level getFailureThreshold(); 0211 #endif 0212 #else 0213 constexpr Level getFailureThreshold() { 0214 // Default "NO" failure threshold 0215 return Level::MAX; 0216 } 0217 #endif 0218 0219 #endif 0220 0221 /// @brief Set debug level above which an exception will be thrown after logging 0222 /// 0223 /// All messages with a debug level equal or higher than @p level will 0224 /// cause an exception to be thrown after log emission. 0225 /// 0226 /// @warning The runtime log failure threshold is **global state**, therefore 0227 /// this function is **not threadsafe**. The intention is that this 0228 /// level is set once, before multi-threaded execution begins, and then 0229 /// not modified before the end of the job. 0230 /// @note This function is only available if @c ACTS_LOG_FAILURE_THRESHOLD is 0231 /// unset, i.e. no compile-time threshold is used. Otherwise an 0232 /// exception is thrown. 0233 void setFailureThreshold(Level level); 0234 0235 /// Custom exception class so threshold failures can be caught 0236 class ThresholdFailure : public std::runtime_error { 0237 using std::runtime_error::runtime_error; 0238 }; 0239 0240 /// Helper class that changes the failure threshold for the duration of its 0241 /// lifetime. 0242 class ScopedFailureThreshold { 0243 public: 0244 explicit ScopedFailureThreshold(Level level) { setFailureThreshold(level); } 0245 ScopedFailureThreshold(const ScopedFailureThreshold&) = delete; 0246 ScopedFailureThreshold& operator=(const ScopedFailureThreshold&) = delete; 0247 ScopedFailureThreshold(ScopedFailureThreshold&&) = delete; 0248 ScopedFailureThreshold& operator=(ScopedFailureThreshold&&) = delete; 0249 0250 ~ScopedFailureThreshold() noexcept; 0251 0252 private: 0253 Level m_previousLevel{getFailureThreshold()}; 0254 }; 0255 0256 /// @brief abstract base class for printing debug output 0257 /// 0258 /// Implementations of this interface need to define how and where to @a print 0259 /// debug messages (e.g. to a file, to a stream into a database etc). 0260 class OutputPrintPolicy { 0261 public: 0262 /// virtual default destructor 0263 virtual ~OutputPrintPolicy() = default; 0264 0265 /// @brief handle output of debug message 0266 /// 0267 /// @param [in] lvl debug output level of message 0268 /// @param [in] input text of debug message 0269 virtual void flush(const Level& lvl, const std::string& input) = 0; 0270 0271 /// Return the name of the print policy 0272 /// @return the name 0273 virtual const std::string& name() const = 0; 0274 0275 /// Make a copy of this print policy with a new name 0276 /// @param name the new name 0277 /// @return the copy 0278 virtual std::unique_ptr<OutputPrintPolicy> clone( 0279 const std::string& name) const = 0; 0280 }; 0281 0282 /// @brief abstract base class for filtering debug output 0283 /// 0284 /// Implementations of this interface need to define whether a debug message 0285 /// with a certain debug level is processed or filtered out. 0286 class OutputFilterPolicy { 0287 public: 0288 /// virtual default destructor 0289 virtual ~OutputFilterPolicy() = default; 0290 0291 /// @brief decide whether a debug message should be processed 0292 /// 0293 /// @param [in] lvl debug level of debug message 0294 /// 0295 /// @return @c true of debug message should be processed, @c false if debug 0296 /// message should be skipped 0297 virtual bool doPrint(const Level& lvl) const = 0; 0298 0299 /// Get the level of this filter policy 0300 /// @return the levele 0301 virtual Level level() const = 0; 0302 0303 /// Make a copy of this filter policy with a new level 0304 /// @param level the new level 0305 /// @return the new copy 0306 virtual std::unique_ptr<OutputFilterPolicy> clone(Level level) const = 0; 0307 }; 0308 0309 /// @brief default filter policy for debug messages 0310 /// 0311 /// All debug messages with a debug level equal or larger to the specified 0312 /// threshold level are processed. 0313 class DefaultFilterPolicy final : public OutputFilterPolicy { 0314 public: 0315 /// @brief constructor 0316 /// 0317 /// @param [in] lvl threshold debug level 0318 explicit DefaultFilterPolicy(Level lvl) : m_level(lvl) { 0319 if (lvl > getFailureThreshold()) { 0320 throw ThresholdFailure( 0321 "Requested debug level is incompatible with " 0322 "the ACTS_LOG_FAILURE_THRESHOLD=" + 0323 std::string{levelName(getFailureThreshold())} + 0324 " configuration. See " 0325 "https://acts.readthedocs.io/en/latest/core/misc/" 0326 "logging.html#logging-thresholds"); 0327 } 0328 } 0329 0330 /// virtual default destructor 0331 ~DefaultFilterPolicy() override = default; 0332 0333 /// @brief decide whether a debug message should be processed 0334 /// 0335 /// @param [in] lvl debug level of debug message 0336 /// 0337 /// @return @c true if @p lvl >= #m_level, otherwise @c false 0338 bool doPrint(const Level& lvl) const override { return m_level <= lvl; } 0339 0340 /// Get the level of this filter policy 0341 /// @return the levele 0342 Level level() const override { return m_level; } 0343 0344 /// Make a copy of this filter policy with a new level 0345 /// @param level the new level 0346 /// @return the new copy 0347 std::unique_ptr<OutputFilterPolicy> clone(Level level) const override { 0348 return std::make_unique<DefaultFilterPolicy>(level); 0349 } 0350 0351 private: 0352 /// threshold debug level for messages to be processed 0353 Level m_level; 0354 }; 0355 0356 /// @brief base class for decorating the debug output 0357 /// 0358 /// Derived classes may augment the debug message with additional information. 0359 /// Chaining different decorators is possible to customize the output to your 0360 /// needs. 0361 class OutputDecorator : public OutputPrintPolicy { 0362 public: 0363 /// @brief constructor wrapping actual output print policy 0364 /// 0365 /// @param [in] wrappee output print policy object which is wrapped by this 0366 /// decorator object 0367 explicit OutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee) 0368 : m_wrappee(std::move(wrappee)) {} 0369 0370 /// @brief flush the debug message to the destination stream 0371 /// 0372 /// @param [in] lvl debug level of debug message 0373 /// @param [in] input text of debug message 0374 /// 0375 /// This function delegates the flushing of the debug message to its wrapped 0376 /// object. 0377 void flush(const Level& lvl, const std::string& input) override { 0378 m_wrappee->flush(lvl, input); 0379 } 0380 0381 /// Return the name of the output decorator (forwards to wrappee) 0382 /// @return the name 0383 const std::string& name() const override { return m_wrappee->name(); } 0384 0385 protected: 0386 /// wrapped object for printing the debug message 0387 std::unique_ptr<OutputPrintPolicy> m_wrappee; 0388 }; 0389 0390 /// @brief decorate debug message with a name 0391 /// 0392 /// The debug message is complemented with a name. 0393 class NamedOutputDecorator final : public OutputDecorator { 0394 public: 0395 /// @brief constructor 0396 /// 0397 /// @param [in] wrappee output print policy object to be wrapped 0398 /// @param [in] name name to be added to debug message 0399 /// @param [in] maxWidth maximum width of field used for name 0400 NamedOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee, 0401 const std::string& name, unsigned int maxWidth = 15) 0402 : OutputDecorator(std::move(wrappee)), 0403 m_name(name), 0404 m_maxWidth(maxWidth) {} 0405 0406 /// @brief flush the debug message to the destination stream 0407 /// 0408 /// @param [in] lvl debug level of debug message 0409 /// @param [in] input text of debug message 0410 /// 0411 /// This function prepends the given name to the debug message and then 0412 /// delegates the flushing of the whole message to its wrapped object. 0413 void flush(const Level& lvl, const std::string& input) override { 0414 std::ostringstream os; 0415 os << std::left << std::setw(m_maxWidth) << m_name.substr(0, m_maxWidth - 3) 0416 << input; 0417 OutputDecorator::flush(lvl, os.str()); 0418 } 0419 0420 /// Make a copy of this print policy with a new name 0421 /// @param name the new name 0422 /// @return the copy 0423 std::unique_ptr<OutputPrintPolicy> clone( 0424 const std::string& name) const override { 0425 return std::make_unique<NamedOutputDecorator>(m_wrappee->clone(name), name, 0426 m_maxWidth); 0427 } 0428 0429 /// Get this named output decorators name 0430 /// @return the name 0431 const std::string& name() const override { return m_name; } 0432 0433 private: 0434 /// name to be prepended 0435 std::string m_name; 0436 0437 /// maximum width of field for printing the name 0438 unsigned int m_maxWidth; 0439 }; 0440 0441 /// @brief decorate debug message with a time stamp 0442 /// 0443 /// The debug message is complemented with a time stamp. 0444 class TimedOutputDecorator final : public OutputDecorator { 0445 public: 0446 /// @brief constructor 0447 /// 0448 /// @param [in] wrappee output print policy object to be wrapped 0449 /// @param [in] format format of time stamp (see std::strftime) 0450 explicit TimedOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee, 0451 const std::string& format = "%X") 0452 : OutputDecorator(std::move(wrappee)), m_format(format) {} 0453 0454 /// @brief flush the debug message to the destination stream 0455 /// 0456 /// @param [in] lvl debug level of debug message 0457 /// @param [in] input text of debug message 0458 /// 0459 /// This function prepends a time stamp to the debug message and then 0460 /// delegates the flushing of the whole message to its wrapped object. 0461 void flush(const Level& lvl, const std::string& input) override { 0462 std::ostringstream os; 0463 os << std::left << std::setw(12) << now() << input; 0464 OutputDecorator::flush(lvl, os.str()); 0465 } 0466 0467 /// Make a copy of this print policy with a new name 0468 /// @param name the new name 0469 /// @return the copy 0470 std::unique_ptr<OutputPrintPolicy> clone( 0471 const std::string& name) const override { 0472 return std::make_unique<TimedOutputDecorator>(m_wrappee->clone(name), 0473 m_format); 0474 } 0475 0476 private: 0477 /// @brief get current time stamp 0478 /// 0479 /// @return current time stamp as string 0480 std::string now() const { 0481 char buffer[20]; 0482 time_t t{}; 0483 std::time(&t); 0484 struct tm tbuf {}; 0485 std::strftime(buffer, sizeof(buffer), m_format.c_str(), 0486 localtime_r(&t, &tbuf)); 0487 return buffer; 0488 } 0489 0490 /// format of the time stamp (see std::strftime for details) 0491 std::string m_format; 0492 }; 0493 0494 /// @brief decorate debug message with a thread ID 0495 /// 0496 /// The debug message is complemented with a thread ID. 0497 class ThreadOutputDecorator final : public OutputDecorator { 0498 public: 0499 /// @brief constructor 0500 /// 0501 /// @param [in] wrappee output print policy object to be wrapped 0502 explicit ThreadOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee) 0503 : OutputDecorator(std::move(wrappee)) {} 0504 0505 /// @brief flush the debug message to the destination stream 0506 /// 0507 /// @param [in] lvl debug level of debug message 0508 /// @param [in] input text of debug message 0509 /// 0510 /// This function prepends the thread ID to the debug message and then 0511 /// delegates the flushing of the whole message to its wrapped object. 0512 void flush(const Level& lvl, const std::string& input) override { 0513 std::ostringstream os; 0514 os << std::left << std::setw(20) << std::this_thread::get_id() << input; 0515 OutputDecorator::flush(lvl, os.str()); 0516 } 0517 0518 /// Make a copy of this print policy with a new name 0519 /// @param name the new name 0520 /// @return the copy 0521 std::unique_ptr<OutputPrintPolicy> clone( 0522 const std::string& name) const override { 0523 return std::make_unique<ThreadOutputDecorator>(m_wrappee->clone(name)); 0524 } 0525 }; 0526 0527 /// @brief decorate debug message with its debug level 0528 /// 0529 /// The debug message is complemented with its debug level. 0530 class LevelOutputDecorator final : public OutputDecorator { 0531 public: 0532 /// @brief constructor 0533 /// 0534 /// @param [in] wrappee output print policy object to be wrapped 0535 explicit LevelOutputDecorator(std::unique_ptr<OutputPrintPolicy> wrappee) 0536 : OutputDecorator(std::move(wrappee)) {} 0537 0538 /// @brief flush the debug message to the destination stream 0539 /// 0540 /// @param [in] lvl debug level of debug message 0541 /// @param [in] input text of debug message 0542 /// 0543 /// This function prepends the debug level to the debug message and then 0544 /// delegates the flushing of the whole message to its wrapped object. 0545 void flush(const Level& lvl, const std::string& input) override { 0546 std::ostringstream os; 0547 os << std::left << std::setw(10) << toString(lvl) << input; 0548 OutputDecorator::flush(lvl, os.str()); 0549 } 0550 0551 /// Make a copy of this print policy with a new name 0552 /// @param name the new name 0553 /// @return the copy 0554 std::unique_ptr<OutputPrintPolicy> clone( 0555 const std::string& name) const override { 0556 return std::make_unique<LevelOutputDecorator>(m_wrappee->clone(name)); 0557 } 0558 0559 private: 0560 /// @brief convert debug level to string 0561 /// 0562 /// @param [in] lvl debug level 0563 /// 0564 /// @return string representation of debug level 0565 std::string toString(const Level& lvl) const { 0566 static const char* const buffer[] = {"VERBOSE", "DEBUG", "INFO", 0567 "WARNING", "ERROR", "FATAL"}; 0568 return buffer[lvl]; 0569 } 0570 }; 0571 0572 /// @brief default print policy for debug messages 0573 /// 0574 /// This class allows to print debug messages without further modifications to 0575 /// a specified output stream. 0576 class DefaultPrintPolicy final : public OutputPrintPolicy { 0577 public: 0578 /// @brief constructor 0579 /// 0580 /// @param [in] out pointer to output stream object 0581 /// 0582 /// @pre @p out is non-zero 0583 explicit DefaultPrintPolicy(std::ostream* out = &std::cout) : m_out(out) {} 0584 0585 /// @brief flush the debug message to the destination stream 0586 /// 0587 /// @param [in] lvl debug level of debug message 0588 /// @param [in] input text of debug message 0589 void flush(const Level& lvl, const std::string& input) final { 0590 // Mutex to serialize access to std::cout 0591 static std::mutex s_stdoutMutex; 0592 std::unique_lock lock{s_stdoutMutex, 0593 std::defer_lock}; // prep empty, we might not need it 0594 0595 if (m_out == &std::cout) { 0596 lock.lock(); // lock only if we are printing to std::cout 0597 } 0598 0599 (*m_out) << input << std::endl; 0600 if (lvl >= getFailureThreshold()) { 0601 throw ThresholdFailure( 0602 "Previous debug message exceeds the " 0603 "ACTS_LOG_FAILURE_THRESHOLD=" + 0604 std::string{levelName(getFailureThreshold())} + 0605 " configuration, bailing out. See " 0606 "https://acts.readthedocs.io/en/latest/core/misc/" 0607 "logging.html#logging-thresholds"); 0608 } 0609 } 0610 0611 /// Fulfill @c OutputPrintPolicy interface. This policy doesn't actually have a 0612 /// name, so the assumption is that somewhere in the decorator hierarchy, 0613 /// there is something that returns a name without delegating to a wrappee, 0614 /// before reaching this overload. 0615 /// @note This method will throw an exception 0616 /// @return the name, but it never returns 0617 const std::string& name() const override { 0618 throw std::runtime_error{ 0619 "Default print policy doesn't have a name. Is there no named output in " 0620 "the decorator chain?"}; 0621 }; 0622 0623 /// Make a copy of this print policy with a new name 0624 /// @return the copy 0625 std::unique_ptr<OutputPrintPolicy> clone( 0626 const std::string& /*name*/) const override { 0627 return std::make_unique<DefaultPrintPolicy>(m_out); 0628 }; 0629 0630 private: 0631 /// pointer to destination output stream 0632 std::ostream* m_out; 0633 }; 0634 } // namespace Logging 0635 0636 /// @brief class for printing debug output 0637 /// 0638 /// This class provides the user interface for printing debug messages with 0639 /// different levels of severity. 0640 /// 0641 /// @ingroup Logging 0642 class Logger { 0643 public: 0644 /// @brief construct from output print and filter policy 0645 /// 0646 /// @param [in] pPrint policy for printing debug messages 0647 /// @param [in] pFilter policy for filtering debug messages 0648 Logger(std::unique_ptr<Logging::OutputPrintPolicy> pPrint, 0649 std::unique_ptr<Logging::OutputFilterPolicy> pFilter) 0650 : m_printPolicy(std::move(pPrint)), m_filterPolicy(std::move(pFilter)) {} 0651 0652 /// @brief decide whether a message with a given debug level has to be printed 0653 /// 0654 /// @param [in] lvl debug level of debug message 0655 /// 0656 /// @return @c true if debug message should be printed, otherwise @c false 0657 bool doPrint(const Logging::Level& lvl) const { 0658 return m_filterPolicy->doPrint(lvl); 0659 } 0660 0661 /// @brief log a debug message 0662 /// 0663 /// @param [in] lvl debug level of debug message 0664 /// @param [in] input text of debug message 0665 void log(const Logging::Level& lvl, const std::string& input) const { 0666 if (doPrint(lvl)) { 0667 m_printPolicy->flush(lvl, input); 0668 } 0669 } 0670 0671 /// Return the print policy for this logger 0672 /// @return the print policy 0673 const Logging::OutputPrintPolicy& printPolicy() const { 0674 return *m_printPolicy; 0675 } 0676 0677 /// Return the filter policy for this logger 0678 /// @return the filter policy 0679 const Logging::OutputFilterPolicy& filterPolicy() const { 0680 return *m_filterPolicy; 0681 } 0682 0683 /// Return the level of the filter policy of this logger 0684 /// @return the level 0685 Logging::Level level() const { return m_filterPolicy->level(); } 0686 0687 /// Return the name of the print policy of this logger 0688 /// @return the name 0689 const std::string& name() const { return m_printPolicy->name(); } 0690 0691 /// Make a copy of this logger, optionally changing the name or the level 0692 /// @param _name the optional new name 0693 /// @param _level the optional new level 0694 std::unique_ptr<Logger> clone( 0695 const std::optional<std::string>& _name = std::nullopt, 0696 const std::optional<Logging::Level>& _level = std::nullopt) const { 0697 return std::make_unique<Logger>( 0698 m_printPolicy->clone(_name.value_or(name())), 0699 m_filterPolicy->clone(_level.value_or(level()))); 0700 } 0701 0702 /// Make a copy of the logger, with a new level. Convenience function for 0703 /// if you only want to change the level but not the name. 0704 /// @param _level the new level 0705 /// @return the new logger 0706 std::unique_ptr<Logger> clone(Logging::Level _level) const { 0707 return clone(std::nullopt, _level); 0708 } 0709 0710 /// Make a copy of the logger, with a suffix added to the end of it's 0711 /// name. You can also optionally supply a new level 0712 /// @param suffix the suffix to add to the end of the name 0713 /// @param _level the optional new level 0714 std::unique_ptr<Logger> cloneWithSuffix( 0715 const std::string& suffix, 0716 std::optional<Logging::Level> _level = std::nullopt) const { 0717 return clone(name() + suffix, _level.value_or(level())); 0718 } 0719 0720 /// Helper function so a logger reference can be used as is with the logging 0721 /// macros 0722 const Logger& operator()() const { return *this; } 0723 0724 private: 0725 /// policy object for printing debug messages 0726 std::unique_ptr<Logging::OutputPrintPolicy> m_printPolicy; 0727 0728 /// policy object for filtering debug messages 0729 std::unique_ptr<Logging::OutputFilterPolicy> m_filterPolicy; 0730 }; 0731 0732 /// @brief get default debug output logger 0733 /// 0734 /// @param [in] name name of the logger instance 0735 /// @param [in] lvl debug threshold level 0736 /// @param [in] log_stream output stream used for printing debug messages 0737 /// 0738 /// This function returns a pointer to a Logger instance with the following 0739 /// decorations enabled: 0740 /// - time stamps 0741 /// - name of logging instance 0742 /// - debug level 0743 /// 0744 /// @return pointer to logging instance 0745 std::unique_ptr<const Logger> getDefaultLogger( 0746 const std::string& name, const Logging::Level& lvl, 0747 std::ostream* log_stream = &std::cout); 0748 0749 const Logger& getDummyLogger(); 0750 0751 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |