|
||||
File indexing completed on 2025-01-18 09:54:48
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2020-2024 UT-Battelle, LLC, and other Celeritas developers. 0003 // See the top-level COPYRIGHT file for details. 0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0005 //---------------------------------------------------------------------------// 0006 //! \file corecel/io/Logger.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <string> 0011 #include <utility> 0012 0013 #include "LoggerTypes.hh" 0014 0015 #include "detail/LoggerMessage.hh" // IWYU pragma: export 0016 0017 //---------------------------------------------------------------------------// 0018 // MACROS 0019 //---------------------------------------------------------------------------// 0020 //! Inject the source code provenance (current file and line) 0021 #define CELER_CODE_PROVENANCE \ 0022 ::celeritas::LogProvenance \ 0023 { \ 0024 __FILE__, __LINE__ \ 0025 } 0026 0027 /*! 0028 * \def CELER_LOG 0029 * 0030 * Return a LogMessage object for streaming into at the given level. The 0031 * regular \c CELER_LOG call is for code paths that happen uniformly in 0032 * parallel. 0033 * 0034 * The logger will only format and print messages. It is not responsible 0035 * for cleaning up the state or exiting an app. 0036 * 0037 * \code 0038 CELER_LOG(debug) << "Don't print this in general"; 0039 CELER_LOG(warning) << "You may want to reconsider your life choices"; 0040 CELER_LOG(critical) << "Caught a fatal exception: " << e.what(); 0041 * \endcode 0042 */ 0043 #define CELER_LOG(LEVEL) \ 0044 ::celeritas::world_logger()(CELER_CODE_PROVENANCE, \ 0045 ::celeritas::LogLevel::LEVEL) 0046 0047 //---------------------------------------------------------------------------// 0048 /*! 0049 * \def CELER_LOG_LOCAL 0050 * 0051 * Like \c CELER_LOG but for code paths that may only happen on a single 0052 * process. Use sparingly. 0053 */ 0054 #define CELER_LOG_LOCAL(LEVEL) \ 0055 ::celeritas::self_logger()(CELER_CODE_PROVENANCE, \ 0056 ::celeritas::LogLevel::LEVEL) 0057 0058 namespace celeritas 0059 { 0060 class MpiCommunicator; 0061 0062 //---------------------------------------------------------------------------// 0063 /*! 0064 * Manage logging in serial and parallel. 0065 * 0066 * This should generally be called by the \c world_logger and \c 0067 * self_logger functions below. The call \c operator() returns an object that 0068 * should be streamed into in order to create a log message. 0069 * 0070 * This object \em is assignable, so to replace the default log handler with a 0071 * different one, you can call \code 0072 world_logger = Logger(celeritas::comm_world(), my_handler); 0073 * \endcode 0074 */ 0075 class Logger 0076 { 0077 public: 0078 //!@{ 0079 //! \name Type aliases 0080 using Message = detail::LoggerMessage; 0081 //!@} 0082 0083 public: 0084 //! Get the default log level 0085 static constexpr LogLevel default_level() { return LogLevel::status; } 0086 0087 // Construct with default celeritas communicator 0088 explicit Logger(LogHandler handle); 0089 0090 // Construct with custom communicator (only rank zero is active) and 0091 // handler 0092 Logger(MpiCommunicator const& comm, LogHandler handle); 0093 0094 // Create a logger that flushes its contents when it destructs 0095 inline Message operator()(LogProvenance&& prov, LogLevel lev); 0096 0097 //! Set the minimum logging verbosity 0098 void level(LogLevel lev) { min_level_ = lev; } 0099 0100 //! Get the current logging verbosity 0101 LogLevel level() const { return min_level_; } 0102 0103 private: 0104 LogHandler handle_; 0105 LogLevel min_level_{default_level()}; 0106 }; 0107 0108 //---------------------------------------------------------------------------// 0109 // INLINE DEFINITIONS 0110 //---------------------------------------------------------------------------// 0111 /*! 0112 * Create a logger that flushes its contents when it destructs. 0113 * 0114 * It's assumed that log messages will be relatively unlikely (and expensive 0115 * anyway), so we mark as \c CELER_UNLIKELY to optimize for the no-logging 0116 * case. 0117 */ 0118 auto Logger::operator()(LogProvenance&& prov, LogLevel lev) -> Message 0119 { 0120 LogHandler* handle = nullptr; 0121 if (CELER_UNLIKELY(handle_ && lev >= min_level_)) 0122 { 0123 handle = &handle_; 0124 } 0125 return {handle, std::move(prov), lev}; 0126 } 0127 0128 //---------------------------------------------------------------------------// 0129 // FREE FUNCTIONS 0130 //---------------------------------------------------------------------------// 0131 // Get the log level from an environment variable 0132 LogLevel log_level_from_env(std::string const&); 0133 0134 // Create loggers with reasonable default behaviors. 0135 Logger make_default_world_logger(); 0136 Logger make_default_self_logger(); 0137 0138 // Parallel logger (print only on "main" process) 0139 Logger& world_logger(); 0140 0141 // Serial logger (print on *every* process) 0142 Logger& self_logger(); 0143 0144 //---------------------------------------------------------------------------// 0145 } // 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 |