qt中使用日志系统,自定义日志彩色输出,qt日志写入文件,自定义qt日志格式,同时提供Qt日志重定向功能(将qDebug信息输出到界面控件)

一、介绍

在qt中要使用qt自带的日志系统我们都知道实现回调函数QtMessageHandler,再用qInstallMessageHandler函数进行注册:

// 注册日志处理
qInstallMessageHandler();

同时在pro文件中加入:

DEFINES += QT_MESSAGELOGCONTEXT # 日志

题外话:一般在商业项目中,我们可能不会使用qt的日志系统,而是会采用第三方的日志系统,比如常用语java后端的log4j,在qt中有Log4Qt,这篇文章很详细:https://blog.youkuaiyun.com/robert_cysy/article/details/105446185

二、实现

基于此我们就可以写出我们自定义的日志系统了,我写的这个日志系统具有以下特点:

1、支持设置日志输出路径

2、支持日志打印格式设置

3、支持不同日志级别的不同样式设置

4、支持3种日志备份策略,采用延迟策略,不是用定时器实现周期备份,而是在具体打印内容时才触发,这么做的目的是减少定时的开销

5、支持分日志类型备份日志

6、支持备份策略参数的json文件地址存储自定义

7、支持回调函数注册,便于一些想将日志输出到自己项目界面展示的小伙伴

下面是我的实现,我们只需要引入相应的h和cpp文件即可:

log.h

#ifndef LOG_H
#define LOG_H

#include <QApplication>
#include <QReadWriteLock>
#include <QFile>

/**
 * @brief The Color class 颜色设置
 */
class ConsoleFont {
public:
    const static int DEFAULT; // 重置颜色设置
    const static int BOLD; // 加粗
    const static int UN_BOLD; // 去粗
    const static int UNDER_LINE; // 下滑线
    const static int GLINT; // 闪烁
    const static int INVERSE;// 反色
    const static int BOLD_2; // 加粗
    const static int NORMAL ; // 正常
    const static int UN_UNDER_LINE; // 去掉下滑线
    const static int STOP_GLINT; // 停止闪烁
    const static int INVERSE_2;// 反色

    const static int FORE_GROUND_BLACK;// 前景,黑色
    const static int FORE_GROUND_RED;// 前景,红色
    const static int FORE_GROUND_GREEN;// 前景,绿色
    const static int FORE_GROUND_ORANGE;// 前景,黄色
    const static int FORE_GROUND_BLUE; //前景,篮色
    const static int FORE_GROUND_PURPLE; //前景,紫色
    const static int FORE_GROUND_CYAN; //前景,青色
    const static int FORE_GROUND_WHITE; //前景,白色

    const static int BACK_GROUND_BLACK;// 背景,黑色
    const static int BACK_GROUND_RED;// 背景,红色
    const static int BACK_GROUND_GREEN;// 背景,绿色
    const static int BACK_GROUND_ORANGE;// 背景,黄色
    const static int BACK_GROUND_BLUE; //背景,篮色
    const static int BACK_GROUND_PURPLE; //背景,紫色
    const static int BACK_GROUND_CYAN; //背景,青色
    const static int BACK_GROUND_WHITE; //背景,白色

    /**
     * @brief setConsoleFont 设置控制台字体样式
     * @param codes 字体样式code集合,用{}设置数组的方式进行传参
     * @param msg 信息
     * @return 设置样式后的内容
     */
    const static QString setConsoleFont(std::initializer_list<int> codes, QString msg);
};

/**
 * @brief The LogType enum 日志输出类型
 */
enum LogOutType {
    STANDARD_OUTPUT, // 标准输出流
    STANDARD_ERROR_OUTPUT // 标准错误输出流
};

/**
 * @brief The LogSwitchoverType enum 日志切换方式(即备份方式)
 */
enum LogSwitchoverType{
    ALL_DAY, // 指定天数备份,即相隔天数的凌晨00:00:00(对应单位是天d)
    TIME_PERIOD, // 指定时间间隔备份,即从项目启动开始后的间隔时间周期(对应单位是秒s)
    FILE_SIZE // 指定文件大小备份(对应单位是kb)
};


