分享一个Qt日志管理的代码

分享一个Qt日志管理的代码

概要

Qt日志打印功能的代码很多,但好用的很少。先分享一个自己很喜欢功能代码

技术细节

介绍
分享一个Qt日志管理的代码_第1张图片
项目目录截图如上

代码
Log.pro

QT -= gui
TEMPLATE = lib
DEFINES += LOG_LIBRARY
CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    Log.cpp
HEADERS += \
#    Log_global.h \
    Log.h
    
# Default rules for deployment.
unix {
    target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

Log.h

//#pragma once

//#include "Log_global.h"
#pragma once

#include 

#if defined(LOG_LIBRARY)
#  define LOG_EXPORT Q_DECL_EXPORT
#else
#  define LOG_EXPORT Q_DECL_IMPORT
#endif

#include 
#include 

class LOG_EXPORT Log
{
public:
    static Log& instance();
public:
    virtual void outputRaw(const QString& message, bool isError = false) = 0;
    virtual void setPath(const QString& path) = 0;
    virtual void setThreashold(QtMsgType msgType) = 0;
    virtual QString path() const = 0;
    virtual QtMsgType messageType() const = 0;
    virtual void start(const QString& path = {}) = 0;
    virtual void stop() = 0;
    virtual void setFunllMessage(bool fullMessage) = 0;
};

Log.cpp

#include "Log.h"
#include 
#include 
#include 
#include 
#include 
#include 

class LogImpl: public Log {
public:
    static LogImpl& instance(){
        static LogImpl theInstance;
        return  theInstance;
    }
    ~LogImpl(){
        stop();
    }

public:
    void outputRaw(const QString &message, bool isError)
        {
            if(isError)
            {
                std::cerr<<qPrintable(message)<<std::endl;
                std::cerr.flush();
            }
            else
            {
                std::cout<<qPrintable(message)<<std::endl;
                std::cout.flush();
            }
            QMutexLocker locker(&mutext_);
            if(file_)
            {
                file_->write(message.toUtf8());
                file_->write("\n");
                file_->flush();
            }
        }
        void setPath(const QString &path){
            QMutexLocker locker(&mutext_);
            path_ = path;
            QDir().mkpath(path_);
            if(file_){
                delete file_;
                file_ = nullptr;
            }
        }
        void setThreashold(QtMsgType msgType)
        {
            QMutexLocker locker(&mutext_);
            messageType_ = msgType;
        }
        QString path() const
        {
            return  path_;
        }
        QtMsgType messageType() const
        {
            return  messageType_;
        }
        void start(const QString &path)
        {
            if(!path.isEmpty())
                setPath(path);
            QMutexLocker locker(&mutext_);
            if(file_) return;
            if(!qApp) return;
            QString filePath = path_ + "/" + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss") + ".log";
            file_ = new QFile(filePath);
            if(!file_->open(QFile::Text | QFile::Truncate | QFile::WriteOnly))
            {
                std::cerr <<" cannot open log file : " << filePath.toStdString() << std::endl;
                delete file_;
                file_ = nullptr;
            }
            qInstallMessageHandler(messageOutput);
        }
        void stop()
        {
            QMutexLocker locker(&mutext_);
            if(file_)
            {
                file_->close();
                delete file_;
                file_ = nullptr;
            }
        }
        void setFunllMessage(bool fullMessage){
            QMutexLocker locker(&mutext_);
            fullMessage_ = fullMessage;
        }

    private:

        static void messageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
            {
                const char* file = context.file ? context.file : "";
                const char* function = context.function ? context.function : "";
                QString output;
                if(instance().fullMessage_)
                {
                    output = QString("%1 %2:%3[%4] %5").arg(QDateTime::currentDateTime().toString("MM-dd hh:mm:ss:zzz"))
                            .arg(file).arg(function).arg(context.line).arg(msg);
                }
                else {
                    if(auto s = strchr(file, '\\')) file = s + 1;
                    else if (auto s = strchr(file, '/')) file = s + 1;
                    output = QString("%1 %2[%3] %4").arg(QDateTime::currentDateTime().toString("MM-dd hh:mm:ss:zzz"))
                            .arg(file).arg(context.line).arg(msg);
                }
                if((int) type < (int)LogImpl::instance().messageType_)
                    return ;
                switch (type)
                {
                case QtDebugMsg: LogImpl::instance().outputRaw("[D]" + output, false); break;
                case QtInfoMsg: LogImpl::instance().outputRaw("[I]" + output, false); break;
                case QtWarningMsg: LogImpl::instance().outputRaw("[W]" + output, true); break;
                case QtCriticalMsg: LogImpl::instance().outputRaw("[E]" + output, false); break;
                case QtFatalMsg: LogImpl::instance().outputRaw("[F]" + output, false); break;
                }
            }

private:
    static inline bool destroyed_ = false;

    QMutex mutext_;
    QString path_;
    QtMsgType messageType_ = QtDebugMsg;
    bool fullMessage_ = false;
    QFile *file_ = nullptr;
};

Log &Log::instance()
{
    return LogImpl::instance();
}

使用方法:在项目main.cpp中,引入头文件,然后调用单例。

main.cpp

#include "MainWindow.h"
#include 
#include 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Log::instance().start(a.applicationDirPath()+"/../data/log/"+a.applicationName()+"/");
    MainWindow w;
    w.show();
    return a.exec();
}

小结

可输出详细信息或者简单信息。

简单的做一下记录。

你可能感兴趣的:(qt,开发语言)