#ifndef _SPDLOGGER_h_
#define _SPDLOGGER_h_
#include "alg_export.h"
#include <iostream>
#include <string>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/common.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include <string>
namespace xxx{
// Macro to extract the file name from the full path
#define FILE_BASE_NAME (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define FUNC_BASE_NAME (strrchr(__FUNCTION__, '::') ? strrchr(__FUNCTION__, ':') + 1 : __FUNCTION__)
#define LOG_TRACE(...) spdLogger::getInstance().get()->trace(__VA_ARGS__)
#define LOG_DEBUG(...) spdLogger::getInstance().get()->debug(__VA_ARGS__)
//#define LOG_INFO(...) spdLogger::getInstance().get()->info(__VA_ARGS__)
#define LOG_INFO(...) spdLogger::getInstance().get()->info("{} {} {}",__FUNCTION__, __LINE__, __VA_ARGS__)
#define LOG_WARN(...) spdLogger::getInstance().get()->warn(__VA_ARGS__)
#define LOG_ERROR(...) spdLogger::getInstance().get()->error(__VA_ARGS__)
#define LOG_CRITICAL(...) spdLogger::getInstance().get()->critical(__VA_ARGS__)
// Define a macro to log the function name and execution time
#define FUNCTION_TIMER() \
auto start_time = std::chrono::high_resolution_clock::now(); \
auto func_end_time = start_time; \
auto elapsed = std::chrono::duration<double>::zero(); \
struct TimerGuard { \
std::chrono::high_resolution_clock::time_point& start_time; \
std::chrono::high_resolution_clock::time_point& func_end_time; \
std::chrono::duration<double>& elapsed; \
TimerGuard(std::chrono::high_resolution_clock::time_point& start, \
std::chrono::high_resolution_clock::time_point& end, \
std::chrono::duration<double>& duration) \
: start_time(start), func_end_time(end), elapsed(duration) {} \
~TimerGuard() { \
func_end_time = std::chrono::high_resolution_clock::now(); \
elapsed = func_end_time - start_time; \
spdlog::info("{} {:.6f} seconds", __FUNCTION__, elapsed.count()); \
} \
} timer_guard(start_time, func_end_time, elapsed);
// spdlog打印信息格式
/*
LOG_WARN("Easy padding in numbers like {:08d}", 12);
// [2021-04-07 23:49:24.916] [warning] Easy padding in numbers like 00000012
LOG_CRITICAL("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
// [2021-04-07 23:49:24.916] [critical] Support for int: 42; hex: 2a; oct: 52; bin: 101010
LOG_INFO("Support for floats {1:06.4f}", 1.23456, 9.8754321);
// [2021-04-07 23:49:24.916] [info] Support for floats 9.8754
LOG_INFO("Positional args are {1} {0}..", "too", "supported");
// [2021-04-07 23:49:24.916] [info] Positional args are supported too..
LOG_INFO("{:>8} aligned, {:<8} aligned", "right", "left");
// [2021-04-07 23:49:24.916] [info] right aligned, left aligned
*/
/*
使用时先执行init方法,参数
std::string logger_name :生成日志文件的名称,默认为log
std::size_t max_size :单个日志文件的大小,默认为10mb
std::size_t max_files :最大日志数目,默认为10
*/
class xxxx spdLogger
{
public:
static std::shared_ptr<spdlog::logger> getInstance();
spdLogger(const spdLogger&) = delete;
spdLogger& operator=(const spdLogger&) = delete;
static void inline init(std::string logger_name = "log", std::size_t max_size = 1024 * 1024 * 10, std::size_t max_files = 10);
private:
spdLogger() = default;
static std::shared_ptr<spdlog::logger> logger_;
};
}
#endif
void inline spdLogger::init(std::string logger_name, std::size_t max_size, std::size_t max_files)
{
try {
/* file sink */
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logger_name, max_size, max_files);
file_sink->set_level(spdlog::level::trace);
//file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
/* ����̨sink */
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::trace);
//console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");
//console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t] %v");
console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
/* Sink��� */
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(console_sink);
sinks.push_back(file_sink);
logger_ = std::make_shared<spdlog::logger>("multi-sink", begin(sinks), end(sinks));
//std::cout << "SPDLOG: create spdlog success!" << std::endl;
LOG_INFO("create spdlog success!");
}
catch (const spdlog::spdlog_ex& ex) {
perror("spdlog init error.");
}
}
std::shared_ptr<spdlog::logger> spdLogger::logger_ = nullptr;
std::shared_ptr<spdlog::logger> spdLogger::getInstance() {
if (!logger_) {
std::string log_dir = "log";
std::filesystem::create_directories(log_dir);
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm = *std::localtime(&now_c);
std::stringstream ss;
ss << std::put_time(&now_tm, "%Y-%m-%d"); // 格式化为 "YYYY-MM-DD"
std::string log_path = log_dir + "/" + ss.str() + ".log";
init(log_path);
}
return logger_;
}