|
|
|||
File indexing completed on 2026-11-03 10:19:17
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 <utility> 0010 0011 #include "corecel/Macros.hh" 0012 #include "corecel/io/detail/NullLoggerMessage.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 0056 * should be used for error messages from an 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::null_log_message() 0067 # undef CELER_LOG_LOCAL 0068 # define CELER_LOG_LOCAL(LEVEL) ::celeritas::null_log_message() 0069 #endif 0070 0071 namespace celeritas 0072 { 0073 //---------------------------------------------------------------------------// 0074 /*! 0075 * Create a log message to be printed based on output/verbosity settings. 0076 * 0077 * This should generally be called by the \c world_logger and \c 0078 * self_logger functions below. The call \c operator() returns an object that 0079 * should be streamed into in order to create a log message. 0080 * 0081 * This object \em is assignable, so to replace the default log handler with a 0082 * different one, you can call \code 0083 world_logger = Logger(my_handler); 0084 * \endcode 0085 * 0086 * When using with MPI, set a null handle to \c world_logger on all processes 0087 * other than rank 0, or use \c LocalMpiHandler on each process. 0088 * 0089 * \todo Replace the back-end with \c spdlog to reduce maintenance 0090 * burden and improve flexibility. 0091 */ 0092 class Logger 0093 { 0094 public: 0095 //!@{ 0096 //! \name Type aliases 0097 using Message = detail::LoggerMessage; 0098 //!@} 0099 0100 public: 0101 //! Get the default log level 0102 static constexpr LogLevel default_level() { return LogLevel::status; } 0103 0104 // Construct a null logger 0105 Logger() = default; 0106 0107 // Construct a logger with handle and default level 0108 explicit Logger(LogHandler&& handle); 0109 0110 // Construct a logger with handle and level 0111 Logger(LogHandler&& handle, LogLevel min_lev); 0112 0113 // Create a log message that flushes its contents when it destructs 0114 inline Message operator()(LogProvenance&& prov, LogLevel lev) const; 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 //! Access the log handle 0123 LogHandler const& handle() const { return handle_; } 0124 0125 //! Set the log handle (null disables logger) 0126 void handle(LogHandler&& handle) { handle_ = std::move(handle); } 0127 0128 private: 0129 LogHandler handle_; 0130 LogLevel min_level_{default_level()}; 0131 }; 0132 0133 //---------------------------------------------------------------------------// 0134 // INLINE DEFINITIONS 0135 //---------------------------------------------------------------------------// 0136 /*! 0137 * Create a logger that flushes its contents when it destructs. 0138 * 0139 * It's assumed that log messages will be relatively unlikely (and expensive 0140 * anyway), so we mark as \c CELER_UNLIKELY to optimize for the no-logging 0141 * case. 0142 */ 0143 auto Logger::operator()(LogProvenance&& prov, LogLevel lev) const -> Message 0144 { 0145 LogHandler const* handle = nullptr; 0146 if (CELER_UNLIKELY(handle_ && lev >= min_level_)) 0147 { 0148 handle = &handle_; 0149 } 0150 return Message{handle, std::move(prov), lev}; 0151 } 0152 0153 //---------------------------------------------------------------------------// 0154 // FREE FUNCTIONS 0155 //---------------------------------------------------------------------------// 0156 0157 // Parallel logger (print only on "main" process using CELER_LOG) 0158 Logger& world_logger(); 0159 0160 // Serial logger (print on *every* process using CELER_LOG_LOCAL) 0161 Logger& self_logger(); 0162 0163 //! Return a stream-like object that ignores everything (used for device code) 0164 CELER_CONSTEXPR_FUNCTION auto null_log_message() 0165 { 0166 return detail::NullLoggerMessage(); 0167 } 0168 0169 //---------------------------------------------------------------------------// 0170 } // 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 |
|