/**
 * 回调函数,日志类型、日志上下文,日志信息、格式化之后的信息,传入对象上下文
 */
typedef void (*LogInfoCallBackHandler)(QtMsgType, const QMessageLogContext &, const QString &,const QString &,void *);

/**
 * @brief The CallBackInfo class 回调信息
 */
class CallBackInfo{
public:
    CallBackInfo() {}
    CallBackInfo(QString unique, LogInfoCallBackHandler hander, void* context) {
        this->unique = unique;
        this->hander = hander;
        this->context = context;
    }
    QString unique; // 唯一标识
    LogInfoCallBackHandler hander; // 回调函数
    void* context; // 对象上下文
};

/**
 * 回调信息线程安全集合
 */
class CallBackInfoSafeList{
public:
    CallBackInfoSafeList() {}
    void add(CallBackInfo info){
        QWriteLocker lock(readWriteLock);
        this->mList.append(info);
    }
    QList<CallBackInfo> getList(){
        QReadLocker lock(readWriteLock);
        return mList;
    }
    CallBackInfo get(int index){
        QReadLocker lock(readWriteLock);
        return mList.value(index);
    }
private:
    QList<CallBackInfo> mList; // 回调信息集合
    mutable QReadWriteLock *readWriteLock = new QReadWriteLock(); // 读写锁
};

/**
 * @brief The Log class 日志
 */
class Log
{
public:
    Log() {}
    const static QString INFO_FORMAT_TIME; // 格式化输出日期表示
    const static QString INFO_FORMAT_LEVEL; // 格式化输出日志级别表示
    const static QString INFO_FORMAT_CODE_FILE; // 格式化输出代码文件地址表示
    const static QString INFO_FORMAT_CODE_LINE; // 格式化输出代码所在行表示
    const static QString INFO_FORMAT_CODE_FUNCTION; // 格式化输出代码所在方法函数表示
    const static QString INFO_FORMAT_CODE_MSG; // 格式化输出代码打印内容表示

