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
7namespace yaze {
8namespace util {
9
10// Helper function to convert LogLevel enum to a string representation.
11static const char* LogLevelToString(LogLevel level) {
12 switch (level) {
14 return "YAZE_DEBUG";
15 case LogLevel::INFO:
16 return "INFO";
18 return "WARN";
19 case LogLevel::ERROR:
20 return "ERROR";
21 case LogLevel::FATAL:
22 return "FATAL";
23 }
24 return "UNKN";
25}
26
27// --- LogManager Implementation ---
28
33
35 : min_level_(LogLevel::INFO), all_categories_enabled_(true) {}
36
38 if (log_stream_.is_open()) {
39 log_stream_.close();
40 }
41}
42
43void LogManager::configure(LogLevel level, const std::string& file_path,
44 const std::set<std::string>& categories) {
45 min_level_.store(level);
46
47 if (categories.empty()) {
48 all_categories_enabled_.store(true);
49 enabled_categories_.clear();
50 } else {
51 all_categories_enabled_.store(false);
52 enabled_categories_ = categories;
53
54 // Log which categories are enabled for debugging
55 std::string category_list;
56 for (const auto& cat : categories) {
57 if (!category_list.empty()) category_list += ", ";
58 category_list += cat;
59 }
60 std::cerr << "Log categories filter enabled: [" << category_list << "]" << std::endl;
61 }
62
63 // If a file path is provided, close any existing stream and open the new file.
64 if (!file_path.empty() && file_path != log_file_path_) {
65 if (log_stream_.is_open()) {
66 log_stream_.close();
67 }
68 // Open in append mode to preserve history.
69 log_stream_.open(file_path, std::ios::out | std::ios::app);
70 log_file_path_ = file_path;
71 }
72}
73
74void LogManager::log(LogLevel level, absl::string_view category,
75 absl::string_view message) {
76 // 1. Filter by log level.
77 if (level < min_level_.load()) {
78 return;
79 }
80
81 // 2. Filter by category.
82 if (!all_categories_enabled_.load()) {
83 if (enabled_categories_.find(std::string(category)) ==
84 enabled_categories_.end()) {
85 return;
86 }
87 }
88
89 // 3. Format the complete log message.
90 // [HH:MM:SS.ms] [LEVEL] [category] message
91 auto now = std::chrono::system_clock::now();
92 auto now_tt = std::chrono::system_clock::to_time_t(now);
93 auto now_tm = *std::localtime(&now_tt);
94 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
95 now.time_since_epoch()) %
96 1000;
97
98 std::string final_message = absl::StrFormat(
99 "[%02d:%02d:%02d.%03d] [%-5s] [%s] %s\n", now_tm.tm_hour, now_tm.tm_min,
100 now_tm.tm_sec, ms.count(), LogLevelToString(level), category, message);
101
102 // 4. Write to the configured sink (file or stderr).
103 if (log_stream_.is_open()) {
104 log_stream_ << final_message;
105 log_stream_.flush(); // Ensure immediate write for debugging.
106 } else {
107 std::cerr << final_message;
108 }
109
110 // 5. Abort on FATAL error.
111 if (level == LogLevel::FATAL) {
112 std::abort();
113 }
114}
115
116} // namespace util
117} // namespace yaze
A singleton that manages all logging configuration and output.
Definition log.h:37
std::ofstream log_stream_
Definition log.h:88
static LogManager & instance()
Definition log.cc:29
void configure(LogLevel level, const std::string &file_path, const std::set< std::string > &categories)
Configures the logging system.
Definition log.cc:43
std::string log_file_path_
Definition log.h:89
std::atomic< bool > all_categories_enabled_
Definition log.h:85
std::atomic< LogLevel > min_level_
Definition log.h:83
std::set< std::string > enabled_categories_
Definition log.h:84
void log(LogLevel level, absl::string_view category, absl::string_view message)
The primary logging function.
Definition log.cc:74
LogLevel
Defines the severity levels for log messages. This allows for filtering messages based on their impor...
Definition log.h:27
Main namespace for the application.