Max OS 0.3
Loading...
Searching...
No Matches
logger.cpp
Go to the documentation of this file.
1
9#include <common/logger.h>
10#include <stdarg.h>
11#include <console/framebuffer.h>
12#include <common/version.h>
13#include <system/cpu.h>
14#include <processes/scheduler.h>
15
16using namespace MaxOS;
17using namespace MaxOS::common;
18using namespace MaxOS::console;
19using namespace MaxOS::processes;
20using namespace MaxOS::system;
21
26: m_log_writers()
27{
28
29 s_active_logger = this;
30
31 // The following line is generated automatically by the MaxOS build system.
32 s_progress_total = 15;
33
34}
35
36
37Logger::~Logger() = default;
38
44void Logger::add_log_writer(OutputStream* log_writer) {
45
46 // If the list is not empty
47 if (m_log_writer_count >= MAX_LOG_WRITERS)
48 return;
49
50 // Add the output stream to the list
51 m_log_writers[m_log_writer_count] = log_writer;
52 m_log_writers_enabled[m_log_writer_count] = true;
53 m_log_writer_count++;
54
55 // Print the setup info
56 *this << LogLevel::INFO << "Logger setup: " << m_log_writer_count << "\n";
57 *this << LogLevel::HEADER << "MaxOS v" << VERSION_STRING << " [ build " << BUILD_NUMBER << " ]\n";
58
59}
60
66void Logger::disable_log_writer(OutputStream* log_writer) {
67
68 // If the list is empty
69 if (m_log_writer_count == 0)
70 return;
71
72 // Find the output stream in the list
73 for (int i = 0; i < m_log_writer_count; i++)
74 if (m_log_writers[i] == log_writer)
75 m_log_writers_enabled[i] = false;
76}
77
83void Logger::enable_log_writer(OutputStream* log_writer) {
84
85 // If the list is empty
86 if (m_log_writer_count == 0)
87 return;
88
89 // Find the output stream in the list
90 for (int i = 0; i < m_log_writer_count; i++)
91 if (m_log_writers[i] == log_writer)
92 m_log_writers_enabled[i] = true;
93
94}
95
100 for (int i = 0; i < m_log_writer_count; i++)
101 if (!m_log_writers_enabled[i])
102 m_log_writers_enabled[i] = true;
103}
104
111
112 // Set the log level
113 m_log_level = log_level;
114
115 // Update the progress bar
116 if (log_level == LogLevel::INFO) {
117 FramebufferConsole::update_progress_bar((m_progress_current * 100) / s_progress_total);
118 m_progress_current++;
119 }
120
121 // Print the header
122 switch (log_level) {
123
124 case LogLevel::HEADER:
125 *this << ANSI_COLOURS[FG_Blue] << "[ BOOT ] ";
126 break;
127
128 case LogLevel::INFO:
129 *this << ANSI_COLOURS[FG_Cyan] << "[ INFO ]" << ANSI_COLOURS[FG_White] << " ";
130 break;
131
132 case LogLevel::TEST:
133 *this << ANSI_COLOURS[FG_Green] << "[ TEST ]" << ANSI_COLOURS[FG_White] << " ";
134 break;
135
136 case LogLevel::DEBUG:
137 *this << ANSI_COLOURS[FG_Yellow] << "[ DEBUG ]" << ANSI_COLOURS[Reset] << " ";
138 break;
139
140 case LogLevel::WARNING:
141 *this << ANSI_COLOURS[BG_Yellow] << ANSI_COLOURS[FG_White] << "[ WARNING ]" << ANSI_COLOURS[Reset] << " ";
142 break;
143
144 case LogLevel::ERROR:
145 *this << ANSI_COLOURS[BG_Red] << "[ ERROR ]" << ANSI_COLOURS[Reset] << " ";
146 break;
147 }
148
150}
151
152
158void Logger::write_char(char c) {
159
160 // Ensure logging at this level is enabled
161 if (m_log_level > MAX_LOG_LEVEL)
162 return;
163
164 // Write the character to all output streams
165 for (int i = 0; i < m_log_writer_count; i++)
166 if (m_log_writers_enabled[i])
167 m_log_writers[i]->write_char(c);
168
169}
170
177
178 return LogRecord(*s_active_logger, LogLevel::OUT);
179}
180
187 return LogRecord(*s_active_logger, LogLevel::TEST);
188}
189
196 return LogRecord(*s_active_logger, LogLevel::INFO);
197}
198
205 return LogRecord(*s_active_logger, LogLevel::DEBUG);
206}
207
214 return LogRecord(*s_active_logger, LogLevel::WARNING);
215}
216
223 return LogRecord(*s_active_logger, LogLevel::ERROR);
224}
225
232 return LogRecord(*s_active_logger, LogLevel::HEADER);
233}
234
241 return s_active_logger;
242}
243
250void Logger::printf(char const *format, ...) {
251
252
253 // Create a pointer to the data
254 va_list parameters;
255 va_start(parameters, format);
256
257 write(String::formatted(format, parameters));
258}
259
267void Logger::assert(bool condition, char const* message, ...) {
268
269 // If the condition is met then everything is ok
270 if (condition)
271 return;
272
273 va_list parameters;
274 va_start(parameters, message);
275
276 // Hang the system
277 CPU::PANIC(String::formatted(message, parameters).c_str());
278}
279
287
288 set_log_level(log_level);
289 return *this;
290
291}
292
300: m_logger(logger)
301{
302
303 // Wait for the logger to be free
304 Logger::s_loggers_lock.lock();
305 if (level != LogLevel::OUT)
306 m_logger.set_log_level(level);
307}
308
313
314 Logger::s_loggers_lock.unlock();
315
316}
A single logging event.
Definition logger.h:106
LogRecord(Logger &logger, LogLevel level)
Definition logger.cpp:299
A class that handles logging messages to the console and files.
Definition logger.h:51
static LogRecord TEST()
Gets the active logger for testing logs.
Definition logger.cpp:186
static void assert(bool condition, const char *message,...)
Puts the system into a panic state if the condition is false, printing the message first.
Definition logger.cpp:267
static LogRecord ERROR()
Gets the active logger for error logs.
Definition logger.cpp:222
void enable_log_writer(OutputStream *log_writer)
Lets an output stream from be used.
Definition logger.cpp:83
void printf(const char *format,...)
Prints a formatted string to the logger (thread safe)
Definition logger.cpp:250
static Logger * active_logger()
Gets the active logger (to be used to modify the logger)
Definition logger.cpp:240
static LogRecord DEBUG()
Gets the active logger for debug logs.
Definition logger.cpp:204
void disable_log_writer(OutputStream *log_writer)
Prevents an output stream from being used.
Definition logger.cpp:66
static LogRecord HEADER()
Gets the active logger for headers.
Definition logger.cpp:231
void add_log_writer(OutputStream *log_writer)
Adds an output stream to the logger.
Definition logger.cpp:44
static LogRecord INFO()
Gets the active logger for info logs.
Definition logger.cpp:195
static LogRecord WARNING()
Gets the active logger for warnings.
Definition logger.cpp:213
void write_char(char c) final
Writes a character to the logger.
Definition logger.cpp:158
static LogRecord Out()
Gets the active logger.
Definition logger.cpp:176
Logger()
Constructs a Logger object and sets it as the active logger.
Definition logger.cpp:25
void set_log_level(LogLevel log_level)
Sets the log level of the logger.
Definition logger.cpp:110
void enable_all_log_writers()
Mark all log writes as allowed to output to.
Definition logger.cpp:99
Logger & operator<<(LogLevel log_level)
Sets the log level of the logger.
Definition logger.cpp:286
static void update_progress_bar(uint8_t percentage)
Updates the progress bar.
static void print_running_header()
Print the header for the running processes in the form ({name}:t{tid}c{core})
static void PANIC(const char *message, cpu_status_t *status=nullptr)
Puts the CPU into a panic state and halts it. Dumps the stack trace and registers.
Definition cpu.cpp:463
Defines Central Processing Unit (CPU) structures and functions for managing CPU state and features.
Defines the VESABootConsole driver for handling console output during boot using an VESA framebuffer.
Defines a Logger class for logging messages with different severity levels to multiple output streams...
LogLevel
Priority levels for logging messages. Different levels may be used to filter messages based on their ...
Definition logger.h:25
constexpr LogLevel MAX_LOG_LEVEL
The maximum log level for this build (messages above this level will not be logged)
Definition logger.h:40
constexpr uint8_t MAX_LOG_WRITERS
The maximum number of log writers that can be added to the logger.
Definition logger.h:36
Defines a GlobalScheduler and Scheduler for managing processes and threads.