#ifndef MYLOGGER_H
#define MYLOGGER_H
#include <memory>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
// 定义宏
#define LOG_INFO(...) MyLogger::getInstance().info(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_WARN(...) MyLogger::getInstance().warn(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_ERROR(...) MyLogger::getInstance().error(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_CRITICAL(...) MyLogger::getInstance().critical(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
class MyLogger
{
private:
std::shared_ptr<spdlog::logger> logger;
public:
MyLogger(const MyLogger &) = delete;
MyLogger &operator=(const MyLogger &) = delete;
MyLogger()
{
// 创建控制台和文件日志记录器
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::trace); // 控制台日志记录器级别为 trace
console_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%^%l%$] [%s:%#] [%!] %v");
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs.txt", true);
file_sink->set_level(spdlog::level::trace); // 文件日志记录器级别为 trace
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%^%l%$] [%s:%#] [%!] %v");
// 创建多线程日志记录器
std::vector<spdlog::sink_ptr> sinks{console_sink, file_sink};
logger = std::make_shared<spdlog::logger>("multi_logger", sinks.begin(), sinks.end());
spdlog::register_logger(logger);
logger->set_level(spdlog::level::trace);
spdlog::flush_every(std::chrono::seconds(5));
}
static MyLogger &getInstance()
{
static MyLogger instance;
return instance;
}
std::shared_ptr<spdlog::logger> get_logger()
{
return logger;
}
template<typename... Args>
void log(const spdlog::source_loc &loc, spdlog::level::level_enum lvl, const char *fmt, const Args &...args)
{
logger->log(loc, lvl, fmt, args...);
}
template<typename... Args>
void info(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::info, fmt, args...);
}
template<typename... Args>
void warn(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::warn, fmt, args...);
}
template<typename... Args>
void error(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::err, fmt, args...);
}
template<typename... Args>
void critical(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::critical, fmt, args...);
}
};
// 实现析构函数(可以留空,因为 std::shared_ptr 会自动管理资源释放)
#endif // MYLOGGER_H
例子
#include "MyLogger.h"
MyLogger globalLogger;
int main() {
LOG_INFO("Hello, world");
LOG_ERROR( "This is an error message");
LOG_WARN( "This is a warning message");
LOG_CRITICAL("This is a critical message");
// 继续你的程序逻辑
return 0;
}
新版本更新了qt调试界面输出,此封装可以识别是不是qt程序,是的话就把控制台输出改成qt调试界面输出
#ifndef MYLOGGER_H
#define MYLOGGER_H
#include <memory>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#ifdef QT_CORE_LIB
#include <spdlog/sinks/qt_sinks.h>
#endif
// 定义宏
#define LOG_INFO(...) MyLogger::getInstance().info(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_WARN(...) MyLogger::getInstance().warn(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_ERROR(...) MyLogger::getInstance().error(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
#define LOG_CRITICAL(...) MyLogger::getInstance().critical(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, __VA_ARGS__)
class MyLogger
{
private:
std::shared_ptr<spdlog::logger> logger;
public:
MyLogger(const MyLogger &) = delete;
MyLogger &operator=(const MyLogger &) = delete;
MyLogger()
{
// 创建控制台和文件日志记录器
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::trace); // 控制台日志记录器级别为 trace
console_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%^%l%$] [%s:%#] [%!] %v");
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs.txt", true);
file_sink->set_level(spdlog::level::trace); // 文件日志记录器级别为 trace
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%^%l%$] [%s:%#] [%!] %v");
#ifdef QT_CORE_LIB
// 创建Qt调试输出接收器
auto qt_sink = std::make_shared<spdlog::sinks::qt_sink_mt>();
qt_sink->set_level(spdlog::level::trace); // Qt调试输出接收器级别为 trace
// 创建多线程日志记录器
std::vector<spdlog::sink_ptr> sinks{console_sink, file_sink, qt_sink};
#else
// 创建多线程日志记录器
std::vector<spdlog::sink_ptr> sinks{console_sink, file_sink};
#endif
logger = std::make_shared<spdlog::logger>("multi_logger", sinks.begin(), sinks.end());
spdlog::register_logger(logger);
logger->set_level(spdlog::level::trace);
spdlog::flush_every(std::chrono::seconds(5));
}
static MyLogger &getInstance()
{
static MyLogger instance;
return instance;
}
std::shared_ptr<spdlog::logger> get_logger()
{
return logger;
}
template<typename... Args>
void log(const spdlog::source_loc &loc, spdlog::level::level_enum lvl, const char *fmt, const Args &...args)
{
// 统一使用spdlog进行日志记录
logger->log(loc, lvl, fmt, args...);
}
template<typename... Args>
void info(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::info, fmt, args...);
}
template<typename... Args>
void warn(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::warn, fmt, args...);
}
template<typename... Args>
void error(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::err, fmt, args...);
}
template<typename... Args>
void critical(const spdlog::source_loc &loc, const char *fmt, const Args &...args)
{
log(loc, spdlog::level::critical, fmt, args...);
}
};
#endif // MYLOGGER_H