Qt种使用C++日志库
日志是软件开发中必不可少的内容。输出日志可以帮助我们定位软件中的错误。更好的定位开发中的问题。
下面我将简单的输出一些日志:
方式一:使用Qt原生QFile来输出
代码如下:
C++
enum LogLevel
{
debugLevel,
infoLevel,
warnLevel,
errorLevel,
fatalLevel
};
class QLogger
{
public:
static QLogger& instance()
{
static QLogger log;
return log;
}
void setLogFilePath(const QString& strFilePath)
{
m_logFile.setFileName(strFilePath);
m_logFile.open(QIODevice::Append|QIODevice::Text);
}
void Log(LogLevel level,const QString strMsg)
{
if(!m_logFile.isOpen())
return;
// 时间
QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
// 日志级别
QString strLevel = level == debugLevel? "[DEBUG]" :
level == infoLevel ? "[INFO]" :
level == warnLevel ? "[WARN]" :
level == errorLevel ? "[ERROR]" : "[FATAL]";
QString strLogLine = QString("%1 %2 %3\n").arg(strTime).arg(strLevel).arg(strMsg);
QTextStream out(&m_logFile);
out << strLogLine;
qDebug() << strLogLine.trimmed(); // 控制台用qDebug输出
}
private:
QFile m_logFile;
};
// 便捷宏定义
#define LOG_DEBUG(msg) QLogger::instance().Log(debugLevel,msg)
#define LOG_INFO(msg) QLogger::instance().Log(infoLevel,msg)
#define LOG_WARN(msg) QLogger::instance().Log(warnLevel,msg)
#define LOG_ERROR(msg) QLogger::instance().Log(errorLevel,msg)
#define LOG_FATAL(msg) QLogger::instance().Log(fatalLevel,msg)
使用方式:
c++
QString strPath = QCoreApplication::applicationDirPath();
QString strFile = QDir(strPath).filePath("app.log");
QLogger::instance().setLogFilePath(strFile);
LOG_INFO("应用程序启动");
LOG_DEBUG(QString("Qt版本: %1").arg(QT_VERSION_STR));
LOG_WARN("配置文件未找到,使用默认配置");
LOG_ERROR("数据库连接失败");
输出效果如下:

方式二:使用spdlog库来输出
2.1 Spdlog简介
什么是 Spdlog 日志库
Spdlog 是一个 C++ 的日志库,它具有高效、易用、跨平台等特点。它可以写入到控制台、文件等输出目标,支持多种日志级别、多线程安全等功能,非常适合在 C++ 项目中使用。
Spdlog下载:Spdlog
2.2 Spdlog库使用
下载完成后:将项目中的include文件夹和src文件夹都拷贝到项目中,如下图。


然后在项目中添加对include和src中文件的引用,如下图:

在代码中使用spdlog库:
qlogmgr.h
c++
#ifndef QLOGMGR_H
#define QLOGMGR_H
#include "spdlog/spdlog.h"
#include <QString>
class QLogMgr
{
public:
QLogMgr();
~QLogMgr();
void startUp();
void shutDown();
inline void Trace(QString strMsg)
{
spdlog::trace(strMsg.toStdString().c_str());
}
inline void Debug(QString strMsg)
{
spdlog::debug(strMsg.toStdString().c_str());
}
inline void Info(QString strMsg)
{
spdlog::info(strMsg.toStdString().c_str());
}
inline void Warn(QString strMsg)
{
spdlog::warn(strMsg.toStdString().c_str());
}
inline void Error(QString strMsg)
{
spdlog::error(strMsg.toStdString().c_str());
}
inline void Critical(QString strMsg)
{
spdlog::critical(strMsg.toStdString().c_str());
}
};
#endif // QLOGMGR_H
qlogmgr.cpp
c++
#include "qlogmgr.h"
#include "spdlog/sinks/rotating_file_sink.h" // 滚动文件输出
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/async.h"
#include<QDir>
#include <QMessageBox>
QLogMgr::QLogMgr()
{
}
void QLogMgr::startUp()
{
try
{
// 创建日志目录
QDir logDir("logs");
if(!logDir.exists() && !logDir.mkpath("."))
{
QMessageBox::critical(nullptr,"日志错误","无法创建日志目录");
return;
}
// 初始化线程池,8192个消息,1个后台线程
spdlog::init_thread_pool(8192,1);
// 设置自动刷新
spdlog::flush_every(std::chrono::seconds(5));
// 创建滚动文件sinks(最大5M,保留3个备份)
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/App.log",1024*1024*5,100);
// 创建控制台sinks
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
// 组合sink
std::vector<spdlog::sink_ptr> vtSink = {rotating_sink,console_sink};
// 创建异步日志器
auto logger = std::make_shared<spdlog::async_logger>(
"qtLogger",
vtSink.begin(),
vtSink.end(),
spdlog::thread_pool(),
spdlog::async_overflow_policy::block
);
// 设置日志器格式
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
// 设置全局设置器
spdlog::set_default_logger(logger);
// 设置日志级别
#ifdef QT_DEBUG
logger->set_level(spdlog::level::debug);
#elif
logger->set_level(spdlog::level::info);
#endif
// 刷新错误立即写入
logger->flush_on(spdlog::level::err);
spdlog::info("App Strart Up");
spdlog::debug("Enable debug log");
spdlog::info("Current Qt Version:{}",qVersion());
// 获取SPDLOG版本号
auto logVersion = QString("%1.%2.%3").arg(QString::number(SPDLOG_VER_MAJOR),
QString::number(SPDLOG_VER_MINOR),
QString::number(SPDLOG_VER_PATCH)
).toStdString();
spdlog::info("Current spdlog version: {}", logVersion.c_str());
}
catch(const spdlog::spdlog_ex& ex)
{
QMessageBox::critical(nullptr,"日志初始化错误",QString("日志初始话失败:%1").arg(ex.what()));
}
}
void QLogMgr::shutDown()
{
spdlog::info("App Shut Down");
spdlog::shutdown();
}
代码测试:
c++
QLogMgr* plogMgr = new QLogMgr();
plogMgr->startUp();
plogMgr->Debug("应用程序启动");
plogMgr->Info(QString("Qt版本: %1").arg(QT_VERSION_STR));
代码输出:

好了关于Qt中简单输出日志库的方式就介绍到这里了。
参考文章:Qt以直接包含源码的方式引用spdlog