当前位置: 首页 > news >正文

Qt 中日志级别

在 Qt 中,日志级别主要通过 qDebug()qInfo()qWarning()qCritical() 和 qFatal() 这几个宏来区分。它们分别对应不同的严重程度。

一、Qt 内置的日志级别(按严重程度从低到高排序)

宏 / 函数日志级别说明默认行为
qDebug()Debug调试信息。用于程序开发调试阶段输出详细信息,发布版本通常关闭。输出到 stderr(或系统日志)。
qInfo()Info信息消息。用于输出程序正常运行时的状态信息(如启动、配置加载成功)。输出到 stderr(或系统日志)。
qWarning()Warning警告消息。表明发生了意外情况,但应用程序仍能继续运行(如解析配置文件失败使用默认值)。输出到 stderr(或系统日志)。
qCritical()Critical严重错误消息。表明发生了严重错误,应用程序可能无法继续正常运行(如磁盘空间不足、关键功能失效)。输出到 stderr(或系统日志)。
qFatal()Fatal致命错误消息。在输出此消息后,应用程序会自动中止(abort)。用于发生了不可恢复的错误(如断言失败、关键数据损坏)。输出到 stderr 并调用 abort() 终止程序。

二、 基本使用示例

cpp

#include <QCoreApplication>
#include <QDebug>
#include <QInfo>
#include <QWarning>
#include <QCritical>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug()   << "This is a DEBUG message. Value of argc:" << argc;qInfo()    << "This is an INFO message. Application started successfully.";qWarning() << "This is a WARNING message. Configuration file not found, using defaults.";qCritical() << "This is a CRITICAL message. Failed to connect to the database!";// 下面的语句会终止程序// if (someCriticalError)//     qFatal("Fatal error: Unable to start the core component. Aborting.");return a.exec();
}

输出示例:

text

debug: This is a DEBUG message. Value of argc: 1
info: This is an INFO message. Application started successfully.
warning: This is a WARNING message. Configuration file not found, using defaults.
critical: This is a CRITICAL message. Failed to connect to the database!

三、 高级控制:分类日志(Categorized Logging)和规则(Rules)

从 Qt 5.2 开始,引入了更精细的日志控制系统。你可以为不同的日志类别(Category)设置不同的级别和输出规则。

a. 定义日志类别

使用 Q_LOGGING_CATEGORY 宏来定义一个类别。

cpp

// 在头文件中定义
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(myAppCore)
Q_DECLARE_LOGGING_CATEGORY(myAppUi)// 在源文件中实现
Q_LOGGING_CATEGORY(myAppCore, "myapp.core")
Q_LOGGING_CATEGORY(myAppUi, "myapp.ui")
b. 使用类别日志

使用 qCDebug()qCInfo()qCWarning()qCCritical() 宏。

cpp

qCDebug(myAppCore) << "Core module initialized.";
qCWarning(myAppUi) << "UI component took too long to respond.";
示例

假设你的应用叫 "ChatApp":

cpp

// main.cpp
#include <QApplication>
#include <QLoggingCategory>// 定义日志类别
Q_LOGGING_CATEGORY(chatapp, "chatapp")
Q_LOGGING_CATEGORY(chatappNetwork, "chatapp.network")
Q_LOGGING_CATEGORY(chatappMessage, "chatapp.message")int main(int argc, char *argv[])
{QApplication app(argc, argv);app.setApplicationName("ChatApp");qCInfo(chatapp) << "ChatApp started";qCDebug(chatappNetwork) << "Network module initialized";return app.exec();
}

输出结果

在 Qt 的 Debug 构建模式下,通常能看到:

text

chatapp.info: ChatApp started
chatapp.network.debug: Network module initialized

在 Release 构建模式下,默认可能只看到:

text

chatapp.info: ChatApp started
c. 通过环境变量配置日志规则

你可以在程序启动前设置 QT_LOGGING_RULES 环境变量来控制哪些类别的日志应该被输出。

