spdlog高速日志系统
1.什么是spdlog
①.spdlog是一款高效的C++日志库,特别适用于使用C++和需要引入日志库的项目。
②.spdlog以极高的性能和零成本的抽象而著称,通过模板和内联函数实现零成本的抽象。
③.spdlog支持异步和同步的日志输出和记录
日志的作用:追踪程序运行的状态,出现问题提供现场运行信息,分析性能瓶颈和潜在的系统故障
spdlog提供多种日志级别,如info、debug、trace、error、critical等。
2.同步日志和异步日志的区别
①.同步日志:调用日志函数后,日志内容立即打印并落盘,当前线程阻塞等待日志完成。
②.异步日志:调用日志函数后,日志内容被抛入队列,由其他线程在后台打印,当前线程立即返回。
③.多线程使用日志库与同步或异步无关,关键在于日志库是否线程安全。
3.spdlog的抽象模型
①.registry:注册器,单例管理多个logger。
②.logger:日志记录器,管理多个sink。
③.sink:日志接收器,具体负责将日志输出到目的地。
④.thread_pool:线程池,用于异步日志的输出。
4.如何创建logger??
①工厂方法创建
//使用工厂默认的
auto logger = spdlog::stdout_color_mt<spdlog::async_factory>("conslole");
logger->info("helloworldtoo!!");//直接info
spdlog::get("conslole")->info("helloworldtootoo!!");//根据name info
②手动创建
//自己定义的sink
auto sink1 =make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto sink2 =make_shared<spdlog::sinks::basic_file_sink_mt>("lion.txt");
方便携带多个sink
auto logger1 =make_shared<spdlog::logger>("conslole1");
logger1->sinks().push_back(sink1);//把sink1加入
logger1->sinks().push_back(sink2);//把sink2加入
spdlog::register_logger(logger1);//把logger1绑定在register里
spdlog::get("conslole1")->info(("heloworldtootootoo!!"));
//sink1 接收器 在终端输出
//sink2 接收器 在输出到.txt文件里
注册logger,目的是为了全局访问
5.如何自定义格式
class my_formatter_flag : public spdlog::custom_flag_formatter
{
public:
void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override
{
std::string some_txt = "lion-flag";
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
}
std::unique_ptr<custom_flag_formatter> clone() const override
{
return spdlog::details::make_unique<my_formatter_flag>();
}
};
//formatter标识绑定
auto formatter = make_unique<spdlog::pattern_formatter>();
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n][%*][%^%l%$]%v");
sink1->set_formatter(std::move(formatter));
//sink1 --->formatter 自己添加的标识
//sink2 --->自己手动定义的pattern
sink2->set_pattern("[%^%l%$]%v");
sink1使用了formatter标识
sink2使用了set_pattern
6.创建异步日志的方法总结
线程池在异步日志的应用
spdlog::init_thread_pool(8292, 8);
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(sink1);
sinks.push_back(sink2);
auto logger_tp = std::make_shared<spdlog::async_logger>("tp", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::overrun_oldest);
logger_tp->info("hello thread pool");
logger_tp->info("hello thread pool");
logger_tp->flush();
logger_tp->flush_on(spdlog::level::err);
spdlog::flush_every(std::chrono::seconds(5));
综上所述,这段代码实现了一个异步日志记录系统,使用线程池来处理日志消息,将日志消息发送到多个日志接收器,并设置了不同的刷新策略来确保日志消息能够及时写入到日志接收器中。