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 "gutsConventions.h"
5#include "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 __FUNCSIG__ + std::string(" > ")
31#else
32#define FUNCTION_NAME __func__ + std::string(" > ") // fallback
33#endif
34
44#define SFUNCTION_NAME __func__ + std::string(" > ") // Always portable and standard since C++11
45
46
60
85{
86public:
102 explicit GLogger(const std::shared_ptr<GOptions>& gopts, const std::string& cname, const std::string& lname = "")
103 : class_name(cname), logger_name(lname), log_counter{0} {
104 // Resolve the runtime policy for this subsystem name from the global options.
105 verbosity_level = gopts->getVerbosityFor(logger_name);
106 debug_level = gopts->getDebugFor(logger_name);
107
108 // Optional lifetime trace to help identify logger ownership and construction order.
109 debug(CONSTRUCTOR, logger_name, " logger");
110 }
111
122 GLogger() = default;
123
130 ~GLogger() { debug(DESTRUCTOR, logger_name, " logger"); }
131
150 template <typename... Args>
151 void debug(debug_type type, Args&&... args) const {
152 if (debug_level == 0) return; // Debug disabled for this logger instance.
153
154 std::ostringstream oss;
155 (oss << ... << std::forward<Args>(args));
156
157 switch (type) {
158 case NORMAL:
159 G4cout << KCYN << header_string() << "DEBUG: " << oss.str() << RST << G4endl;
160 break;
161 case CONSTRUCTOR:
162 G4cout << KCYN << header_string() << "DEBUG: " <<
163 CONSTRUCTORLOG << " " << oss.str() << " " << CONSTRUCTORLOG << RST << G4endl;
164 break;
165 case DESTRUCTOR:
166 G4cout << KCYN << header_string() << "DEBUG: " <<
167 DESTRUCTORLOG << " " << oss.str() << " " << DESTRUCTORLOG << RST << G4endl;
168 break;
169 }
170 }
171
187 template <typename... Args>
188 void info(int level, Args&&... args) const {
189 // Validate the requested verbosity level early so callers fail fast with a clear message.
190 if (level != 0 && level != 1 && level != 2) {
191 G4cerr << FATALERRORL << header_string() << GWARNING << " Invalid verbosity level requested: " << level <<
192 RST << G4endl;
194 }
195
196 // Apply the gating rule associated with the requested level.
197 if (level == 0 || (level == 1 && verbosity_level > 0) || (level == 2 && verbosity_level > 1)) {
198 std::ostringstream oss;
199 (oss << ... << std::forward<Args>(args));
200 G4cout << header_string() << "INFO L" << level << ": " << oss.str() << G4endl;
201 }
202 }
203
213 template <typename... Args>
214 void info(Args&&... args) const { info(0, std::forward<Args>(args)...); }
215
227 template <typename... Args>
228 void warning(Args&&... args) const {
229 std::ostringstream oss;
230 (oss << ... << std::forward<Args>(args));
231 G4cout << KYEL << header_string() << GWARNING << KYEL << oss.str() << RST << G4endl;
232 }
233
249 template <typename... Args>
250 [[noreturn]] void error(int exit_code, Args&&... args) const {
251 std::ostringstream oss;
252 (oss << ... << std::forward<Args>(args));
253 G4cerr << FATALERRORL << header_string() << KRED << oss.str() << RST << G4endl;
254 G4cerr << FATALERRORL << header_string() << KRED << "Exit Code: " << exit_code << RST << G4endl;
255 std::exit(exit_code);
256 }
257
267 template <typename... Args>
268 void critical(Args&&... args) const {
269 std::ostringstream oss;
270 (oss << ... << std::forward<Args>(args));
271 G4cout << KBOLD << header_string() << RST << oss.str() << G4endl;
272 }
273
282 [[nodiscard]] std::string get_class_name() const { return class_name; }
283
284private:
285 std::string class_name;
286 std::string logger_name;
288 int verbosity_level{};
289 int debug_level{};
290
291 mutable std::atomic<int> log_counter{};
292
304 [[nodiscard]] std::string header_string() const {
305 ++log_counter; // Increment first so the first emitted message is "1" rather than "0".
306 return " [ " + logger_name + " - " + std::to_string(log_counter.load()) + " ] ";
307 }
308};
Handles structured logging with verbosity and debug levels.
Definition glogger.h:85
void warning(Args &&... args) const
Logs a warning message.
Definition glogger.h:228
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:102
void debug(debug_type type, Args &&... args) const
Logs a debug message if the debug level is nonzero.
Definition glogger.h:151
GLogger()=default
Default constructor.
void info(Args &&... args) const
Convenience overload of info() that defaults to level 0.
Definition glogger.h:214
std::string get_class_name() const
Returns the caller-provided class name associated with this logger instance.
Definition glogger.h:282
~GLogger()
Destructor.
Definition glogger.h:130
void critical(Args &&... args) const
Logs a critical message.
Definition glogger.h:268
void info(int level, Args &&... args) const
Logs an informational message, optionally gated by verbosity level.
Definition glogger.h:188
void error(int exit_code, Args &&... args) const
Logs an error message and terminates the process.
Definition glogger.h:250
debug_type
Classifies debug messages by intent.
Definition glogger.h:59
@ CONSTRUCTOR
Definition glogger.h:59
@ NORMAL
Definition glogger.h:59
@ DESTRUCTOR
Definition glogger.h:59
#define EC_WRONG_VERBOSITY_LEVEL
#define GWARNING
#define KCYN
#define DESTRUCTORLOG
#define CONSTRUCTORLOG
#define KRED
#define KBOLD
#define KYEL
#define FATALERRORL
#define RST