feat(logger): 增强日志服务功能并添加颜色支持
添加新的Registry日志级别和颜色支持功能 实现Windows控制台ANSI颜色和UTF-8支持 新增日志级别颜色自定义功能 添加带颜色参数的日志宏 移除不必要的头文件引用并优化注册表日志输出
This commit is contained in:
parent
65b143573c
commit
62b03144a1
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <extra2d/core/service_interface.h>
|
#include <extra2d/core/service_interface.h>
|
||||||
#include <extra2d/core/service_locator.h>
|
#include <extra2d/core/service_locator.h>
|
||||||
#include <extra2d/core/types.h>
|
#include <extra2d/core/types.h>
|
||||||
|
|
@ -8,6 +9,41 @@
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志颜色结构
|
||||||
|
*/
|
||||||
|
struct LogColor {
|
||||||
|
uint8_t r, g, b;
|
||||||
|
|
||||||
|
constexpr LogColor() : r(255), g(255), b(255) {}
|
||||||
|
constexpr LogColor(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {}
|
||||||
|
|
||||||
|
static constexpr LogColor White() { return LogColor(255, 255, 255); }
|
||||||
|
static constexpr LogColor Gray() { return LogColor(128, 128, 128); }
|
||||||
|
static constexpr LogColor Red() { return LogColor(255, 85, 85); }
|
||||||
|
static constexpr LogColor Green() { return LogColor(85, 255, 85); }
|
||||||
|
static constexpr LogColor Yellow() { return LogColor(255, 255, 85); }
|
||||||
|
static constexpr LogColor Blue() { return LogColor(85, 85, 255); }
|
||||||
|
static constexpr LogColor Magenta() { return LogColor(255, 85, 255); }
|
||||||
|
static constexpr LogColor Cyan() { return LogColor(85, 255, 255); }
|
||||||
|
static constexpr LogColor Orange() { return LogColor(255, 165, 0); }
|
||||||
|
|
||||||
|
static constexpr LogColor Slate() { return LogColor(100, 116, 139); }
|
||||||
|
static constexpr LogColor SlateLight() { return LogColor(148, 163, 184); }
|
||||||
|
static constexpr LogColor Sky() { return LogColor(14, 165, 233); }
|
||||||
|
static constexpr LogColor SkyLight() { return LogColor(125, 211, 252); }
|
||||||
|
static constexpr LogColor Emerald() { return LogColor(16, 185, 129); }
|
||||||
|
static constexpr LogColor EmeraldLight() { return LogColor(110, 231, 183); }
|
||||||
|
static constexpr LogColor Amber() { return LogColor(245, 158, 11); }
|
||||||
|
static constexpr LogColor AmberLight() { return LogColor(252, 211, 77); }
|
||||||
|
static constexpr LogColor Rose() { return LogColor(244, 63, 94); }
|
||||||
|
static constexpr LogColor RoseLight() { return LogColor(253, 164, 175); }
|
||||||
|
static constexpr LogColor Violet() { return LogColor(139, 92, 246); }
|
||||||
|
static constexpr LogColor VioletLight() { return LogColor(196, 181, 253); }
|
||||||
|
static constexpr LogColor Indigo() { return LogColor(99, 102, 241); }
|
||||||
|
static constexpr LogColor IndigoLight() { return LogColor(165, 180, 252); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 日志级别枚举
|
* @brief 日志级别枚举
|
||||||
*/
|
*/
|
||||||
|
|
@ -15,10 +51,11 @@ enum class LogLevel {
|
||||||
Trace = 0,
|
Trace = 0,
|
||||||
Debug = 1,
|
Debug = 1,
|
||||||
Info = 2,
|
Info = 2,
|
||||||
Warn = 3,
|
Registry = 3,
|
||||||
Error = 4,
|
Warn = 4,
|
||||||
Fatal = 5,
|
Error = 5,
|
||||||
Off = 6
|
Fatal = 6,
|
||||||
|
Off = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -68,6 +105,11 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void info(const char *fmt, ...) = 0;
|
virtual void info(const char *fmt, ...) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registry级别日志(用于模块/服务注册显示)
|
||||||
|
*/
|
||||||
|
virtual void registry(const char *fmt, ...) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Warn级别日志
|
* @brief Warn级别日志
|
||||||
*/
|
*/
|
||||||
|
|
@ -83,6 +125,31 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void fatal(const char *fmt, ...) = 0;
|
virtual void fatal(const char *fmt, ...) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置日志级别颜色
|
||||||
|
* @param level 日志级别
|
||||||
|
* @param color 颜色
|
||||||
|
*/
|
||||||
|
virtual void setLevelColor(LogLevel level, const LogColor &color) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取日志级别颜色
|
||||||
|
* @param level 日志级别
|
||||||
|
* @return 颜色
|
||||||
|
*/
|
||||||
|
virtual LogColor getLevelColor(LogLevel level) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启用/禁用颜色输出
|
||||||
|
* @param enabled 是否启用
|
||||||
|
*/
|
||||||
|
virtual void setColorEnabled(bool enabled) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 是否启用颜色输出
|
||||||
|
*/
|
||||||
|
virtual bool isColorEnabled() const = 0;
|
||||||
|
|
||||||
ServiceInfo getServiceInfo() const override {
|
ServiceInfo getServiceInfo() const override {
|
||||||
ServiceInfo info;
|
ServiceInfo info;
|
||||||
info.name = "Logger";
|
info.name = "Logger";
|
||||||
|
|
@ -113,15 +180,24 @@ public:
|
||||||
void trace(const char *fmt, ...) override;
|
void trace(const char *fmt, ...) override;
|
||||||
void debug(const char *fmt, ...) override;
|
void debug(const char *fmt, ...) override;
|
||||||
void info(const char *fmt, ...) override;
|
void info(const char *fmt, ...) override;
|
||||||
|
void registry(const char *fmt, ...) override;
|
||||||
void warn(const char *fmt, ...) override;
|
void warn(const char *fmt, ...) override;
|
||||||
void error(const char *fmt, ...) override;
|
void error(const char *fmt, ...) override;
|
||||||
void fatal(const char *fmt, ...) override;
|
void fatal(const char *fmt, ...) override;
|
||||||
|
|
||||||
|
void setLevelColor(LogLevel level, const LogColor &color) override;
|
||||||
|
LogColor getLevelColor(LogLevel level) const override;
|
||||||
|
void setColorEnabled(bool enabled) override;
|
||||||
|
bool isColorEnabled() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void output(LogLevel level, const char *msg);
|
void output(LogLevel level, const char *msg);
|
||||||
const char *getLevelString(LogLevel level);
|
const char *getLevelString(LogLevel level);
|
||||||
|
std::string getAnsiColor(LogLevel level);
|
||||||
|
|
||||||
LogLevel level_;
|
LogLevel level_;
|
||||||
|
bool colorEnabled_;
|
||||||
|
LogColor levelColors_[7];
|
||||||
class Impl;
|
class Impl;
|
||||||
UniquePtr<Impl> impl_;
|
UniquePtr<Impl> impl_;
|
||||||
|
|
||||||
|
|
@ -167,7 +243,6 @@ void format_impl(std::string &result, const char *fmt, T &&value,
|
||||||
}
|
}
|
||||||
result += *p++;
|
result += *p++;
|
||||||
}
|
}
|
||||||
// 没有更多的 {},追加剩余参数(不应该发生)
|
|
||||||
result += " ";
|
result += " ";
|
||||||
result += to_string(std::forward<T>(value));
|
result += to_string(std::forward<T>(value));
|
||||||
format_impl(result, p, std::forward<Args>(args)...);
|
format_impl(result, p, std::forward<Args>(args)...);
|
||||||
|
|
@ -198,23 +273,58 @@ std::string format_str(const char *fmt, Args &&...args) {
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define E2D_LOG_TRACE(...) E2D_LOG(::extra2d::LogLevel::Trace, __VA_ARGS__)
|
#define E2D_LOG_TRACE(...) E2D_LOG(::extra2d::LogLevel::Trace, __VA_ARGS__)
|
||||||
|
|
||||||
#define E2D_LOG_DEBUG(...) E2D_LOG(::extra2d::LogLevel::Debug, __VA_ARGS__)
|
#define E2D_LOG_DEBUG(...) E2D_LOG(::extra2d::LogLevel::Debug, __VA_ARGS__)
|
||||||
|
|
||||||
#define E2D_LOG_INFO(...) E2D_LOG(::extra2d::LogLevel::Info, __VA_ARGS__)
|
#define E2D_LOG_INFO(...) E2D_LOG(::extra2d::LogLevel::Info, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_REGISTRY(...) \
|
||||||
|
E2D_LOG(::extra2d::LogLevel::Registry, __VA_ARGS__)
|
||||||
#define E2D_LOG_WARN(...) E2D_LOG(::extra2d::LogLevel::Warn, __VA_ARGS__)
|
#define E2D_LOG_WARN(...) E2D_LOG(::extra2d::LogLevel::Warn, __VA_ARGS__)
|
||||||
|
|
||||||
#define E2D_LOG_ERROR(...) E2D_LOG(::extra2d::LogLevel::Error, __VA_ARGS__)
|
#define E2D_LOG_ERROR(...) E2D_LOG(::extra2d::LogLevel::Error, __VA_ARGS__)
|
||||||
|
|
||||||
#define E2D_LOG_FATAL(...) E2D_LOG(::extra2d::LogLevel::Fatal, __VA_ARGS__)
|
#define E2D_LOG_FATAL(...) E2D_LOG(::extra2d::LogLevel::Fatal, __VA_ARGS__)
|
||||||
|
|
||||||
// 简写宏
|
// 简写宏
|
||||||
#define E2D_INFO(...) E2D_LOG_INFO(__VA_ARGS__)
|
#define E2D_INFO(...) E2D_LOG_INFO(__VA_ARGS__)
|
||||||
|
#define E2D_REGISTRY(...) E2D_LOG_REGISTRY(__VA_ARGS__)
|
||||||
#define E2D_WARN(...) E2D_LOG_WARN(__VA_ARGS__)
|
#define E2D_WARN(...) E2D_LOG_WARN(__VA_ARGS__)
|
||||||
#define E2D_ERROR(...) E2D_LOG_ERROR(__VA_ARGS__)
|
#define E2D_ERROR(...) E2D_LOG_ERROR(__VA_ARGS__)
|
||||||
#define E2D_FATAL(...) E2D_LOG_FATAL(__VA_ARGS__)
|
#define E2D_FATAL(...) E2D_LOG_FATAL(__VA_ARGS__)
|
||||||
|
|
||||||
|
// 带颜色参数的日志宏
|
||||||
|
#define E2D_LOG_COLOR(level, color, ...) \
|
||||||
|
do { \
|
||||||
|
if (auto logService = ::extra2d::ServiceLocator::instance() \
|
||||||
|
.tryGetService<::extra2d::ILogger>()) { \
|
||||||
|
if (logService->isEnabled(level)) { \
|
||||||
|
auto prevColor = logService->getLevelColor(level); \
|
||||||
|
logService->setLevelColor(level, color); \
|
||||||
|
logService->log(level, ::extra2d::format_str(__VA_ARGS__)); \
|
||||||
|
logService->setLevelColor(level, prevColor); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define E2D_LOG_TRACE_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Trace, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_DEBUG_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Debug, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_INFO_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Info, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_REGISTRY_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Registry, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_WARN_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Warn, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_ERROR_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Error, color, __VA_ARGS__)
|
||||||
|
#define E2D_LOG_FATAL_COLOR(color, ...) \
|
||||||
|
E2D_LOG_COLOR(::extra2d::LogLevel::Fatal, color, __VA_ARGS__)
|
||||||
|
|
||||||
|
// 简写带颜色宏
|
||||||
|
#define E2D_INFO_COLOR(color, ...) E2D_LOG_INFO_COLOR(color, __VA_ARGS__)
|
||||||
|
#define E2D_REGISTRY_COLOR(color, ...) \
|
||||||
|
E2D_LOG_REGISTRY_COLOR(color, __VA_ARGS__)
|
||||||
|
#define E2D_WARN_COLOR(color, ...) E2D_LOG_WARN_COLOR(color, __VA_ARGS__)
|
||||||
|
#define E2D_ERROR_COLOR(color, ...) E2D_LOG_ERROR_COLOR(color, __VA_ARGS__)
|
||||||
|
#define E2D_FATAL_COLOR(color, ...) E2D_LOG_FATAL_COLOR(color, __VA_ARGS__)
|
||||||
|
|
||||||
#ifdef E2D_DEBUG
|
#ifdef E2D_DEBUG
|
||||||
#define E2D_DEBUG_LOG(...) E2D_LOG_DEBUG(__VA_ARGS__)
|
#define E2D_DEBUG_LOG(...) E2D_LOG_DEBUG(__VA_ARGS__)
|
||||||
#define E2D_TRACE(...) E2D_LOG_TRACE(__VA_ARGS__)
|
#define E2D_TRACE(...) E2D_LOG_TRACE(__VA_ARGS__)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#include <extra2d/core/registry.h>
|
#include <extra2d/core/registry.h>
|
||||||
#include <extra2d/core/service_locator.h>
|
|
||||||
#include <extra2d/services/logger_service.h>
|
#include <extra2d/services/logger_service.h>
|
||||||
#include <iostream>
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
@ -13,30 +11,24 @@ Registry &Registry::instance() {
|
||||||
|
|
||||||
bool Registry::init() {
|
bool Registry::init() {
|
||||||
auto sorted = topologicalSort();
|
auto sorted = topologicalSort();
|
||||||
|
E2D_REGISTRY("Initializing {} modules...", sorted.size());
|
||||||
std::cout << "[Registry] Initializing " << sorted.size() << " modules..."
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
for (auto *module : sorted) {
|
for (auto *module : sorted) {
|
||||||
std::cout << "[Registry] Initializing module: " << module->name()
|
E2D_REGISTRY("Initializing module: {}", module->name());
|
||||||
<< std::endl;
|
|
||||||
if (!module->init()) {
|
if (!module->init()) {
|
||||||
std::cerr << "[Registry] Failed to initialize module: " << module->name()
|
E2D_ERROR("Failed to initialize module: {}", module->name());
|
||||||
<< std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::cout << "[Registry] Module " << module->name()
|
E2D_REGISTRY("Module {} initialized successfully", module->name());
|
||||||
<< " initialized successfully" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[Registry] All modules initialized" << std::endl;
|
E2D_REGISTRY("All modules initialized");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Registry::shutdown() {
|
void Registry::shutdown() {
|
||||||
auto sorted = topologicalSort();
|
auto sorted = topologicalSort();
|
||||||
|
|
||||||
// 反向关闭
|
|
||||||
for (auto it = sorted.rbegin(); it != sorted.rend(); ++it) {
|
for (auto it = sorted.rbegin(); it != sorted.rend(); ++it) {
|
||||||
(*it)->shutdown();
|
(*it)->shutdown();
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +44,6 @@ std::vector<Module *> Registry::topologicalSort() {
|
||||||
std::unordered_map<Module *, int> inDegree;
|
std::unordered_map<Module *, int> inDegree;
|
||||||
std::unordered_map<Module *, std::vector<Module *>> adj;
|
std::unordered_map<Module *, std::vector<Module *>> adj;
|
||||||
|
|
||||||
// 构建图
|
|
||||||
for (auto &[typeIdx, module] : modules_) {
|
for (auto &[typeIdx, module] : modules_) {
|
||||||
inDegree[module.get()] = 0;
|
inDegree[module.get()] = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +58,6 @@ std::vector<Module *> Registry::topologicalSort() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先级队列(优先级小的先处理)
|
|
||||||
auto cmp = [](Module *a, Module *b) { return a->priority() > b->priority(); };
|
auto cmp = [](Module *a, Module *b) { return a->priority() > b->priority(); };
|
||||||
std::priority_queue<Module *, std::vector<Module *>, decltype(cmp)> pq(cmp);
|
std::priority_queue<Module *, std::vector<Module *>, decltype(cmp)> pq(cmp);
|
||||||
|
|
||||||
|
|
@ -77,7 +67,6 @@ std::vector<Module *> Registry::topologicalSort() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 拓扑排序
|
|
||||||
while (!pq.empty()) {
|
while (!pq.empty()) {
|
||||||
Module *curr = pq.top();
|
Module *curr = pq.top();
|
||||||
pq.pop();
|
pq.pop();
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,65 @@
|
||||||
#include <extra2d/services/logger_service.h>
|
#include <extra2d/services/logger_service.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
// ConsoleLogger 实现
|
#ifdef _WIN32
|
||||||
|
/**
|
||||||
|
* @brief 初始化 Windows 控制台(ANSI 颜色 + UTF-8)
|
||||||
|
*/
|
||||||
|
static bool enableWindowsConsoleFeatures() {
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (hOut != INVALID_HANDLE_VALUE) {
|
||||||
|
DWORD dwMode = 0;
|
||||||
|
if (GetConsoleMode(hOut, &dwMode)) {
|
||||||
|
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
if (!SetConsoleMode(hOut, dwMode)) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
|
SetConsoleCP(CP_UTF8);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool g_windowsConsoleInitialized = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
class ConsoleLogger::Impl {
|
class ConsoleLogger::Impl {
|
||||||
public:
|
public:
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ConsoleLogger::ConsoleLogger()
|
ConsoleLogger::ConsoleLogger()
|
||||||
: level_(LogLevel::Info), impl_(std::make_unique<Impl>()) {
|
: level_(LogLevel::Info), colorEnabled_(true),
|
||||||
|
impl_(std::make_unique<Impl>()) {
|
||||||
info_.name = "ConsoleLogger";
|
info_.name = "ConsoleLogger";
|
||||||
info_.priority = ServicePriority::Core;
|
info_.priority = ServicePriority::Core;
|
||||||
|
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Trace)] = LogColor::Gray();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Debug)] = LogColor::Cyan();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Info)] = LogColor::SkyLight();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Registry)] = LogColor::IndigoLight();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Warn)] = LogColor::Yellow();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Error)] = LogColor::Red();
|
||||||
|
levelColors_[static_cast<int>(LogLevel::Fatal)] = LogColor::Magenta();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (!g_windowsConsoleInitialized) {
|
||||||
|
g_windowsConsoleInitialized = enableWindowsConsoleFeatures();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleLogger::~ConsoleLogger() = default;
|
ConsoleLogger::~ConsoleLogger() = default;
|
||||||
|
|
@ -87,6 +134,17 @@ void ConsoleLogger::info(const char *fmt, ...) {
|
||||||
output(LogLevel::Info, buffer);
|
output(LogLevel::Info, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConsoleLogger::registry(const char *fmt, ...) {
|
||||||
|
if (!isEnabled(LogLevel::Registry))
|
||||||
|
return;
|
||||||
|
char buffer[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
output(LogLevel::Registry, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void ConsoleLogger::warn(const char *fmt, ...) {
|
void ConsoleLogger::warn(const char *fmt, ...) {
|
||||||
if (!isEnabled(LogLevel::Warn))
|
if (!isEnabled(LogLevel::Warn))
|
||||||
return;
|
return;
|
||||||
|
|
@ -120,6 +178,32 @@ void ConsoleLogger::fatal(const char *fmt, ...) {
|
||||||
output(LogLevel::Fatal, buffer);
|
output(LogLevel::Fatal, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConsoleLogger::setLevelColor(LogLevel level, const LogColor &color) {
|
||||||
|
int idx = static_cast<int>(level);
|
||||||
|
if (idx >= 0 && idx < 7) {
|
||||||
|
levelColors_[idx] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogColor ConsoleLogger::getLevelColor(LogLevel level) const {
|
||||||
|
int idx = static_cast<int>(level);
|
||||||
|
if (idx >= 0 && idx < 7) {
|
||||||
|
return levelColors_[idx];
|
||||||
|
}
|
||||||
|
return LogColor::White();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleLogger::setColorEnabled(bool enabled) { colorEnabled_ = enabled; }
|
||||||
|
|
||||||
|
bool ConsoleLogger::isColorEnabled() const { return colorEnabled_; }
|
||||||
|
|
||||||
|
std::string ConsoleLogger::getAnsiColor(LogLevel level) {
|
||||||
|
const LogColor &c = getLevelColor(level);
|
||||||
|
char buf[32];
|
||||||
|
snprintf(buf, sizeof(buf), "\033[38;2;%d;%d;%dm", c.r, c.g, c.b);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void ConsoleLogger::output(LogLevel level, const char *msg) {
|
void ConsoleLogger::output(LogLevel level, const char *msg) {
|
||||||
std::lock_guard<std::mutex> lock(impl_->mutex_);
|
std::lock_guard<std::mutex> lock(impl_->mutex_);
|
||||||
|
|
||||||
|
|
@ -137,36 +221,16 @@ void ConsoleLogger::output(LogLevel level, const char *msg) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *levelStr = getLevelString(level);
|
const char *levelStr = getLevelString(level);
|
||||||
|
|
||||||
// 颜色代码
|
|
||||||
const char *color = "";
|
|
||||||
const char *reset = "\033[0m";
|
const char *reset = "\033[0m";
|
||||||
|
|
||||||
switch (level) {
|
if (colorEnabled_) {
|
||||||
case LogLevel::Trace:
|
std::string color = getAnsiColor(level);
|
||||||
color = "\033[90m";
|
printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", color.c_str(), tm.tm_hour,
|
||||||
break;
|
tm.tm_min, tm.tm_sec, (int)ms.count(), levelStr, msg, reset);
|
||||||
case LogLevel::Debug:
|
} else {
|
||||||
color = "\033[36m";
|
printf("[%02d:%02d:%02d.%03d] [%s] %s\n", tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||||
break;
|
(int)ms.count(), levelStr, msg);
|
||||||
case LogLevel::Info:
|
|
||||||
color = "\033[32m";
|
|
||||||
break;
|
|
||||||
case LogLevel::Warn:
|
|
||||||
color = "\033[33m";
|
|
||||||
break;
|
|
||||||
case LogLevel::Error:
|
|
||||||
color = "\033[31m";
|
|
||||||
break;
|
|
||||||
case LogLevel::Fatal:
|
|
||||||
color = "\033[35m";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s[%02d:%02d:%02d.%03d] [%s] %s%s\n", color, tm.tm_hour, tm.tm_min,
|
|
||||||
tm.tm_sec, (int)ms.count(), levelStr, msg, reset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ConsoleLogger::getLevelString(LogLevel level) {
|
const char *ConsoleLogger::getLevelString(LogLevel level) {
|
||||||
|
|
@ -177,6 +241,8 @@ const char *ConsoleLogger::getLevelString(LogLevel level) {
|
||||||
return "DEBUG";
|
return "DEBUG";
|
||||||
case LogLevel::Info:
|
case LogLevel::Info:
|
||||||
return "INFO";
|
return "INFO";
|
||||||
|
case LogLevel::Registry:
|
||||||
|
return "REGISTRY";
|
||||||
case LogLevel::Warn:
|
case LogLevel::Warn:
|
||||||
return "WARN";
|
return "WARN";
|
||||||
case LogLevel::Error:
|
case LogLevel::Error:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue