glogging
Loading...
Searching...
No Matches
glogger.h
Go to the documentation of this file.
1#pragma once
2
3// Color conventions and logging macros
4#include <gemc/guts/gutsConventions.h>
5#include <gemc/goptions/goptions.h>
6
7// Geant4
8#include "G4UIsession.hh"
9#include <atomic>
10#include <string>
11#include <sstream>
12#include <utility>
13
14
27#if defined(__clang__) || defined(__GNUC__)
28#define FUNCTION_NAME std::string(__PRETTY_FUNCTION__) + std::string(" > ")
29#elif defined(_MSC_VER)
30#define FUNCTION_NAME std::string(__FUNCSIG__) + std::string(" > ")
31#else
32#define FUNCTION_NAME std::string(__func__) + std::string(" > ")
33#endif
34
46#define SFUNCTION_NAME std::string(__func__) + std::string(" > ")
47
61
86{
87public:
103 explicit GLogger(const std::shared_ptr<GOptions>& gopts, const std::string& cname, const std::string& lname = "")
104 : class_name(cname), logger_name(lname), log_counter{0} {
105 // Resolve the runtime policy for this subsystem name from the global options.
106 verbosity_level = gopts->getVerbosityFor(logger_name);
107 debug_level = gopts->getDebugFor(logger_name);
108
109 // Optional lifetime trace to help identify logger ownership and construction order.
110 debug(CONSTRUCTOR, logger_name, " logger");
111 }
112
123 GLogger() = default;
124
131 ~GLogger() { debug(DESTRUCTOR, logger_name, " logger"); }
132
151 template <typename... Args>
152 void debug(debug_type type, Args&&... args) const {
153 if (debug_level == 0) return; // Debug disabled for this logger instance.
154
155 std::ostringstream oss;
156 (oss << ... << std::forward<Args>(args));
157
158 switch (type) {
159 case NORMAL:
160 G4cout << guts::KCYN << header_string() << "DEBUG: " << oss.str() << guts::RST << G4endl;
161 break;
162 case CONSTRUCTOR:
163 G4cout << guts::KCYN << header_string() << "DEBUG: " <<
164 guts::CONSTRUCTORLOG << " " << oss.str() << " " << guts::CONSTRUCTORLOG << guts::RST << G4endl;
165 break;
166 case DESTRUCTOR:
167 G4cout << guts::KCYN << header_string() << "DEBUG: " <<
168 guts::DESTRUCTORLOG << " " << oss.str() << " " << guts::DESTRUCTORLOG << guts::RST << G4endl;
169 break;
170 }
171 }
172
188 template <typename... Args>
189 void info(int level, Args&&... args) const {
190 // Validate the requested verbosity level early so callers fail fast with a clear message.
191 if (level != 0 && level != 1 && level != 2) {
192 G4cerr << guts::FATALERRORL << header_string() << guts::GWARNING
193 << " Invalid verbosity level requested: " << level << guts::RST << G4endl;
195 }
196
197 // Apply the gating rule associated with the requested level.
198 if (level == 0 || (level == 1 && verbosity_level > 0) || (level == 2 && verbosity_level > 1)) {
199 std::ostringstream oss;
200 (oss << ... << std::forward<Args>(args));
201 G4cout << header_string() << "INFO L" << level << ": " << oss.str() << G4endl;
202 }
203 }
204
214 template <typename... Args>
215 void info(Args&&... args) const { info(0, std::forward<Args>(args)...); }
216
228 template <typename... Args>
229 void warning(Args&&... args) const {
230 std::ostringstream oss;
231 (oss << ... << std::forward<Args>(args));
232 G4cout << guts::KYEL << header_string() << guts::GWARNING << guts::KYEL << oss.str() << guts::RST << G4endl;
233 }
234
250 template <typename... Args>
251 [[noreturn]] void error(int exit_code, Args&&... args) const {
252 std::ostringstream oss;
253 (oss << ... << std::forward<Args>(args));
254 G4cerr << guts::FATALERRORL << header_string() << guts::KRED << oss.str() << guts::RST << G4endl;
255 G4cerr << guts::FATALERRORL << header_string() << guts::KRED << "Exit Code: " << exit_code << guts::RST
256 << G4endl;
257 std::exit(exit_code);
258 }
259
269 template <typename... Args>
270 void critical(Args&&... args) const {
271 std::ostringstream oss;
272 (oss << ... << std::forward<Args>(args));
273 G4cout << guts::KBOLD << header_string() << guts::RST << oss.str() << G4endl;
274 }
275
284 [[nodiscard]] std::string get_class_name() const { return class_name; }
285
286private:
287 std::string class_name;
288 std::string logger_name;
290 int verbosity_level{};
291 int debug_level{};
292
293 mutable std::atomic<int> log_counter{};
294
306 [[nodiscard]] std::string header_string() const {
307 ++log_counter; // Increment first so the first emitted message is "1" rather than "0".
308 return " [ " + logger_name + " - " + std::to_string(log_counter.load()) + " ] ";
309 }
310};
void warning(Args &&... args) const
Logs a warning message.
Definition glogger.h:229
GLogger(const std::shared_ptr< GOptions > &gopts, const std::string &cname, const std::string &lname="")
Constructs a GLogger instance and resolves its runtime configuration.
Definition glogger.h:103
void debug(debug_type type, Args &&... args) const
Logs a debug message if the debug level is nonzero.
Definition glogger.h:152
GLogger()=default
Default constructor.
void info(Args &&... args) const
Convenience overload of info() that defaults to level 0.
Definition glogger.h:215
std::string get_class_name() const
Returns the caller-provided class name associated with this logger instance.
Definition glogger.h:284
~GLogger()
Destructor.
Definition glogger.h:131
void critical(Args &&... args) const
Logs a critical message.
Definition glogger.h:270
void info(int level, Args &&... args) const
Logs an informational message, optionally gated by verbosity level.
Definition glogger.h:189
void error(int exit_code, Args &&... args) const
Logs an error message and terminates the process.
Definition glogger.h:251
debug_type
Classifies debug messages by intent.
Definition glogger.h:60
@ CONSTRUCTOR
Definition glogger.h:60
@ NORMAL
Definition glogger.h:60
@ DESTRUCTOR
Definition glogger.h:60
constexpr int EC_WRONG_VERBOSITY_LEVEL
constexpr char RST[]
constexpr char FATALERRORL[]
constexpr char GWARNING[]
constexpr char DESTRUCTORLOG[]
constexpr char CONSTRUCTORLOG[]
constexpr char KCYN[]
constexpr char KRED[]
constexpr char KYEL[]
constexpr char KBOLD[]