![]() |
|
|||
File indexing completed on 2025-09-15 08:55:05
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file corecel/io/Logger.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include <string> 0010 #include <utility> 0011 0012 #include "corecel/Config.hh" 0013 0014 #include "LoggerTypes.hh" 0015 0016 #include "detail/LoggerMessage.hh" // IWYU pragma: export 0017 #if CELER_DEVICE_COMPILE 0018 # include "detail/NullLoggerMessage.hh" // IWYU pragma: export 0019 #endif 0020 0021 //---------------------------------------------------------------------------// 0022 // MACROS 0023 //---------------------------------------------------------------------------// 0024 //! Inject the source code provenance (current file and line) 0025 #define CELER_CODE_PROVENANCE \ 0026 ::celeritas::LogProvenance \ 0027 { \ 0028 __FILE__, __LINE__ \ 0029 } 0030 0031 /*! 0032 * \def CELER_LOG 0033 * 0034 * Return a LogMessage object for streaming into at the given level. The 0035 * regular \c CELER_LOG call is for code paths that happen uniformly in 0036 * parallel, approximately the same message from every thread and task. 0037 * 0038 * The logger will only format and print messages. It is not responsible 0039 * for cleaning up the state or exiting an app. 0040 * 0041 * \code 0042 CELER_LOG(debug) << "Don't print this in general"; 0043 CELER_LOG(warning) << "You may want to reconsider your life choices"; 0044 CELER_LOG(critical) << "Caught a fatal exception: " << e.what(); 0045 * \endcode 0046 */ 0047 #define CELER_LOG(LEVEL) \ 0048 ::celeritas::world_logger()(CELER_CODE_PROVENANCE, \ 0049 ::celeritas::LogLevel::LEVEL) 0050 0051 /*! 0052 * \def CELER_LOG_LOCAL 0053 * 0054 * Like \c CELER_LOG but for code paths that may only happen on a single 0055 * process or thread. Use sparingly because this can be very verbose. This is 0056 * typically used only for error messages coming from an a event or 0057 * track at runtime. 0058 */ 0059 #define CELER_LOG_LOCAL(LEVEL) \ 0060 ::celeritas::self_logger()(CELER_CODE_PROVENANCE, \ 0061 ::celeritas::LogLevel::LEVEL) 0062 0063 // Allow CELER_LOG to be present (but ignored) in device code 0064 #if CELER_DEVICE_COMPILE 0065 # undef CELER_LOG 0066 # define CELER_LOG(LEVEL) ::celeritas::detail::NullLoggerMessage() 0067 # undef CELER_LOG_LOCAL 0068 # define CELER_LOG_LOCAL(LEVEL) ::celeritas::detail::NullLoggerMessage() 0069 #endif 0070 0071 namespace celeritas 0072 { 0073 class MpiCommunicator; 0074 0075 //---------------------------------------------------------------------------// 0076 /*! 0077 * Create a log message to be printed based on output/verbosity sttings. 0078 * 0079 * This should generally be called by the \c world_logger and \c 0080 * self_logger functions below. The call \c operator() returns an object that 0081 * should be streamed into in order to create a log message. 0082 * 0083 * This object \em is assignable, so to replace the default log handler with a 0084 * different one, you can call \code 0085 world_logger = Logger(my_handler); 0086 * \endcode 0087 * 0088 * When using with MPI, the \c world_logger global objects are different on 0089 * each process: rank 0 will have a handler that outputs to screen, and the 0090 * other ranks will have a "null" handler that suppresses all log output. 0091 * 0092 * \todo For v1.0, replace the back-end with \c spdlog to reduce maintenance 0093 * burden and improve flexibility. 0094 */ 0095 class Logger 0096 { 0097 public: 0098 //!@{ 0099 //! \name Type aliases 0100 using Message = detail::LoggerMessage; 0101 //!@} 0102 0103 public: 0104 //! Get the default log level 0105 static constexpr LogLevel default_level() { return LogLevel::status; } 0106 0107 // Create a logger from a handle and level environment variable 0108 static Logger from_handle_env(LogHandler&& handle, std::string const& key); 0109 0110 // Construct from an output handle 0111 explicit Logger(LogHandler&& handle); 0112 0113 // Create a logger that flushes its contents when it destructs 0114 inline Message operator()(LogProvenance&& prov, LogLevel lev); 0115 0116 //! Set the minimum logging verbosity 0117 void level(LogLevel lev) { min_level_ = lev; } 0118 0119 //! Get the current logging verbosity 0120 LogLevel level() const { return min_level_; } 0121 0122 private: 0123 LogHandler handle_; 0124 LogLevel min_level_{default_level()}; 0125 }; 0126 0127 //---------------------------------------------------------------------------// 0128 // INLINE DEFINITIONS 0129 //---------------------------------------------------------------------------// 0130 /*! 0131 * Create a logger that flushes its contents when it destructs. 0132 * 0133 * It's assumed that log messages will be relatively unlikely (and expensive 0134 * anyway), so we mark as \c CELER_UNLIKELY to optimize for the no-logging 0135 * case. 0136 */ 0137 auto Logger::operator()(LogProvenance&& prov, LogLevel lev) -> Message 0138 { 0139 LogHandler* handle = nullptr; 0140 if (CELER_UNLIKELY(handle_ && lev >= min_level_)) 0141 { 0142 handle = &handle_; 0143 } 0144 return {handle, std::move(prov), lev}; 0145 } 0146 0147 //---------------------------------------------------------------------------// 0148 // FREE FUNCTIONS 0149 //---------------------------------------------------------------------------// 0150 // Get the log level from an environment variable 0151 LogLevel log_level_from_env(std::string const&, LogLevel default_lev); 0152 LogLevel log_level_from_env(std::string const&); 0153 0154 // Create loggers with reasonable default behaviors. 0155 Logger make_default_world_logger(); 0156 Logger make_default_self_logger(); 0157 0158 // Parallel logger (print only on "main" process) 0159 Logger& world_logger(); 0160 0161 // Serial logger (print on *every* process) 0162 Logger& self_logger(); 0163 0164 //---------------------------------------------------------------------------// 0165 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |