QT随手记系列——多线程日志spdlog,同时输出到控件和日志文件

OK,兄弟们,觉得好点点关注呀,需要你们的支持。

最近搞了个项目,500个线程一起跑,还需要将日志实时打印到控件上。

研究了一下spdlog,实现了,这里记一下。

目录

1.配置spdlog

2.配置库文件

3.库文件使用

4.多线程使用


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库支持多线程,所以不用担心资源抢占问题。

要将spdlog输出Qt表格上,您需要执行以下步骤: 1. 创建一个继承自QAbstractTableModel的类,用于管理表格数据。 2. 在该类中实现rowCount()、columnCount()、data()等函数,以便管理表格数据。 3. 创建一个spdloglogger,用于日志。 4. 创建一个继承自spdlog::sinks::sink的类,用于将日志输出到表格上。 5. 在该类中实现log()函数,将日志数据添加到表格中。 6. 将该sink添加到logger中,以便将日志输出到表格上。 以下是一个示例代码: ``` // MyTableModel.h class MyTableModel : public QAbstractTableModel { public: MyTableModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; void addLog(const QString &log); private: QList<QString> m_logs; }; // MyTableModel.cpp MyTableModel::MyTableModel(QObject *parent) : QAbstractTableModel(parent) { } int MyTableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) return m_logs.count(); } int MyTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return 1; } QVariant MyTableModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::DisplayRole) return m_logs.at(index.row()); return QVariant(); } void MyTableModel::addLog(const QString &log) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_logs << log; endInsertRows(); } // MySink.h class MySink : public spdlog::sinks::sink { public: MySink(MyTableModel *tableModel); void log(const spdlog::details::log_msg &msg) override; void flush() override; private: MyTableModel *m_tableModel; }; // MySink.cpp MySink::MySink(MyTableModel *tableModel) : m_tableModel(tableModel) { } void MySink::log(const spdlog::details::log_msg &msg) { QString log = QString::fromStdString(msg.formatted); m_tableModel->addLog(log); } void MySink::flush() { // do nothing } // main.cpp int main(int argc, char *argv[]) { QApplication app(argc, argv); MyTableModel tableModel; MySink sink(&tableModel); spdlog::logger logger("my_logger", &sink); logger.set_level(spdlog::level::trace); logger.trace("This is a trace message."); logger.debug("This is a debug message."); logger.info("This is an info message."); logger.warn("This is a warning message."); logger.error("This is an error message."); QTableView tableView; tableView.setModel(&tableModel); tableView.show(); return app.exec(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值