OK,兄弟们,觉得好点点关注呀,需要你们的支持。
最近搞了个项目,500个线程一起跑,还需要将日志实时打印到控件上。
研究了一下spdlog,实现了,这里记一下。
目录
1.配置spdlog
首先下载spdlog库
https://github.com/gabime/spdlog
解压后,将目录下的spdlog文件夹直接复制到项目中
2.配置库文件
库文件是我自己写的,直接复制就好
#include "my_spdlog.h"
#include <spdlog/sinks/qt_sinks.h>
my_spdlog::my_spdlog()
{
log_file_created = false;
logger_droped = false;
}
void my_spdlog::create_log_file(QString file_name, QTextBrowser *textBrowser)
{
log_file_name = file_name.toStdString();
stringstream log_full_path;
log_full_path << LOG_PATH << log_file_name;
if(access(LOG_PATH, F_OK) != 0)
{
mkdir(LOG_PATH); //首先检查log目录是否存在,不存在则创建
}
log_file_created = true;
// 创建一个输出到文件的sink
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_full_path.str(), true);
auto qtSink = std::make_shared<spdlog::sinks::qt_sink_mt>(textBrowser, "append");
// 创建一个输出到控制台的sink
my_logger = std::make_shared<spdlog::logger>("my_logger", spdlog::sinks_init_list{file_sink, qtSink});
}
void my_spdlog::write_message(QString messages)
{
string str = messages.toStdString();
if(log_file_created != true) return;
my_logger->info(str);
my_logger->flush();
}
#ifndef MY_SPDLOG_H
#define MY_SPDLOG_H
#include <iostream>
#include <cstring>
#include <sstream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/logger.h"
#include <QString>
#include <QTextBrowser>
using namespace std;
#define LOG_PATH "./log/" //存在log的子目录
#define USE_LOG_FILE 1
class my_spdlog
{
public:
my_spdlog();
string log_file_name; //log文件名
std::shared_ptr<spdlog::logger> my_logger; //创建的logger指针
bool log_file_created; //Log文件已创建标志,以免有进程访问了不存在的Log file
bool logger_droped; //循环创建log文件时使用,此测试程序中暂未使用
void create_log_file(QString file_name, QTextBrowser *textBrowser);
void destroy_logger();
void write_message(QString messages);
};
#endif // MY_SPDLOG_H
3.库文件使用
这里简单讲一下文件使用
1.主函数中创建log实例,初始化时创建日志文件,并且将控件指针给库
2.需要写入日志的时候,调用该函数,将会同时在控件和文件中写入
4.多线程使用
(1)子线程中创建指针
(2)将主线程中创建的log实例付给子线程log指针,注意,子线程初始化时不要调用
create_log_fil函数,不然程序将会报错
(3)子线程写入日志
由于spdlog库支持多线程,所以不用担心资源抢占问题。