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