qt客户端技术杂谈-日志库01

一、日志库选型

日志库现在有很多,c++中较为出名的有log4cxx、spdlog等,但qt中要是用的不是很复杂,可以采用qt自带的日志机制,方便且实用

二、qt日志机制实现

  1. 实现一个注册函数
    void DemoLog::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)

  2. 注册
    qInstallMessageHandler(outputMessage);//注册MsgHandler回调函数

  3. 注意要点
    qt机制不难,但是要想项目中实际使用,还必须考虑到线程安全、日志堆积问题后台调用日志显示等

  4. 下面实现一个实际项目使用的日志类,示例如下:

DemoLog g_DemoLog;

DemoLog::DemoLog(QObject *parent)
    :QObject(parent),
      m_mutex(QMutex::Recursive),
      m_backConsole(false)//用来控制是否在指定控制台界面输出日志信息
{
}

DemoLog::~DemoLog()
{

}

void DemoLog::initLog(const bool &bConsole, const QString &strFilePath)
{
    qInstallMessageHandler(outputMessage);//注册MsgHandler回调函数
//多线程安全
    QMutexLocker locker(&m_mutex);

    m_bConsole = bConsole;
    m_strFilePath = strFilePath;
    QJsonObject jsonLog = CommonUtils::readJsonFromFile(QApplication::applicationDirPath() + "/config/configSystem.json");
    m_bNeedLog = jsonLog.value("Skey_LogNeed").toBool(true);
    m_nMaxCountLogFile = jsonLog.value("SKey_LogDate").toInt(30);

    QString strLogPath = QApplication::applicationDirPath() + strFilePath;
    deleteLogFile(strLogPath, m_nMaxCountLogFile);
    //corefile clear
    deleteLogFile("/corefile", m_nMaxCountCoreFile);
    QDir dirLog(strLogPath);
    if (!dirLog.exists())
    {
        dirLog.mkpath(strLogPath);
    }

    QDateTime noeDate = QDateTime::currentDateTime();
    QString strBuf = QString("%1_0.log").arg(noeDate.toString("yyyyMMdd-hhmmss"));
    m_strFileName = QString("%1/%2").arg(strLogPath).arg(strBuf);
    m_strBaseFileName = m_strFileName;
}

void DemoLog::setBackConsole(const bool &bStatus)
{
    m_backConsole.store(bStatus);
}

void DemoLog::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
//真正的日志处理函数
    g_DemoLog.processMsg(type, context, msg);
}

void DemoLog::processMsg(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Q_UNUSED(context);
    QMutexLocker locker(&m_mutex);

    const qint64 M = 5 * 1024 *1024;
    qint64 fileSize = QFileInfo(m_strFileName).size();

    if (fileSize > M)
    {
        m_nLogNum++ ;
        if (m_nLogNum == INT32_MAX)
        {
            m_nLogNum = 0;
        }
        m_strFileName = m_strBaseFileName.left(m_strBaseFileName.length() - 4) + QString::number(m_nLogNum) + ".log";
        //clear log and corefile
        QString strLogPath = QApplication::applicationDirPath() + m_strFilePath;
        deleteLogFile(strLogPath, m_nMaxCountLogFile);
        deleteLogFile("/corefile", m_nMaxCountCoreFile);
    }

    QDateTime nowDate = QDateTime::currentDateTime();
    QString strMsgLog = QString("[%1] %2").arg(nowDate.toString("yyyy-MM-dd hh:mm:ss:zzz")).arg(msg);
    strMsgLog.replace("\\n", "\n");
    //for devloper
    if (m_bConsole && type != QtDebugMsg)
    {
        QString strConsole = QString("%1 %2\n").arg(CYAN, strMsgLog);
        std::cout << strConsole.toUtf8().data() << std::endl;
    }

    //for log file
    if (!m_bNeedLog)
    {
        return;
    }

    ObjectPtr<IBackConsoleController> backConsoleController;
    if (backConsoleController.operator bool() && m_backConsole.load())
    {
    //需要显示日志信息的界面执行显示操作
        QMetaObject::invokeMethod(backConsoleController->getObject(),
                                  "sltTextBrowerText",
                                  Q_ARG(QString, strMsgLog + "\r\n\r\n"));
    }
    QFile file(m_strFileName);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream << strMsgLog << "\r\n\r\n";

    file.close();
}

void DemoLog::deleteLogFile(const QString &strDir, const int& nCount)
{
    QDir dir(strDir);
    dir.setFilter(QDir::Files);

    QList<QFileInfo> fileInfoList = dir.entryInfoList();

    if(fileInfoList.size() > nCount)
    {
        std::sort(fileInfoList.begin(),fileInfoList.end(),[](const QFileInfo &a,const QFileInfo &b)
        {
            return a.lastModified() > b.lastModified();
        });

        for(int i = nCount; i < fileInfoList.size();i++)
        {
            dir.remove(fileInfoList.at(i).fileName());
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值