    /**
     * @brief setFormat 设置日志输出内容格式化
     * @param infoFormat 内容格式化参数
     * @param timeFormat 日期格式化
     */
    static void setFormat(QString infoFormat, QString timeFormat = "yyyy-MM-dd hh:mm:ss:zzz");
    /**
     * @brief setLevelColor 设置不同日志级别的字体格式
     * @param type 日志类型
     * @param levelColor 字体格式
     */
    static void setLevelFont(QtMsgType type, std::initializer_list<int> levelFont);
    /**
     * @brief setOutLogPath 设置输出地址
     * @param outLogPath 日志输出地址
     */
    static void setOutLogPath(QString outLogPath);
    /**
     * @brief setOutLogParamPath 设置日志备份参数json存储地址
     * @param logParamPath 日志备份参数json存储地址
     */
    static void setOutLogParamJsonPath(QString logParamJsonPath);
    /**
     * @brief setLogSwitchover 设置日志切换备份方式
     * @param logSwitchoverType 日志备份类型
     * @param switchoverNum 备份时间或大小(ALL_DAY则是天数;TIME_PERIOD是时间间隔,单位秒;FILE_SIZE是文件大小,单位时kb)
     */
    static void setLogSwitchover(LogSwitchoverType logSwitchoverType, long long switchoverNum);
    /**
     * @brief setDistinguishLevel 设置备份输出是否区分日志级别单独输出
     * @param isDistinguishLevel 是否区分
     */
    static void setDistinguishLevel(bool isDistinguishLevel);
    /**
     * @brief messageOutput 日志输出注册函数
     * @param type 日志信息类型
     * @param context 日志信息上下文
     * @param msg 输出内容信息
     */
    static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
    /**
     * @brief registLogInfoCallBack 注册回调函数,注册函数使用链式调用,只要注册的函数都会进行调用
     * @param unique 唯一标识
     * @param hander 回调函数
     * @param contex 上下文,可以传入自己想操作的对象
     * @return
     */
    static LogInfoCallBackHandler registLogInfoCallBack(QString unique, LogInfoCallBackHandler hander,void* context = nullptr);
private:
    /**
     * @brief msgTypeMap 日志类型与标识、输出类型映射
     */
    static QMap<QtMsgType,QPair<QString, LogOutType>> msgTypeMap;
    /**
     * @brief levelFontMap 针对不同日志级别的字体显示设置映射
     */
    static QMap<QtMsgType,std::initializer_list<int>> levelFontMap;
    /**
     * @brief logSwitchoverTypeMap 备份类型与字符的映射
     */
    static QMap<LogSwitchoverType, QString> logSwitchoverTypeMap;
    /**
     * @brief outLogFile 输出file
     */
    static QFile* outLogFile;
    /**
     * @brief levelPaths 不同级别对应的输出路径
     */
    static QMap<QtMsgType, QFile*> levelPaths;
    /**
     * @brief isDistinguishLevel 是否区分日志级别输出
     */
    static bool isDistinguishLevel;
    /**
     * @brief infoFormat 日志输出内容格式化参数
     */
    static QString infoFormat;
    /**
     * @brief timeFormat 日期格式
     */
    static QString timeFormat;
    /**
     * @brief logParamJsonFile 日志备份策略参数保存json文件
     */
    static QFile* logParamJsonFile;
    /**
     * @brief logSwitchoverType 指定备份类型
     */
    static LogSwitchoverType logSwitchoverType;
    /**
     * @brief switchoverNum 指定备份时间或大小
     */
    static long long switchoverNum;
    /**
     * @brief switchoverTime 备份切换时间
     */
    static QDateTime switchoverTime;
    /**
     * @brief isLoadLogSwitchoverSetting 是否加载备份日志设置
     */
    static bool isLoadLogSwitchoverSetting;
    /**
     * @brief pCallback 存放回调函数的集合
     */
    static CallBackInfoSafeList pCallbacks;


    /**
     * @brief initMsgTypeMap 初始化日志类型与标识、输出类型映射
     * @return 日志类型与标识、输出类型映射
     */
    static QMap<QtMsgType,QPair<QString, LogOutType>> initMsgTypeMap();
    /**
     * @brief initLevelColors 初始化不同日志级别的字体显示设置映射
     */
    static QMap<QtMsgType,std::initializer_list<int>> initLevelFonts();
    /**
     * @brief initLogSwitchoverTypeMap 初始化备份类型与字符的映射
     */
    static QMap<LogSwitchoverType, QString> initLogSwitchoverTypeMap();
    /**
     * @brief writeLog 输出日志内容到文件
     * @param str 日志内容
     * @param QtMsgType 日志类型
     */
    static void writeLog(QString str, QtMsgType msgType);
    /**
     * @brief loadLogSwitchoverSetting 加载日志备份设置
     */
    static void loadLogSwitchoverSetting();
    /**
     * @brief logSwitchoverSettingHander 日志备份设置处理
     */
    static void logSwitchoverSettingHander();
    /**
     * @brief writeLogParamJson 向json文件中写入备份参数
     */
    static void writeLogParamJson();
    /**
     * @brief copyLogOutFile 备份日志文件
     */
    static void copyLogOutFile(QtMsgType msgType);
    /**
     * @brief copy 拷贝文件,目标文件存在则覆盖
     * @param srcFilepPath 源文件
     * @param targetFilePath 目标文件
     * @param 拷贝成功与否
     */
    static bool copy(QString srcFilepPath, QString targetFilePath);
    /**
     * @brief replace 替换字符串
     * @param src 原字符串
     * @param before 被替换的字符串
     * @param after 替换字符串
     * @return 被替换之后的字符串
     */
    static QString replace(QString src, QString before, QString after);
    /**
     * @brief isContainInfoFormat 判断是否包含格式化信息
     * @return 包含与否
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值