MetaImGUI 1.0.0
ImGui Application Template for C++20
Loading...
Searching...
No Matches
Logger.cpp
Go to the documentation of this file.
1/*
2 MetaImGUI
3 Copyright (C) 2026 A P Nicholson
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17*/
18
19#include "Logger.h"
20
21#include <chrono>
22#include <ctime>
23#include <iomanip>
24#include <iostream>
25
26namespace MetaImGUI {
27
28Logger::Logger() = default;
29
30Logger::~Logger() {
31 Shutdown();
32}
33
35 static Logger instance;
36 return instance;
37}
38
39void Logger::Initialize(const std::filesystem::path& logFilePath, LogLevel minLevel) {
40 const std::lock_guard<std::mutex> lock(m_mutex);
41
42 m_minLevel = minLevel;
43 m_logFilePath = logFilePath;
44
45 if (!logFilePath.empty()) {
46 // Ensure parent directory exists
47 auto parentPath = logFilePath.parent_path();
48 if (!parentPath.empty() && !std::filesystem::exists(parentPath)) {
49 std::error_code ec;
50 std::filesystem::create_directories(parentPath, ec);
51 if (ec) {
52 std::cerr << "Warning: Could not create log directory: " << ec.message() << '\n';
53 }
54 }
55
56 m_logFile.open(logFilePath, std::ios::out | std::ios::app);
57 if (m_logFile.is_open()) {
58 m_fileOutput = true;
59 m_logFile << "\n========== Log Session Started: " << GetTimestamp() << " ==========\n";
60 m_logFile.flush();
61 } else {
62 std::cerr << "Failed to open log file: " << logFilePath << '\n';
63 m_fileOutput = false;
64 }
65 }
66
67 if (m_consoleOutput) {
68 std::cout << "Logger initialized (Level: " << LevelToString(minLevel) << ")" << '\n';
69 }
70}
71
73 const std::lock_guard<std::mutex> lock(m_mutex);
74
75 if (m_logFile.is_open()) {
76 m_logFile << "========== Log Session Ended: " << GetTimestamp() << " ==========\n\n";
77 m_logFile.close();
78 }
79}
80
82 const std::lock_guard<std::mutex> lock(m_mutex);
83 m_minLevel = level;
84}
85
87 const std::lock_guard<std::mutex> lock(m_mutex);
88 return m_minLevel;
89}
90
91void Logger::SetConsoleOutput(bool enable) {
92 const std::lock_guard<std::mutex> lock(m_mutex);
93 m_consoleOutput = enable;
94}
95
96void Logger::SetFileOutput(bool enable) {
97 const std::lock_guard<std::mutex> lock(m_mutex);
98 m_fileOutput = enable && m_logFile.is_open();
99}
100
102 const std::lock_guard<std::mutex> lock(m_mutex);
103 if (m_logFile.is_open()) {
104 m_logFile.flush();
105 }
106 std::cout.flush();
107 std::cerr.flush();
108}
109
110std::filesystem::path Logger::GetLogFilePath() const {
111 const std::lock_guard<std::mutex> lock(m_mutex);
112 return m_logFilePath;
113}
114
115void Logger::LogMessage(LogLevel level, const std::string& message) {
116 const std::lock_guard<std::mutex> lock(m_mutex);
117
118 const std::string timestamp = GetTimestamp();
119 const std::string levelStr = LevelToString(level);
120 const std::string formattedMessage = "[" + timestamp + "] [" + levelStr + "] " + message;
121
122 // Console output with colors
123 if (m_consoleOutput) {
124 const char* color = LevelToColor(level);
125 const char* reset = "\033[0m";
126
127 std::ostream& out = (level >= LogLevel::Error) ? std::cerr : std::cout;
128 out << color << formattedMessage << reset << '\n';
129 }
130
131 // File output without colors
132 if (m_fileOutput && m_logFile.is_open()) {
133 m_logFile << formattedMessage << '\n';
134
135 // Auto-flush for errors and above
136 if (level >= LogLevel::Error) {
137 m_logFile.flush();
138 }
139 }
140}
141
142std::string Logger::GetTimestamp() const {
143 auto now = std::chrono::system_clock::now();
144 auto time = std::chrono::system_clock::to_time_t(now);
145 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
146
147 std::tm tm_buf{};
148#ifdef _WIN32
149 localtime_s(&tm_buf, &time);
150#else
151 localtime_r(&time, &tm_buf);
152#endif
153
154 std::ostringstream oss;
155 oss << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S");
156 oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
157 return oss.str();
158}
159
160std::string Logger::LevelToString(LogLevel level) const {
161 switch (level) {
162 case LogLevel::Debug:
163 return "DEBUG";
164 case LogLevel::Info:
165 return "INFO ";
167 return "WARN ";
168 case LogLevel::Error:
169 return "ERROR";
170 case LogLevel::Fatal:
171 return "FATAL";
172 default:
173 return "?????";
174 }
175}
176
177const char* Logger::LevelToColor(LogLevel level) const {
178 switch (level) {
179 case LogLevel::Debug:
180 return "\033[36m"; // Cyan
181 case LogLevel::Info:
182 return "\033[32m"; // Green
184 return "\033[33m"; // Yellow
185 case LogLevel::Error:
186 return "\033[31m"; // Red
187 case LogLevel::Fatal:
188 return "\033[35m"; // Magenta
189 default:
190 return "\033[0m"; // Reset
191 }
192}
193
194} // namespace MetaImGUI
Simple logging system with file and console output.
Definition Logger.h:58
void SetFileOutput(bool enable)
Enable/disable file output.
Definition Logger.cpp:96
void SetConsoleOutput(bool enable)
Enable/disable console output.
Definition Logger.cpp:91
void Shutdown()
Shutdown logger and flush buffers.
Definition Logger.cpp:72
void Initialize(const std::filesystem::path &logFilePath="", LogLevel minLevel=LogLevel::Info)
Initialize logger with optional log file.
Definition Logger.cpp:39
LogLevel GetLevel() const
Get current log level.
Definition Logger.cpp:86
static Logger & Instance()
Get singleton instance.
Definition Logger.cpp:34
void SetLevel(LogLevel level)
Set minimum log level.
Definition Logger.cpp:81
std::filesystem::path GetLogFilePath() const
Get log file path.
Definition Logger.cpp:110
void Flush()
Flush log buffers.
Definition Logger.cpp:101
LogLevel
Log severity levels.
Definition Logger.h:34
@ Warning
Warning messages.
@ Info
Informational messages.
@ Fatal
Fatal error messages.
@ Error
Error messages.
@ Debug
Detailed debugging information.