Qt开源作品21-日志重定向输出类

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

一、前言

用qt开发商业程序已经十年了,陆陆续续开发过至少几十个程序,除了一些算不算项目的小工具外,大部分的程序都需要有个日志的输出功能,希望可以将程序的运行状态存储到文本文件或者数据库或者做其他处理等,qt对这个日志输出也做了很好的封装,在Qt4是qInstallMsgHandler,Qt5里边是qInstallMessageHandler,有了这个神器,只要在你的项目中所有qdebug qinfo等输出的日志信息,都会重定向接收到,网上大部分人写的demo都是接收到输出打印日志存储到文本文件,其实这就带给很多人误解,容易产生以为日志只能输出到文本文件,其实安装了日志钩子以后,拿到了所有调试打印信息,你完全可以用来存储到数据库+html有颜色区分格式的文件+网络转发输出(尤其适用于嵌入式linux无界面程序,现场不方便外接调试打印的设备)。
做过的这么多项目中,Qt4和Qt5的都有,我一般保留四个版本,4.8.7,为了兼容qt4, 5.7.0,最后的支持XP的版本, 最新的长期支持版本5.9.7 最高的新版本5.12。毫无疑问,我要封装的这个日志类,也要支持4+5的,而且提供友好的接口。

主要功能:

  1. 支持动态启动和停止。
  2. 支持日志存储的目录。
  3. 支持网络发出打印日志。
  4. 支持Qt4+Qt5,开箱即用。
  5. 支持多线程。
  6. 使用做到最简单,start即可。

二、代码思路

//日志重定向
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
void Log(QtMsgType type, const char *msg)
#else
void Log(QtMsgType type, const QMessageLogContext &, const QString &msg)
#endif
{
    //加锁,防止多线程中qdebug太频繁导致崩溃
    QMutex mutex;
    QMutexLocker locker(&mutex);
    QString content;

    //这里可以根据不同的类型加上不同的头部用于区分
    switch (type) {
    case QtDebugMsg:
        content = QString("%1").arg(msg);
        break;

    case QtWarningMsg:
        content = QString("%1").arg(msg);
        break;

    case QtCriticalMsg:
        content = QString("%1").arg(msg);
        break;

    case QtFatalMsg:
        content = QString("%1").arg(msg);
        break;
    }

    SaveLog::Instance()->save(content);
}

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

    return self.data();
}

SaveLog::SaveLog(QObject *parent) : QObject(parent)
{
    //必须用信号槽形式,不然提示 QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
    //估计日志钩子可能单独开了线程
    connect(this, SIGNAL(send(QString)), SendLog::Instance(), SLOT(send(QString)));

    file = new QFile(this);
    toNet = false;
    //默认取应用程序根目录
    path = qApp->applicationDirPath();
    //默认取应用程序可执行文件名称
    QString str = qApp->applicationFilePath();
    QStringList list = str.split("/");
    name = list.at(list.count() - 1).split(".").at(0);
    fileName = "";
}

SaveLog::~SaveLog()
{
    file->close();    
}

//安装日志钩子,输出调试信息到文件,便于调试
void SaveLog::start()
{
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
    qInstallMsgHandler(Log);
#else
    qInstallMessageHandler(Log);
#endif
}

//卸载日志钩子
void SaveLog::stop()
{
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
    qInstallMsgHandler(0);
#else
    qInstallMessageHandler(0);
#endif
}

void SaveLog::save(const QString &content)
{
    //如果重定向输出到网络则通过网络发出去,否则输出到日志文件
    if (toNet) {
        emit send(content);
    } else {
        //方法改进:之前每次输出日志都打开文件,改成只有当日期改变时才新建和打开文件
        QString fileName = QString("%1/%2_log_%3.txt").arg(path).arg(name).arg(QDATE);
        if (this->fileName != fileName) {
            this->fileName = fileName;
            if (file->isOpen()) {
                file->close();
            }

            file->setFileName(fileName);
            file->open(QIODevice::WriteOnly | QIODevice::Append | QFile::Text);
        }

        QTextStream logStream(file);
        logStream << content << "\n";
    }
}

三、效果图

savelog

四、开源主页

以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。

  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 个人主页:https://blog.csdn.net/feiyangqingyun
  4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5天前
|
存储 人工智能 JSON
RAG Logger:专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、性能监控
RAG Logger 是一款专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、检索结果记录、LLM 交互记录和性能监控等功能。
28 7
RAG Logger:专为检索增强生成(RAG)应用设计的开源日志工具,支持查询跟踪、性能监控
|
16天前
|
人工智能 监控 算法
3D-Speaker:阿里通义开源的多模态说话人识别项目,支持说话人识别、语种识别、多模态识别、说话人重叠检测和日志记录
3D-Speaker是阿里巴巴通义实验室推出的多模态说话人识别开源项目,结合声学、语义和视觉信息,提供高精度的说话人识别和语种识别功能。项目包含工业级模型、训练和推理代码,以及大规模多设备、多距离、多方言的数据集,适用于多种应用场景。
142 18
3D-Speaker:阿里通义开源的多模态说话人识别项目,支持说话人识别、语种识别、多模态识别、说话人重叠检测和日志记录
|
9天前
|
JSON 安全 API
.net 自定义日志类
在.NET中,创建自定义日志类有助于更好地管理日志信息。示例展示了如何创建、配置和使用日志记录功能,包括写入日志文件、设置日志级别、格式化消息等。注意事项涵盖时间戳、日志级别、JSON序列化、线程安全、日志格式、文件处理及示例使用。请根据需求调整代码。
36 13
|
13天前
|
人工智能 算法 数据挖掘
开源更新|通义3D-Speaker多说话人日志功能
开源更新|通义3D-Speaker多说话人日志功能
|
2月前
|
存储 运维 监控
开源日志Graylog
【10月更文挑战第21天】
251 8
|
2月前
|
存储 监控 安全
|
2月前
|
存储 数据采集 监控
开源日志Fluentd
【10月更文挑战第21天】
53 7
|
2月前
|
存储 数据采集 监控
开源日志分析Elasticsearch
【10月更文挑战第22天】
52 5
|
2月前
|
机器学习/深度学习 运维 监控
开源日志分析Kibana
【10月更文挑战第22天】
54 3
|
2月前
|
存储 JSON 监控
开源日志分析Logstash
【10月更文挑战第22天】
65 1

推荐镜像

更多
下一篇
开通oss服务