• Qt的简易日志库实现及封装


    用于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文件内容:

    1. HEADERS += $$PWD/MessageLogger.h
    2. SOURCES += $$PWD/MessageLogger.cpp
    3. INCLUDEPATH += $$PWD

    简易封装 

    1. #ifndef MESSAGELOGGER_H
    2. #define MESSAGELOGGER_H
    3. /** @description 用于Qt项目的一个简单的日志库,将日志存入日志文件(文本文件)中。
    4. * 典型用法示例:
    5. * 第一个 FileLogger 将日志输出到 stderr 上。
    6. * 第二个 FileLogger 将日志输出到文件。
    7. * 建议将这段代码放到 main 函数的开头处,但是要在 QCoreApplication 或 QApplication 之后。
    8. * LoggerController logger;
    9. * logger.attach(new FileLogger("stderr",
    10. * FileLogger::E_DEBUG |
    11. * FileLogger::E_INFO |
    12. * FileLogger::E_WARNING |
    13. * FileLogger::E_CRITICAL |
    14. * FileLogger::E_FATAL));
    15. * logger.attach(new FileLogger("d:/log2.txt"));
    16. * logger.startLogging();
    17. */
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. class FileLogger
    25. {
    26. public:
    27. enum LEVEL{E_DEBUG = 1, E_INFO = 2, E_WARNING = 4, E_CRITICAL = 8, E_FATAL = 16};
    28. FileLogger(QString name, LEVEL level);
    29. FileLogger(QString name = "stderr", bool debug=false, bool info=true, bool warning=true, bool critical=true, bool fatal=true);
    30. virtual ~FileLogger();
    31. /**
    32. * @brief setFileName 设置日志存储的文件名
    33. * @param name 日志存储的文件名,如果为 "stderr" 则输出到 stderr
    34. * @return
    35. */
    36. bool setFileName(QString name = "stderr");
    37. /**
    38. * @brief setLogLevel 设置哪些级别的信息要输出到文件
    39. * @param level 可以为 E_DEBUG、E_INFO、E_WARNING、E_CRITICAL、E_FATAL 或者这些项的组合(bit or)
    40. * 没有设置的 level 则不输出日志
    41. */
    42. void setLogLevel(LEVEL level);
    43. /**
    44. * @brief setLogLevel 设置哪些级别的信息要输出到文件
    45. * @param debug true 表示 qDebug 信息输出到日志
    46. * @param info true 表示 qInfo 信息输出到日志
    47. * @param warning true 表示 qWarning 信息输出到日志
    48. * @param critical true 表示 qCritical 信息输出到日志
    49. * @param fatal true 表示 qFatal 信息输出到日志
    50. */
    51. void setLogLevel(bool debug = false, bool info = true, bool warning = true, bool critical= true, bool fatal = true);
    52. virtual void writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg);
    53. private:
    54. QString messageType(QtMsgType type);
    55. FileLogger(FileLogger &f) {Q_UNUSED(f);} // 不能被拷贝
    56. FileLogger& operator=( FileLogger &f) {Q_UNUSED(f);} // 不能被拷贝
    57. private:
    58. QFile m_file;
    59. QMapbool> m_level;
    60. bool m_where;
    61. };
    62. class LoggerController
    63. {
    64. public:
    65. LoggerController(){}
    66. ~LoggerController();
    67. /**
    68. * @brief startLogging 启动日志系统,在这之后所有的调试信息发送到对应的 FileLogger
    69. */
    70. void startLogging();
    71. /**
    72. * @brief attach 在日志系统中注册一个新的 FileLogger
    73. * @param m_currentLogger
    74. */
    75. void attach(FileLogger *m_currentLogger);
    76. void detach(FileLogger *m_currentLogger);
    77. private:
    78. static void writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg);
    79. static LoggerController * m_currentLogger;
    80. QList m_list;
    81. };
    82. #endif // MESSAGELOGGER_H
    1. #include "MessageLogger.h"
    2. #include
    3. #include
    4. FileLogger::FileLogger(QString name, bool debug, bool info, bool warning, bool critical, bool fatal)
    5. :m_where(true)
    6. {
    7. setFileName(name);
    8. setLogLevel(debug, info, warning, critical, fatal);
    9. }
    10. FileLogger::FileLogger(QString name, LEVEL level)
    11. :m_where(false)
    12. {
    13. setFileName(name);
    14. setLogLevel(level);
    15. }
    16. FileLogger::~FileLogger()
    17. {
    18. m_file.close();
    19. }
    20. bool FileLogger::setFileName(QString name)
    21. {
    22. m_file.close();
    23. if(name == "stderr")
    24. {
    25. return m_file.open(stderr, QIODevice::WriteOnly);
    26. }
    27. else
    28. {
    29. m_file.setFileName(name);
    30. return m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
    31. }
    32. }
    33. void FileLogger::setLogLevel(LEVEL level)
    34. {
    35. m_level[QtDebugMsg] = static_cast<bool> (level & E_DEBUG);
    36. m_level[QtInfoMsg] = static_cast<bool> (level & E_INFO);
    37. m_level[QtWarningMsg] = static_cast<bool> (level & E_WARNING);
    38. m_level[QtCriticalMsg] = static_cast<bool> (level & E_CRITICAL);
    39. m_level[QtFatalMsg] = static_cast<bool> (level & E_FATAL);
    40. }
    41. void FileLogger::setLogLevel(bool debug, bool info, bool warning, bool critical, bool fatal)
    42. {
    43. m_level[QtDebugMsg] = debug;
    44. m_level[QtInfoMsg] = info;
    45. m_level[QtWarningMsg] = warning;
    46. m_level[QtCriticalMsg] = critical;
    47. m_level[QtFatalMsg] = fatal;
    48. }
    49. void FileLogger::writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    50. {
    51. if(!m_level[type])
    52. {
    53. return;
    54. }
    55. QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    56. QTextStream logfile(&m_file);
    57. logfile << strTime << ", ";
    58. logfile << messageType(type) << ", ";
    59. logfile << msg;
    60. if(context.file && m_where)
    61. {
    62. logfile << ", (" << context.file << ":" << context.line << ", " << context.function << ")\n";
    63. }
    64. else
    65. {
    66. logfile << endl;
    67. }
    68. if(type == QtFatalMsg)
    69. {
    70. abort();
    71. }
    72. }
    73. QString FileLogger::messageType(QtMsgType type)
    74. {
    75. QString str;
    76. switch (type)
    77. {
    78. case QtDebugMsg:
    79. str = "[D]";
    80. break;
    81. case QtInfoMsg:
    82. str = "[I]";
    83. break;
    84. case QtWarningMsg:
    85. str = "[W]";
    86. break;
    87. case QtCriticalMsg:
    88. str = "[C]";
    89. break;
    90. case QtFatalMsg:
    91. str = "[F]";
    92. }
    93. return str;
    94. }
    95. void LoggerController::attach(FileLogger *logger)
    96. {
    97. m_list.append(logger);
    98. }
    99. void LoggerController::detach(FileLogger *logger)
    100. {
    101. if(logger)
    102. {
    103. m_list.removeOne(logger);
    104. delete logger;
    105. }
    106. }
    107. void LoggerController::startLogging()
    108. {
    109. m_currentLogger = this;
    110. qInstallMessageHandler(LoggerController::writeLog);
    111. }
    112. LoggerController::~LoggerController()
    113. {
    114. qDeleteAll(m_list);
    115. }
    116. LoggerController* LoggerController::m_currentLogger = nullptr;
    117. void LoggerController::writeLog(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    118. {
    119. if( m_currentLogger )
    120. {
    121. QList &list = m_currentLogger->m_list;
    122. QList::const_iterator i;
    123. for (i = list.cbegin(); i != list.cend(); ++i)
    124. {
    125. (*i)->writeLog(type, context, msg);
    126. }
    127. }
    128. }

    简单使用

    1. #include "mainwindow.h"
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include "cglobal.h"
    9. #include "MessageLogger.h"
    10. #include "utils.h"
    11. int main(int argc, char *argv[])
    12. {
    13. //自适应高分辨率(DPI),不确定是否管用
    14. #if (QT_VERSION >= QT_VERSION_CHECK(5,9,0))
    15. QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    16. QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    17. #endif
    18. QApplication a(argc, argv);
    19. a.setFont(QFont("Microsoft Yahei", 9));//设置应用程序字体
    20. a.setWindowIcon(QIcon(":/main.ico"));//设置应用程序图标
    21. mkDirIfNotExist();
    22. //打印日志到文件中
    23. LoggerController logger;
    24. logger.attach(new FileLogger("stderr",
    25. FileLogger::E_DEBUG,
    26. FileLogger::E_INFO ,
    27. FileLogger::E_WARNING ,
    28. FileLogger::E_CRITICAL,
    29. FileLogger::E_FATAL));
    30. QString dateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmss");
    31. QString logName = LOG_PATH+dateTime+"_log.txt";
    32. //日志文件输入以下级别的日志
    33. FileLogger::LEVEL level = (FileLogger::LEVEL)(FileLogger::E_INFO | FileLogger::E_WARNING);
    34. FileLogger *lg = new FileLogger(logName,level);
    35. logger.attach(lg);
    36. logger.startLogging();
    37. qInfo("程序启动...");
    38. qInfo(APP_VERION);
    39. MainWindow w;
    40. w.show();
    41. return a.exec();
    42. }
    43. void mkDirIfNotExist(){
    44. QDir *folder = new QDir;
    45. bool exist,ok = false;
    46. exist = folder->exists(LOG_PATH);
    47. if(!exist){
    48. ok = folder->mkdir(LOG_PATH);
    49. if(!ok){
    50. qDebug("Error,创建日志文件夹失败");
    51. }
    52. }
    53. exist = folder->exists(PIC_PATH);
    54. if(!exist){
    55. ok = folder->mkdir(PIC_PATH);
    56. if(!ok){
    57. qDebug("Error,创建图片文件夹失败");
    58. }
    59. }
    60. }

    引用

    QT 轻量级的LOG日志库_Duffy_Gallagher的博客-CSDN博客_qt日志库

    Qt轻量级日志库QsLog的使用_百里杨的博客-CSDN博客_qt 日志库

  • 相关阅读:
    Java-类和对象
    【Unity】LayoutGroup自动缩放子对象大小
    RabbitMQ(六)仲裁队列、流式队列、异地容灾(联邦队列Federation Queue)
    线上答题活动小程序结合线下大屏复盘总结
    Mybatis实战练习四【单个条件(动态SQL)&添加数据】
    申请400电话的详细步骤及操作指南
    CSP2023 游记
    从零开始:使用ChatGPT快速创作引人入胜的博客内容
    C#解决MDI窗体闪屏的方法
    Docker Machine简介
  • 原文地址:https://blog.csdn.net/qq8864/article/details/126216603