使用spdlog接管QT的打印,封装日志宏

一、源码

logoutput.h

#ifndef LOGOUTPUT_H
#define LOGOUTPUT_H

#include <QObject>
#include <spdlog/spdlog.h>

// 全局 spdlog logger
extern std::shared_ptr<spdlog::logger> qspdLogger;

// 用法1:接管qt的打印信息
class logOutput : public QObject
{
    Q_OBJECT
public:
    static logOutput *Instance();
    explicit logOutput(QObject *parent = 0);
    ~logOutput();

public:
    void start();                           // 安装日志钩子
    void stop();                            // 卸载日志钩子
private:
    static QScopedPointer<logOutput> m_self;
    bool m_isRun;

    QString m_filename; // 文件名
    int  m_maxSize;    // 文件最大大小 单位kb
};

//用法2:封装宏,方便直接使用spdlog
#define LOG_TRACE(format,...) qspdLogger->trace(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);
#define LOG_DEBUG(format,...) qspdLogger->debug(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);
#define LOG_INFO(format,...)  qspdLogger->info(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);
#define LOG_WARN(format,...)  qspdLogger->warn(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);
#define LOG_ERROR(format,...) qspdLogger->error(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);
#define LOG_FATAL(format,...) qspdLogger->critical(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__);

#endif // LOGOUTPUT_H

logoutput.cpp

#include "logoutput.h"
#include <QMutex>
#include <spdlog/sinks/rotating_file_sink.h>

// 全局 spdlog logger
std::shared_ptr<spdlog::logger> qspdLogger;

// 自定义消息处理函数
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Q_UNUSED(context)
    // 将 QString 转换为 UTF-8 编码的 std::string
    QByteArray byteArray = msg.toUtf8();
    std::string utf8Msg(byteArray.constData(), byteArray.size());

    switch (type) {
    case QtDebugMsg:
        qspdLogger->debug(utf8Msg);
        break;
    case QtInfoMsg:
        qspdLogger->info(utf8Msg);
        break;
    case QtWarningMsg:
        qspdLogger->warn(utf8Msg);
        break;
    case QtCriticalMsg:
        qspdLogger->critical(utf8Msg);
        break;
    case QtFatalMsg:
        qspdLogger->critical(utf8Msg);
        abort();
    }
}

QScopedPointer<logOutput> logOutput::m_self;
logOutput *logOutput::Instance()
{
    if (m_self.isNull()) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (m_self.isNull()) {
            m_self.reset(new logOutput);
        }
    }

    return m_self.data();
}

logOutput::logOutput(QObject *parent) : QObject(parent)
{
    m_isRun = false;
}

logOutput::~logOutput()
{
}

//安装钩子
void logOutput::start()
{
    if (m_isRun)
        return;

    m_isRun = true;

    // 初始化 spdlog,日志文件:/log/server.log,大小:10MB,保留数量:20
    qspdLogger = spdlog::rotating_logger_mt("file_logger", "log/log.txt", 10*1024*1024, 20);
    spdlog::set_level(spdlog::level::debug);
    spdlog::flush_on(spdlog::level::debug);
    spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e [%l] %v");
    qInstallMessageHandler(outputMessage);
}

//卸载钩子
void logOutput::stop()
{
    if (!m_isRun)
        return;

    m_isRun = false;
    qInstallMessageHandler(0);
}

二、使用方法

1.在main中,或者自己的初始化函数中增加如下语句:

logOutput::Instance()->start();

2.有2种打印方式

方式1:使用QT自带的打印语句,如qDebug、qInfo等

QString a = "test";
int b;
qDebug() << "test" << a << b;

方式2:使用LOG宏定义语句

std::string a;
int b;
LOG_ERROR("a:{},b:{}", a, b);

3.如果spdlog用了我的扩展版(扩展spdlog1.15.0,适配QString和msvc2015-优快云博客),宏定义也可支持QString的输出

std::string a;
int b;
QString qstr;
LOG_ERROR("a:{},b:{},QString:{}", a, b, qstr);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值