用于QT的一个简易日志功能模块封装。算不上强大和多高的性能,但是足够简单小巧。用于记录日志到文件够用了。单独的一个文件模块,使用时直接引入源码。想要其他功能,直接改代码即可。
C++的下的日志库有很多,如log4cpp、Easylogging++,eplog,g3log,Qt下也有log4qt。
还有简单小巧的QsLog,它是一个基于Qt的轻量级开源日志库。
QsLog的git地址:https://github.com/victronenergy/QsLog
log4qt的git地址:https://github.com/devbean/log4qt
如果这些都不想用,还想更简单小巧的,可以看以下这个简易模块封装。
查看日志推荐用baretailpro工具。
使用时只需工程文件.pro中包含模块源码即可。
include(Logger/MessageLogger.pri)
MessageLogger.pri文件内容:
- HEADERS += $$PWD/MessageLogger.h
- SOURCES += $$PWD/MessageLogger.cpp
-
- INCLUDEPATH += $$PWD
- #ifndef MESSAGELOGGER_H
- #define MESSAGELOGGER_H
-
- /** @description 用于Qt项目的一个简单的日志库,将日志存入日志文件(文本文件)中。
- * 典型用法示例:
- * 第一个 FileLogger 将日志输出到 stderr 上。
- * 第二个 FileLogger 将日志输出到文件。
- * 建议将这段代码放到 main 函数的开头处,但是要在 QCoreApplication 或 QApplication 之后。
- * LoggerController logger;
- * logger.attach(new FileLogger("stderr",
- * FileLogger::E_DEBUG |
- * FileLogger::E_INFO |
- * FileLogger::E_WARNING |
- * FileLogger::E_CRITICAL |
- * FileLogger::E_FATAL));
- * logger.attach(new FileLogger("d:/log2.txt"));
- * logger.startLogging();
- */
-
- #include
- #include
- #include
- #include
- #include
- #include
-
- class FileLogger
- {
- public:
- enum LEVEL{E_DEBUG = 1, E_INFO = 2, E_WARNING = 4, E_CRITICAL = 8, E_FATAL = 16};
- FileLogger(QString name, LEVEL level);
- FileLogger(QString name = "stderr", bool debug=false, bool info=true, bool warning=true, bool critical=true, bool fatal=true);
- virtual ~FileLogger();
- /**
- * @brief setFileName 设置日志存储的文件名
- * @param name 日志存储的文件名,如果为 "stderr" 则输出到 stderr
- * @return
- */
- bool setFileName(QString name = "stderr");
- /**
- * @brief setLogLevel 设置哪些级别的信息要输出到文件
- * @param level 可以为 E_DEBUG、E_INFO、E_WARNING、E_CRITICAL、E_FATAL 或者这些项的组合(bit or)
- * 没有设置的 level 则不输出日志
- */
- void setLogLevel(LEVEL level);
- /**
- * @brief setLogLevel 设置哪些级别的信息要输出到文件
- * @param debug true 表示 qDebug 信息输出到日志
- * @param info true 表示 qInfo 信息输出到日志
- * @param warning true 表示 qWarning 信息输出到日志
- * @param critical true 表示 qCritical 信息输出到日志
- * @param fatal true 表示 qFatal 信息输出到日志
- */
- void setLogLevel(bool debug = false, bool info = true, bool warning = true, bool critical= true, bool fatal = true);
- virtual void writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg);
- private:
- QString messageType(QtMsgType type);
- FileLogger(FileLogger &f) {Q_UNUSED(f);} // 不能被拷贝
- FileLogger& operator=( FileLogger &f) {Q_UNUSED(f);} // 不能被拷贝
- private:
- QFile m_file;
- QMap
bool> m_level; - bool m_where;
- };
-
- class LoggerController
- {
- public:
- LoggerController(){}
- ~LoggerController();
- /**
- * @brief startLogging 启动日志系统,在这之后所有的调试信息发送到对应的 FileLogger
- */
- void startLogging();
- /**
- * @brief attach 在日志系统中注册一个新的 FileLogger
- * @param m_currentLogger
- */
- void attach(FileLogger *m_currentLogger);
- void detach(FileLogger *m_currentLogger);
- private:
- static void writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg);
- static LoggerController * m_currentLogger;
- QList
m_list; - };
-
- #endif // MESSAGELOGGER_H
- #include "MessageLogger.h"
- #include
- #include
-
- FileLogger::FileLogger(QString name, bool debug, bool info, bool warning, bool critical, bool fatal)
- :m_where(true)
- {
- setFileName(name);
- setLogLevel(debug, info, warning, critical, fatal);
- }
-
- FileLogger::FileLogger(QString name, LEVEL level)
- :m_where(false)
- {
- setFileName(name);
- setLogLevel(level);
- }
-
- FileLogger::~FileLogger()
- {
- m_file.close();
- }
-
- bool FileLogger::setFileName(QString name)
- {
- m_file.close();
- if(name == "stderr")
- {
- return m_file.open(stderr, QIODevice::WriteOnly);
- }
- else
- {
- m_file.setFileName(name);
- return m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
- }
- }
-
- void FileLogger::setLogLevel(LEVEL level)
- {
- m_level[QtDebugMsg] = static_cast<bool> (level & E_DEBUG);
- m_level[QtInfoMsg] = static_cast<bool> (level & E_INFO);
- m_level[QtWarningMsg] = static_cast<bool> (level & E_WARNING);
- m_level[QtCriticalMsg] = static_cast<bool> (level & E_CRITICAL);
- m_level[QtFatalMsg] = static_cast<bool> (level & E_FATAL);
- }
-
- void FileLogger::setLogLevel(bool debug, bool info, bool warning, bool critical, bool fatal)
- {
- m_level[QtDebugMsg] = debug;
- m_level[QtInfoMsg] = info;
- m_level[QtWarningMsg] = warning;
- m_level[QtCriticalMsg] = critical;
- m_level[QtFatalMsg] = fatal;
- }
-
- void FileLogger::writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg)
- {
- if(!m_level[type])
- {
- return;
- }
- QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
- QTextStream logfile(&m_file);
-
- logfile << strTime << ", ";
- logfile << messageType(type) << ", ";
- logfile << msg;
- if(context.file && m_where)
- {
- logfile << ", (" << context.file << ":" << context.line << ", " << context.function << ")\n";
- }
- else
- {
- logfile << endl;
- }
-
- if(type == QtFatalMsg)
- {
- abort();
- }
- }
-
- QString FileLogger::messageType(QtMsgType type)
- {
- QString str;
- switch (type)
- {
- case QtDebugMsg:
- str = "[D]";
- break;
- case QtInfoMsg:
- str = "[I]";
- break;
- case QtWarningMsg:
- str = "[W]";
- break;
- case QtCriticalMsg:
- str = "[C]";
- break;
- case QtFatalMsg:
- str = "[F]";
- }
- return str;
- }
-
- void LoggerController::attach(FileLogger *logger)
- {
- m_list.append(logger);
- }
-
- void LoggerController::detach(FileLogger *logger)
- {
- if(logger)
- {
- m_list.removeOne(logger);
- delete logger;
- }
- }
-
- void LoggerController::startLogging()
- {
- m_currentLogger = this;
- qInstallMessageHandler(LoggerController::writeLog);
- }
-
- LoggerController::~LoggerController()
- {
- qDeleteAll(m_list);
- }
- LoggerController* LoggerController::m_currentLogger = nullptr;
-
- void LoggerController::writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg)
- {
- if( m_currentLogger )
- {
- QList
&list = m_currentLogger->m_list; -
- QList
::const_iterator i; - for (i = list.cbegin(); i != list.cend(); ++i)
- {
- (*i)->writeLog(type, context, msg);
- }
- }
-
- }
- #include "mainwindow.h"
-
- #include
-
- #include
- #include
- #include
- #include
- #include
- #include "cglobal.h"
- #include "MessageLogger.h"
- #include "utils.h"
-
- int main(int argc, char *argv[])
- {
- //自适应高分辨率(DPI),不确定是否管用
- #if (QT_VERSION >= QT_VERSION_CHECK(5,9,0))
- QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- #endif
- QApplication a(argc, argv);
- a.setFont(QFont("Microsoft Yahei", 9));//设置应用程序字体
- a.setWindowIcon(QIcon(":/main.ico"));//设置应用程序图标
-
- mkDirIfNotExist();
-
- //打印日志到文件中
- LoggerController logger;
- logger.attach(new FileLogger("stderr",
- FileLogger::E_DEBUG,
- FileLogger::E_INFO ,
- FileLogger::E_WARNING ,
- FileLogger::E_CRITICAL,
- FileLogger::E_FATAL));
- QString dateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmss");
- QString logName = LOG_PATH+dateTime+"_log.txt";
- //日志文件输入以下级别的日志
- FileLogger::LEVEL level = (FileLogger::LEVEL)(FileLogger::E_INFO | FileLogger::E_WARNING);
- FileLogger *lg = new FileLogger(logName,level);
- logger.attach(lg);
- logger.startLogging();
- qInfo("程序启动...");
- qInfo(APP_VERION);
-
-
- MainWindow w;
- w.show();
- return a.exec();
- }
-
- void mkDirIfNotExist(){
- QDir *folder = new QDir;
- bool exist,ok = false;
- exist = folder->exists(LOG_PATH);
- if(!exist){
- ok = folder->mkdir(LOG_PATH);
- if(!ok){
- qDebug("Error,创建日志文件夹失败");
- }
- }
- exist = folder->exists(PIC_PATH);
- if(!exist){
- ok = folder->mkdir(PIC_PATH);
- if(!ok){
- qDebug("Error,创建图片文件夹失败");
- }
- }
- }