yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
log.cc
Go to the documentation of this file.
1#include "util/log.h"
2
3#include <chrono>
4#include <iomanip>
5#include <iostream>
6
7#include "core/features.h"
8
9namespace yaze {
10namespace util {
11
12// Helper function to convert LogLevel enum to a string representation.
13static const char* LogLevelToString(LogLevel level) {
14 switch (level) {
16 return "YAZE_DEBUG";
17 case LogLevel::INFO:
18 return "INFO";
20 return "WARN";
21 case LogLevel::ERROR:
22 return "ERROR";
23 case LogLevel::FATAL:
24 return "FATAL";
25 }
26 return "UNKN";
27}
28
29// --- LogManager Implementation ---
30
35
37 : min_level_(LogLevel::INFO), all_categories_enabled_(true) {}
38
40 if (log_stream_.is_open()) {
41 log_stream_.close();
42 }
43}
44
45void LogManager::configure(LogLevel level, const std::string& file_path,
46 const std::set<std::string>& categories) {
47 min_level_.store(level);
48
49 enabled_categories_.clear();
51
52 for (const auto& cat : categories) {
53 if (!cat.empty() && cat[0] == '-') {
54 if (cat.length() > 1) {
55 disabled_categories_.insert(cat.substr(1));
56 }
57 } else {
58 enabled_categories_.insert(cat);
59 }
60 }
61
62 if (enabled_categories_.empty()) {
63 all_categories_enabled_.store(true);
64 } else {
65 all_categories_enabled_.store(false);
66 }
67
68 // Log configuration for debugging
69 if (!enabled_categories_.empty() || !disabled_categories_.empty()) {
70 std::cerr << "Log filtering enabled:" << std::endl;
71 if (!enabled_categories_.empty()) {
72 std::string list;
73 for (const auto& c : enabled_categories_)
74 list += (list.empty() ? "" : ", ") + c;
75 std::cerr << " Allow: " << list << std::endl;
76 }
77 if (!disabled_categories_.empty()) {
78 std::string list;
79 for (const auto& c : disabled_categories_)
80 list += (list.empty() ? "" : ", ") + c;
81 std::cerr << " Block: " << list << std::endl;
82 }
83 }
84
85 // If a file path is provided, close any existing stream and open the new
86 // file.
87 if (!file_path.empty() && file_path != log_file_path_) {
88 if (log_stream_.is_open()) {
89 log_stream_.close();
90 }
91 // Open in append mode to preserve history.
92 log_stream_.open(file_path, std::ios::out | std::ios::app);
93 log_file_path_ = file_path;
94 }
95}
96
97void LogManager::log(LogLevel level, absl::string_view category,
98 absl::string_view message) {
99 // 1. Filter by log level.
100 if (level < min_level_.load()) {
101 return;
102 }
103
104 std::string cat_str(category);
105
106 // 2. Filter by disabled categories (Blocklist).
107 if (disabled_categories_.find(cat_str) != disabled_categories_.end()) {
108 return;
109 }
110
111 // 3. Filter by enabled categories (Allowlist).
112 // If allowlist is active (not empty), we must match it.
113 if (!all_categories_enabled_.load()) {
114 if (enabled_categories_.find(cat_str) ==
115 enabled_categories_.end()) {
116 return;
117 }
118 }
119
120 // 3. Format the complete log message.
121 // [HH:MM:SS.ms] [LEVEL] [category] message
122 auto now = std::chrono::system_clock::now();
123 auto now_tt = std::chrono::system_clock::to_time_t(now);
124 auto now_tm = *std::localtime(&now_tt);
125 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
126 now.time_since_epoch()) %
127 1000;
128
129 std::string final_message = absl::StrFormat(
130 "[%02d:%02d:%02d.%03d] [%-5s] [%s] %s\n", now_tm.tm_hour, now_tm.tm_min,
131 now_tm.tm_sec, ms.count(), LogLevelToString(level), category, message);
132
133 // 4. Write to the configured sink (file and/or stderr).
134 if (log_stream_.is_open()) {
135 log_stream_ << final_message;
136 log_stream_.flush(); // Ensure immediate write for debugging.
137 }
138
139 // Also write to stderr if no file is open OR if console logging is enabled
141 std::cerr << final_message;
142 }
143
144 // 5. Abort on FATAL error.
145 if (level == LogLevel::FATAL) {
146 std::abort();
147 }
148}
149
150} // namespace util
151} // namespace yaze
static Flags & get()
Definition features.h:92
A singleton that manages all logging configuration and output.
Definition log.h:33
std::ofstream log_stream_
Definition log.h:87
static LogManager & instance()
Definition log.cc:31
void configure(LogLevel level, const std::string &file_path, const std::set< std::string > &categories)
Configures the logging system.
Definition log.cc:45
std::string log_file_path_
Definition log.h:88
std::atomic< bool > all_categories_enabled_
Definition log.h:84
std::atomic< LogLevel > min_level_
Definition log.h:81
std::set< std::string > disabled_categories_
Definition log.h:83
std::set< std::string > enabled_categories_
Definition log.h:82
void log(LogLevel level, absl::string_view category, absl::string_view message)
The primary logging function.
Definition log.cc:97
const char * LogLevelToString(yaze::util::LogLevel level)
Definition main.cc:143
LogLevel
Defines the severity levels for log messages. This allows for filtering messages based on their impor...
Definition log.h:23