yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
log.h
Go to the documentation of this file.
1#ifndef YAZE_UTIL_LOG_H
2#define YAZE_UTIL_LOG_H
3
4#include <atomic>
5#include <fstream>
6#include <functional>
7#include <set>
8#include <string>
9#include <utility>
10
11#include "absl/strings/str_cat.h"
12#include "absl/strings/str_format.h"
13#include "absl/strings/string_view.h"
14#include "core/features.h"
15
16namespace yaze {
17namespace util {
18
25
35 public:
36 // Singleton access
37 static LogManager& instance();
38
39 // Deleted constructors for singleton pattern
40 LogManager(const LogManager&) = delete;
41 void operator=(const LogManager&) = delete;
42
50 void configure(LogLevel level, const std::string& file_path,
51 const std::set<std::string>& categories);
52
59 void log(LogLevel level, absl::string_view category,
60 absl::string_view message);
61
66 void Flush();
67
71 bool ShouldLog(LogLevel level) const {
72 return level >= min_level_.load(std::memory_order_relaxed);
73 }
74
78 bool ShouldLog(LogLevel level, absl::string_view category) const;
79
83 void SetLogLevel(LogLevel level) { min_level_.store(level); }
84 LogLevel GetLogLevel() const { return min_level_.load(); }
85
91 bool IsDebugEnabled() const {
92 return min_level_.load() == LogLevel::YAZE_DEBUG;
93 }
94
95 private:
96 LogManager();
98
99 // Configuration state
100 std::atomic<LogLevel> min_level_;
101 // Transparent comparator: lookup with absl::string_view without allocating.
102 std::set<std::string, std::less<>> enabled_categories_;
103 std::set<std::string, std::less<>> disabled_categories_;
104 std::atomic<bool> all_categories_enabled_;
105
106 // Output sink
107 std::ofstream log_stream_;
108 std::string log_file_path_;
109};
110
111// --- Public Logging Macros ---
112// These macros provide a convenient and efficient API for logging.
113// The `do-while(0)` loop ensures they behave like a single statement.
114// The level check avoids the cost of string formatting if the message won't be
115// logged.
116
117// `category` is bound once, so the guard and the log call never evaluate the
118// caller's expression twice. It is bound with `auto&&` rather than
119// absl::string_view: callers may pass a std::string temporary (for example
120// absl::StrCat(...)), and a string_view would dangle for the rest of the block.
121// The formatted message is built only when the message will be emitted, so
122// arguments with side effects do not run for a filtered level or category.
123#define YAZE_LOG_IMPL(level, category, format, ...) \
124 do { \
125 auto&& yaze_log_category_ = (category); \
126 auto& yaze_log_manager_ = ::yaze::util::LogManager::instance(); \
127 if (yaze_log_manager_.ShouldLog(level, yaze_log_category_)) { \
128 yaze_log_manager_.log(level, yaze_log_category_, \
129 absl::StrFormat(format, ##__VA_ARGS__)); \
130 } \
131 } while (0)
132
133#define LOG_DEBUG(category, format, ...) \
134 YAZE_LOG_IMPL(yaze::util::LogLevel::YAZE_DEBUG, category, format, \
135 ##__VA_ARGS__)
136#define LOG_INFO(category, format, ...) \
137 YAZE_LOG_IMPL(yaze::util::LogLevel::INFO, category, format, ##__VA_ARGS__)
138#define LOG_WARN(category, format, ...) \
139 YAZE_LOG_IMPL(yaze::util::LogLevel::WARNING, category, format, ##__VA_ARGS__)
140#define LOG_ERROR(category, format, ...) \
141 YAZE_LOG_IMPL(yaze::util::LogLevel::ERROR, category, format, ##__VA_ARGS__)
142#define LOG_FATAL(category, format, ...) \
143 YAZE_LOG_IMPL(yaze::util::LogLevel::FATAL, category, format, ##__VA_ARGS__)
144
145template <typename... Args>
146inline void logf(const absl::FormatSpec<Args...>& format, Args&&... args) {
148 LogLevel::INFO, "General",
149 absl::StrFormat(format, std::forward<Args>(args)...));
150}
151
152inline void logf(absl::string_view message) {
153 LogManager::instance().log(LogLevel::INFO, "General", message);
154}
155
156} // namespace util
157} // namespace yaze
158
159#endif // YAZE_UTIL_LOG_H
A singleton that manages all logging configuration and output.
Definition log.h:34
std::ofstream log_stream_
Definition log.h:107
std::set< std::string, std::less<> > enabled_categories_
Definition log.h:102
static LogManager & instance()
Definition log.cc:66
void configure(LogLevel level, const std::string &file_path, const std::set< std::string > &categories)
Configures the logging system.
Definition log.cc:80
std::string log_file_path_
Definition log.h:108
void DisableDebugLogging()
Definition log.h:90
std::set< std::string, std::less<> > disabled_categories_
Definition log.h:103
void operator=(const LogManager &)=delete
void EnableDebugLogging()
Toggle debug logging on/off at runtime.
Definition log.h:89
LogLevel GetLogLevel() const
Definition log.h:84
std::atomic< bool > all_categories_enabled_
Definition log.h:104
std::atomic< LogLevel > min_level_
Definition log.h:100
void Flush()
Writes buffered file output now. log() flushes warnings and errors at once but batches other lines fo...
Definition log.cc:139
bool ShouldLog(LogLevel level) const
Fast inline check if logging is enabled for the given level.
Definition log.h:71
void SetLogLevel(LogLevel level)
Runtime log level control (for debug card)
Definition log.h:83
void log(LogLevel level, absl::string_view category, absl::string_view message)
The primary logging function.
Definition log.cc:173
LogManager(const LogManager &)=delete
bool IsDebugEnabled() const
Definition log.h:91
LogLevel
Defines the severity levels for log messages. This allows for filtering messages based on their impor...
Definition log.h:24
void logf(const absl::FormatSpec< Args... > &format, Args &&... args)
Definition log.h:146