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 "absl/strings/str_format.h"
8#include "core/features.h"
9
10namespace yaze {
11namespace util {
12
13// Helper function to convert LogLevel enum to a string representation.
14static const char* LogLevelToString(LogLevel level) {
15 switch (level) {
17 return "YAZE_DEBUG";
18 case LogLevel::INFO:
19 return "INFO";
21 return "WARN";
22 case LogLevel::ERROR:
23 return "ERROR";
24 case LogLevel::FATAL:
25 return "FATAL";
26 }
27 return "UNKN";
28}
29
30// --- LogManager Implementation ---
31
36
38 : min_level_(LogLevel::INFO), all_categories_enabled_(true) {}
39
41 if (log_stream_.is_open()) {
42 log_stream_.close();
43 }
44}
45
46void LogManager::configure(LogLevel level, const std::string& file_path,
47 const std::set<std::string>& categories) {
48 min_level_.store(level);
49
50 enabled_categories_.clear();
52
53 for (const auto& cat : categories) {
54 if (!cat.empty() && cat[0] == '-') {
55 if (cat.length() > 1) {
56 disabled_categories_.insert(cat.substr(1));
57 }
58 } else {
59 enabled_categories_.insert(cat);
60 }
61 }
62
63 if (enabled_categories_.empty()) {
64 all_categories_enabled_.store(true);
65 } else {
66 all_categories_enabled_.store(false);
67 }
68
69 // Log configuration for debugging
70 if (!enabled_categories_.empty() || !disabled_categories_.empty()) {
71 std::cerr << "Log filtering enabled:" << std::endl;
72 if (!enabled_categories_.empty()) {
73 std::string list;
74 for (const auto& c : enabled_categories_)
75 list += (list.empty() ? "" : ", ") + c;
76 std::cerr << " Allow: " << list << std::endl;
77 }
78 if (!disabled_categories_.empty()) {
79 std::string list;
80 for (const auto& c : disabled_categories_)
81 list += (list.empty() ? "" : ", ") + c;
82 std::cerr << " Block: " << list << std::endl;
83 }
84 }
85
86 // If a file path is provided, close any existing stream and open the new
87 // file.
88 if (!file_path.empty() && file_path != log_file_path_) {
89 if (log_stream_.is_open()) {
90 log_stream_.close();
91 }
92 // Open in append mode to preserve history.
93 log_stream_.open(file_path, std::ios::out | std::ios::app);
94 log_file_path_ = file_path;
95 }
96}
97
98void LogManager::log(LogLevel level, absl::string_view category,
99 absl::string_view message) {
100 // 1. Filter by log level.
101 if (level < min_level_.load()) {
102 return;
103 }
104
105 std::string cat_str(category);
106
107 // 2. Filter by disabled categories (Blocklist).
108 if (disabled_categories_.find(cat_str) != disabled_categories_.end()) {
109 return;
110 }
111
112 // 3. Filter by enabled categories (Allowlist).
113 // If allowlist is active (not empty), we must match it.
114 if (!all_categories_enabled_.load()) {
115 if (enabled_categories_.find(cat_str) == 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:32
void configure(LogLevel level, const std::string &file_path, const std::set< std::string > &categories)
Configures the logging system.
Definition log.cc:46
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:98
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