121 lines
2.9 KiB
C
121 lines
2.9 KiB
C
|
/**
|
||
|
* @file mcp_logger.h
|
||
|
* @brief 简单的日志记录机制
|
||
|
*/
|
||
|
|
||
|
#ifndef MCP_LOGGER_H
|
||
|
#define MCP_LOGGER_H
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <sstream>
|
||
|
#include <string>
|
||
|
#include <mutex>
|
||
|
#include <chrono>
|
||
|
#include <iomanip>
|
||
|
|
||
|
namespace mcp {
|
||
|
|
||
|
enum class log_level {
|
||
|
debug,
|
||
|
info,
|
||
|
warning,
|
||
|
error
|
||
|
};
|
||
|
|
||
|
class logger {
|
||
|
public:
|
||
|
static logger& instance() {
|
||
|
static logger instance;
|
||
|
return instance;
|
||
|
}
|
||
|
|
||
|
void set_level(log_level level) {
|
||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||
|
level_ = level;
|
||
|
}
|
||
|
|
||
|
template<typename... Args>
|
||
|
void debug(Args&&... args) {
|
||
|
log(log_level::debug, std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
template<typename... Args>
|
||
|
void info(Args&&... args) {
|
||
|
log(log_level::info, std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
template<typename... Args>
|
||
|
void warning(Args&&... args) {
|
||
|
log(log_level::warning, std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
template<typename... Args>
|
||
|
void error(Args&&... args) {
|
||
|
log(log_level::error, std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
logger() : level_(log_level::info) {}
|
||
|
|
||
|
template<typename T>
|
||
|
void log_impl(std::stringstream& ss, T&& arg) {
|
||
|
ss << std::forward<T>(arg);
|
||
|
}
|
||
|
|
||
|
template<typename T, typename... Args>
|
||
|
void log_impl(std::stringstream& ss, T&& arg, Args&&... args) {
|
||
|
ss << std::forward<T>(arg);
|
||
|
log_impl(ss, std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
template<typename... Args>
|
||
|
void log(log_level level, Args&&... args) {
|
||
|
if (level < level_) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::stringstream ss;
|
||
|
|
||
|
// 添加时间戳
|
||
|
auto now = std::chrono::system_clock::now();
|
||
|
auto now_c = std::chrono::system_clock::to_time_t(now);
|
||
|
auto now_tm = std::localtime(&now_c);
|
||
|
|
||
|
ss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << " ";
|
||
|
|
||
|
// 添加日志级别
|
||
|
switch (level) {
|
||
|
case log_level::debug:
|
||
|
ss << "[DEBUG] ";
|
||
|
break;
|
||
|
case log_level::info:
|
||
|
ss << "[INFO] ";
|
||
|
break;
|
||
|
case log_level::warning:
|
||
|
ss << "[WARNING] ";
|
||
|
break;
|
||
|
case log_level::error:
|
||
|
ss << "[ERROR] ";
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// 添加日志内容
|
||
|
log_impl(ss, std::forward<Args>(args)...);
|
||
|
|
||
|
// 输出日志
|
||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||
|
std::cerr << ss.str() << std::endl;
|
||
|
}
|
||
|
|
||
|
log_level level_;
|
||
|
std::mutex mutex_;
|
||
|
};
|
||
|
|
||
|
#define LOG_DEBUG(...) mcp::logger::instance().debug(__VA_ARGS__)
|
||
|
#define LOG_INFO(...) mcp::logger::instance().info(__VA_ARGS__)
|
||
|
#define LOG_WARNING(...) mcp::logger::instance().warning(__VA_ARGS__)
|
||
|
#define LOG_ERROR(...) mcp::logger::instance().error(__VA_ARGS__)
|
||
|
|
||
|
} // namespace mcp
|
||
|
|
||
|
#endif // MCP_LOGGER_H
|