Qt 之 qDebug() 自定义log

需求

  • GUI log分登记
  • GUI log记入文件
  • GUI log每个文件大小限制在1M
  • GUI log共10个文件,回滚覆盖写入
  • GUI log最新的日志总是计入xxx.0.log, 依次xxx.1.log, xxx.2.log, 依次类推

Qt 调试信息

qDebug() 		//调试消息
qInfo() 		//信息消息
qWarning() 		//警告消息
qCritical() 	//错误消息
qFatal() 		//致命错误消息

默认环境下输出的调试信息

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 打印信息
    qDebug() << "This is a debug message";
    qDebug("This is a debug message");
    qInfo("This is a info message");
    qWarning("This is a warning message");
    qCritical("This is a critical message");
    qFatal("This is a fatal message");
    
    return a.exec();
}

输出结果如下所示:

This is a debug message
This is a debug message
This is a info message
This is a warning message
This is a critical message
This is a fatal message

安装自定义的消息处理程序

先看下官方给的例子

#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    const char *file = context.file ? context.file : "";
    const char *function = context.function ? context.function : "";
    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtInfoMsg:
        fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtWarningMsg:
        fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtCriticalMsg:
        fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    case QtFatalMsg:
        fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
        break;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // 安装消息处理程序
    auto front = qInstallMessageHandler(myMessageOutput);
    // 打印信息
    qDebug() << "This is a debug message";
    qDebug("This is a debug message");
    qInfo("This is a info message");
    qWarning("This is a warning message");
    qCritical("This is a critical message");
    qFatal("This is a fatal message");
    
    return a.exec();
}

  • 输出结果
Debug: This is a debug message (…\main.cpp:89, int __cdecl main(int,char *[]))
Info: This is a info message (…\main.cpp:90, int __cdecl main(int,char *[]))
Warning: This is a warning message (…\main.cpp:91, int __cdecl main(int,char *[]))
Critical: This is a critical message (…\main.cpp:92, int __cdecl main(int,char *[]))
Fatal: This is a fatal message (…\main.cpp:93, int __cdecl main(int,char *[]))

自定义输出格式

通过上述输出结果,可以发现,通过自定义格式,可以让log按找自己想要的结果来记录,比如time, pid, tid, fun, line等信息

enum class LogType {
        Reset = 0,

        Bold,
        Unbold,

        FrontBlack,
        FrontRed,
        FrontGreen,
        FrontYellow,
        FrontBlue,
        FrontPurple,
        FrontCyan,
        FrontWhite,
        BackBlack,
        BackRed,
        BackGreen,
        BackYellow,
        BackBlue,
        BackPurple,
        BackCyan,
        BackWhite,

        TypeCount
    };

    static const char *logCommands[] = {
        "\033[0m",  "\033[1m",  "\033[2m",  "\033[30m", "\033[31m",
        "\033[32m", "\033[33m", "\033[34m", "\033[35m", "\033[36m",
        "\033[37m", "\033[40m", "\033[41m", "\033[42m", "\033[43m",
        "\033[44m", "\033[45m", "\033[46m", "\033[47m",
    };
//自定义消息类型字符串
static const char *msgType[] = {"Debug", "Warning", "Critical", "Fatal",
                                    "Info"};
//自定义消息处理函数
void customMessageHandler(QtMsgType type, const QMessageLogContext &context,const QString &msg) {
        const char *file = context.file ? context.file : "default";
        const char *function = context.function ? context.function : "default";
        
        if (msg.isNull() || msg.isEmpty()) {
            return;
        }

        //获取进程码
        static auto pid = getpid();
        //获取线程PID
        static thread_local auto tid = syscall(__NR_gettid);

        QString logInfo =
            QString::fromLocal8Bit("[%1] %2 %3 [%4] [%5] [%6] [%7] %8")
              .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"))
              .arg(pid)
              .arg(tid)
              .arg(msgType[type])
              .arg(function)
              .arg(context.line)
              .arg(msg.toUtf8().data());
              
 		switch (type) {
        case QtDebugMsg:
            qInfo().noquote() << logCommands[enumToInt(LogType::FrontPurple)]
                              << logInfo << logCommands[0];
            htQLog::debug(logInfo);  //自定义的处理函数
            break;
        case QtInfoMsg:
            qInfo().noquote() << logCommands[enumToInt(LogType::FrontGreen)]
                              << logInfo << logCommands[0];
            htQLog::info(logInfo);
            break;
        case QtWarningMsg:
            qInfo().noquote() << logCommands[enumToInt(LogType::FrontYellow)]
                              << logInfo << logCommands[0];
            htQLog::warning(logInfo);
            break;
        case QtCriticalMsg:
            qInfo().noquote() << logCommands[enumToInt(LogType::FrontRed)]
                              << logCommands[enumToInt(LogType::Bold)] << logInfo
                              << logCommands[0];
            htQLog::critical(logInfo);
            break;
        case QtFatalMsg:
            qInfo().noquote() << logCommands[enumToInt(LogType::FrontRed)]
                              << logCommands[enumToInt(LogType::Bold)] << logInfo
                            << logCommands[0];
            htQLog::fatal(logInfo);
            break;
        default:
            break;
        }
    }

超级终端的字体背景和颜色显示

# man console_codes  //查看支持哪些颜色
printf(“\033[0;30;41m color!!! \033[0m Hello \n”);

其中41的位置代表字的背景色, 30的位置是代表字的颜色,0 是字的一些特殊属性,0代表默认关闭,一些其他属性如闪烁、下划线等。ascii code 是对颜色进行调用的。
\033[ ; m …… \033[0m
  颜色的控制通过ESC字符(\033)加”[“加颜色代码加”m”实现。ESC的ASCII码是十进制的27,八进制的033(\033)

在 ANSI 兼容终端里,可以用彩色显示文本而不仅仅是黑白。但是我们自己编写的程序能否输出彩色的字符呢?当然答案是肯定的。下面的语句就输出高亮的黑色背景的绿色字。
\033 声明了转义序列的开始,然后是 [ 开始定义颜色。后面的 1 定义了高亮显示字符。然后是背景颜色,这里面是40,表示黑色背景。接着是前景颜色,这里面是32,表示绿色。我们用 \033[0m 关闭转义序列, \033[0m 是终端默认颜色。通过上面的介绍,就知道了如何输出彩色字符了。

printf(“\033[1;40;32m color!!! \033[0m hello\n”);

————————————————
原文链接:https://blog.csdn.net/u014470361/article/details/81512330

在这里插入图片描述

写入文件

自定义写入文件接口,将log保存至文件。

htQLog::debug(logInfo);        
htQLog::info(logInfo);
htQLog::warning(logInfo);
htQLog::critical(logInfo);
htQLog::fatal(logInfo);

 QFile file("log.txt");
 file.open(QIODevice::WriteOnly | QIODevice::Append);
 QTextStream text_stream(&file);
 text_stream << message << "\r\n";
 file.flush();
 file.close();

多线程log日志

  • 多线程下I/O操作枷锁
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    // 加锁
    static QMutex mutex;
    mutex.lock();
	
	/*
	* log 组包
	*/
    ...
    
    // 解锁
    mutex.unlock();
}

开源log库

  • 上述写法适用与小型项目,对实时性要求不高。 但是读写文件和获取时间其实是耗时的,再加上锁后,可能会都系统性能要求高的项目有影响。

  • log4qt、spdlog、log4cpp

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值