示例:

  • 禁用所有调试日志:

    bash

    export QT_LOGGING_RULES="*.debug=false"
    ./myapp
  • 启用 myapp.core 类别的调试日志,禁用其他所有调试日志:

    bash

    export QT_LOGGING_RULES="myapp.core.debug=true;*.debug=false"
    ./myapp
  • 在 Windows 命令提示符中:

    cmd

    set QT_LOGGING_RULES=myapp.core.debug=true;*.debug=false
    myapp.exe
d. 在代码中配置规则

你也可以在代码中通过 QLoggingCategory::setFilterRules() 来设置规则。

cpp

int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 在代码中设置规则QString rules;rules = "*.debug=false\n""*.info=true\n""*.warning=true\n""*.critical=true\n""myapp.*.debug=true\n""qt.*.debug=false";QLoggingCategory::setFilterRules(rules);// ... 其余代码 ...return a.exec();
}

四、配置文件来控制日志输出

日志级别输出控制权交给logging.conf文件,通过修改文件增加或减少日志打印输出。

1. log规则读取类

logger.h

#ifndef LOGGER_H
#define LOGGER_H#include <QString>
#include <QMap>class Logger
{
public:static bool loadConfig(const QString &configPath);static void setDefaultConfig();static void enableDebug(bool enable);static void enableCategory(const QString &category, bool enable);static QString getCurrentRules();private:Logger() = delete;// 静态变量用于存储当前规则static QMap<QString, bool> m_rules;static void applyRules();static void parseAndAddRule(const QString &ruleLine);
};#endif // LOGGER_H

logger.cpp

