6#include <spdlog/sinks/basic_file_sink.h>
7#include <spdlog/sinks/rotating_file_sink.h>
8#include <spdlog/sinks/stdout_color_sinks.h>
9#include <spdlog/sinks/stdout_sinks.h>
10#include <spdlog/spdlog.h>
23 static SpdlogManager &GetInstance() {
24 static SpdlogManager instance;
36 void Initialize(
const std::string &app_name =
"Ember",
const std::string &log_file_path =
"logs/Ember.log",
37 size_t max_file_size = 1024 * 1024 * 5,
38 size_t max_files = 3,
bool enable_console_colors =
true) {
41 auto existing_logger = spdlog::get(app_name);
42 if (existing_logger) {
44 m_logger = existing_logger;
46 m_logger->info(
"Using existing spdlog logger: {}", app_name);
51 std::shared_ptr<spdlog::sinks::sink> console_sink;
52 if (enable_console_colors) {
53 auto color_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
55 color_sink->set_color_mode(spdlog::color_mode::always);
56 console_sink = color_sink;
58 console_sink->set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] %v");
60 console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
62 console_sink->set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v");
66 std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file_path, max_file_size, max_files);
69 file_sink->set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v");
72 std::vector<spdlog::sink_ptr> sinks{console_sink, file_sink};
73 m_logger = std::make_shared<spdlog::logger>(app_name, sinks.begin(), sinks.end());
76 m_logger->set_level(spdlog::level::info);
77 m_logger->flush_on(spdlog::level::warn);
80 spdlog::register_logger(m_logger);
81 spdlog::set_default_logger(m_logger);
86 m_logger->info(
"spdlog initialized successfully");
88 }
catch (
const spdlog::spdlog_ex &ex) {
92 auto existing_logger = spdlog::get(app_name);
93 if (existing_logger) {
94 m_logger = existing_logger;
97 if (enable_console_colors) {
98 auto color_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
99 color_sink->set_color_mode(spdlog::color_mode::always);
100 m_logger = std::make_shared<spdlog::logger>(app_name, color_sink);
101 spdlog::register_logger(m_logger);
103 auto plain_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
104 m_logger = std::make_shared<spdlog::logger>(app_name, plain_sink);
105 spdlog::register_logger(m_logger);
108 m_logger->error(
"Failed to initialize file logging: {}", ex.what());
109 m_initialized =
true;
112 m_logger = std::make_shared<spdlog::logger>(app_name);
113 m_initialized =
true;
121 std::shared_ptr<spdlog::logger> GetLogger() {
122 if (!m_initialized) {
132 std::shared_ptr<spdlog::logger> GetLogger(
const std::string &name) {
133 if (!m_initialized) {
137 auto existing = spdlog::get(name);
143 auto new_logger = std::make_shared<spdlog::logger>(name, m_logger->sinks().begin(), m_logger->sinks().end());
144 new_logger->set_level(m_logger->level());
145 spdlog::register_logger(new_logger);
153 void SetLogLevel(spdlog::level::level_enum level) {
155 m_logger->set_level(level);
156 spdlog::set_level(level);
164 void SetConsoleColorsEnabled(
bool enabled) {
165 if (!m_initialized || !m_logger) {
171 auto sinks = m_logger->sinks();
174 for (
size_t i = 0; i < sinks.size(); ++i) {
178 std::shared_ptr<spdlog::sinks::sink> new_console_sink;
180 auto color_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
182 color_sink->set_color_mode(spdlog::color_mode::always);
183 new_console_sink = color_sink;
185 new_console_sink->set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] %v");
187 new_console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
189 new_console_sink->set_pattern(
"[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v");
192 new_console_sink->set_level(sinks[i]->level());
195 sinks[i] = new_console_sink;
201 std::string logger_name = m_logger->name();
202 auto new_logger = std::make_shared<spdlog::logger>(logger_name, sinks.begin(), sinks.end());
203 new_logger->set_level(m_logger->level());
204 new_logger->flush_on(spdlog::level::warn);
207 spdlog::drop(logger_name);
208 spdlog::register_logger(new_logger);
209 spdlog::set_default_logger(new_logger);
211 m_logger = new_logger;
213 }
catch (
const std::exception &ex) {
224 m_initialized =
false;
229 SpdlogManager() =
default;
233 ~SpdlogManager() =
default;
235 std::shared_ptr<spdlog::logger> m_logger;
236 bool m_initialized =
false;
242#define EMBER_SPDLOG_TRACE(...) \
243 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
244 logger->trace(__VA_ARGS__)
245#define EMBER_SPDLOG_DEBUG(...) \
246 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
247 logger->debug(__VA_ARGS__)
248#define EMBER_SPDLOG_INFO(...) \
249 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
250 logger->info(__VA_ARGS__)
251#define EMBER_SPDLOG_WARN(...) \
252 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
253 logger->warn(__VA_ARGS__)
254#define EMBER_SPDLOG_ERROR(...) \
255 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
256 logger->error(__VA_ARGS__)
257#define EMBER_SPDLOG_CRITICAL(...) \
258 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger()) \
259 logger->critical(__VA_ARGS__)
265#define EMBER_SPDLOG_UI_INFO(...) \
266 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("UI")) \
267 logger->info(__VA_ARGS__)
268#define EMBER_SPDLOG_UI_WARN(...) \
269 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("UI")) \
270 logger->warn(__VA_ARGS__)
271#define EMBER_SPDLOG_UI_ERROR(...) \
272 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("UI")) \
273 logger->error(__VA_ARGS__)
275#define EMBER_SPDLOG_CORE_INFO(...) \
276 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Core")) \
277 logger->info(__VA_ARGS__)
278#define EMBER_SPDLOG_CORE_WARN(...) \
279 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Core")) \
280 logger->warn(__VA_ARGS__)
281#define EMBER_SPDLOG_CORE_ERROR(...) \
282 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Core")) \
283 logger->error(__VA_ARGS__)
285#define EMBER_SPDLOG_NETWORK_INFO(...) \
286 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Network")) \
287 logger->info(__VA_ARGS__)
288#define EMBER_SPDLOG_NETWORK_WARN(...) \
289 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Network")) \
290 logger->warn(__VA_ARGS__)
291#define EMBER_SPDLOG_NETWORK_ERROR(...) \
292 if (auto logger = EmberCore::SpdlogManager::GetInstance().GetLogger("Network")) \
293 logger->error(__VA_ARGS__)
298#define EMBER_SPDLOG_TRACE(...)
299#define EMBER_SPDLOG_DEBUG(...)
300#define EMBER_SPDLOG_INFO(...)
301#define EMBER_SPDLOG_WARN(...)
302#define EMBER_SPDLOG_ERROR(...)
303#define EMBER_SPDLOG_CRITICAL(...)
305#define EMBER_SPDLOG_UI_INFO(...)
306#define EMBER_SPDLOG_UI_WARN(...)
307#define EMBER_SPDLOG_UI_ERROR(...)
309#define EMBER_SPDLOG_CORE_INFO(...)
310#define EMBER_SPDLOG_CORE_WARN(...)
311#define EMBER_SPDLOG_CORE_ERROR(...)
313#define EMBER_SPDLOG_NETWORK_INFO(...)
314#define EMBER_SPDLOG_NETWORK_WARN(...)
315#define EMBER_SPDLOG_NETWORK_ERROR(...)
Main types header for EmberCore.