#include "logger.h"
#include <QLoggingCategory>
#include <QFile>
#include <QTextStream>
#include <QSettings>
#include <QDebug>
#include <QRegularExpression>// 初始化静态成员变量
QMap<QString, bool> Logger::m_rules;bool Logger::loadConfig(const QString &configPath)
{QFile file(configPath);if (!file.exists()) {qWarning() << "Logging config file not found:" << configPath;return false;}if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qWarning() << "Cannot open logging config:" << configPath;return false;}// 清空现有规则m_rules.clear();QTextStream in(&file);QString rules;while (!in.atEnd()) {QString line = in.readLine().trimmed();// 跳过注释和空行if (line.startsWith('#') || line.startsWith("//") || line.isEmpty()) {continue;}parseAndAddRule(line);}file.close();applyRules();qInfo() << "Logging configuration loaded successfully";return true;
}void Logger::parseAndAddRule(const QString &ruleLine)
{QString pattern;bool enabled = true;if (ruleLine.contains('=')) {// 处理 key=value 格式int equalsIndex = ruleLine.indexOf('=');pattern = ruleLine.left(equalsIndex).trimmed();QString value = ruleLine.mid(equalsIndex + 1).trimmed();if (value.compare("false", Qt::CaseInsensitive) == 0 || value == "0") {enabled = false;} else {enabled = true;}} else {// 处理简单格式pattern = ruleLine;enabled = true;}if (!pattern.isEmpty()) {m_rules[pattern] = enabled;}
}void Logger::applyRules()
{QString rulesStr;QMap<QString, bool>::const_iterator it;for (it = m_rules.constBegin(); it != m_rules.constEnd(); ++it) {rulesStr += QString("%1=%2\n").arg(it.key()).arg(it.value() ? "true" : "false");}QLoggingCategory::setFilterRules(rulesStr);
}void Logger::setDefaultConfig()
{m_rules.clear();// 设置默认规则m_rules["*.debug"] = false;m_rules["*.info"] = true;m_rules["*.warning"] = true;m_rules["*.critical"] = true;m_rules["myapp.*.debug"] = true;m_rules["myapp.network.info"] = true;m_rules["myapp.database.warning"] = true;m_rules["qt.*.debug"] = false;m_rules["qt.*.info"] = false;applyRules();qInfo() << "Using default logging configuration";
}void Logger::enableDebug(bool enable)
{// 更新所有debug相关的规则QMap<QString, bool> newRules = m_rules;QMap<QString, bool>::iterator it;for (it = newRules.begin(); it != newRules.end(); ++it) {if (it.key().endsWith(".debug")) {it.value() = enable;}}// 也更新全局debug设置newRules["*.debug"] = enable;m_rules = newRules;applyRules();qInfo() << "Debug mode" << (enable ? "enabled" : "disabled");
}void Logger::enableCategory(const QString &category, bool enable)
{// 更新特定类别的所有规则QMap<QString, bool> newRules = m_rules;QMap<QString, bool>::iterator it;for (it = newRules.begin(); it != newRules.end(); ++it) {if (it.key().startsWith(category + ".")) {it.value() = enable;}}m_rules = newRules;applyRules();qInfo() << "Category" << category << (enable ? "enabled" : "disabled");
}QString Logger::getCurrentRules()
{QString rules;QMap<QString, bool>::const_iterator it;for (it = m_rules.constBegin(); it != m_rules.constEnd(); ++it) {rules += QString("%1=%2\n").arg(it.key()).arg(it.value() ? "true" : "false");}return rules;
}

2. 配置文件示例

logging.conf

# 日志配置文件
# 注释以 # 或 // 开头# 全局设置
*.debug=false
*.info=true
*.warning=true
*.critical=true# 应用程序特定设置
myapp.main.debug=true
myapp.network.info=true
myapp.database.warning=true# Qt 内部模块
qt.*.debug=false
qt.core.info=false

3. 在应用程序中集成

// 在应用程序初始化时
void initLogger()
{// 尝试从文件加载配置QString configPath = QCoreApplication::applicationDirPath() + "/logging.conf";if (!Logger::loadConfig(configPath)) {// 使用默认配置Logger::setDefaultConfig();}// 获取当前规则QString currentRules = Logger::getCurrentRules();qDebug() << "Current logging rules:" << currentRules;
}

修改logging.conf配置文件debug=flase,debug=true等值,可以控制日志级别输出。
比如:*.debug=true,在程序应用中qDebug()语句的内容就打印输出。*.debug=false,在程序应用中qDebug()语句的内容不会打印输出。*.info=true,在程序应用中qInfo()语句的内容就打印输出。

http://www.dtcms.com/a/355372.html

相关文章:

  • JS中的String总结
  • Linux 环境源码安装 Docker
  • 影石insta360 DevOps工程师一面记录
  • 学习嵌入式之驱动——I2C子系统
  • 搭建一个Spring cloud 非阻塞式微服务架构
  • 任天堂NDS中文游戏ROM精选毕业整合包整理分享! +NDS模拟器
  • 使用Docker搭建StackEdit在线MarkDown编辑器
  • 如何通过docker进行本地部署?
  • 企业内部机密视频安全保护|如何防止企业内部机密视频泄露?
  • (附源码)基于Spring Boot公务员考试信息管理系统设计与实现
  • GitLab 配置 Pipeline 的过程
  • linux 网络:协议及Wireshark抓包工具的使用
  • Elasticsearch冷热架构:性能与成本完美平衡
  • 《深入浅出 Node.js》分享精简大纲
  • linu 网络 :TCP粘包及UDP
  • 软件设计师备考-(五)计算机网络
  • 客户端是否都需要主动发送`FindService`报文来寻找服务
  • FPGA开发技能(12)matlab图片处理助力FPGA开发
  • 【温室气体数据集】GlobalView 数据概述
  • Kotlin 协程之Channel 的高阶应用
  • RAGFlow
  • plantsimulation知识点 一条轨道上多台RGV如何引用
  • 【Big Data】Presto db 一种语言、一个接口搭建可靠、高效数据湖仓
  • NineData 最新发布 SQL Server 双向实时同步功能
  • 手机上访问你电脑上的前端项目
  • Rust 登堂 之 类型转换(三)
  • 趣味学Rust基础篇(数据类型)
  • Python Discord Logo
  • 【SpringAI】快速上手,详解项目快速集成主流大模型DeepSeek,ChatGPT
  • 操作系统-基础知识面试常见篇