【问题标题】:QMessageLogger : Singleton for a Logger?QMessageLogger:记录器的单例?
【发布时间】:2023-04-05 20:03:01
【问题描述】:

我想为我的应用程序实现一个记录器,因此我创建了一个派生自 QMessageLogger 的类 MyAppLogger

假设我在我的 Qt MyApp 项目中实现了其他几个类:

  • MainWidget:QWidget
  • 帮助对话框:QDialog
  • 计算数值

如何在不创建三个 Logger 的情况下为所有这些类提供 Logger?我想使用 Singleton 机制。 但我读过单例是一种糟糕的编程技术!?

Here 我刚刚创建了一个带有两个空对话框的简单项目。然后我有一个 MyAppLogger,它将创建格式化字符串,如:

[MyApp] info 12:12:00:123[ms]_12.12.2012) 对象“MyCalculator”创建于 0xdeadbeef

[MyApp] 致命 12:12:00:123[ms]_12.12.2012) 函数“divisionDouble”崩溃

当然带有所需的正确参数(currentSystemTimeInMillis()、函数名等...)

示例 Logger,想象还有很多其他类,它们应该能够使用那些 void info(...)、debug(...)、critical(...)、fatal(...);等等。 标题:

#ifndef MYAPPLOGGER_H
#define MYAPPLOGGER_H
#include <QString>
#include <QFile>

class MyAppLogger
{
public:
  MyAppLogger(QString outputFile);

  void info(char* expression);
  void debug(char* expression);
  void critical(char* expression);
  void fatal(char* expression);

private:
  QFile * _debugFile;
};
#endif // MYAPPLOGGER_H

以及对应的SRC:

#include "myapplogger.h"

MyAppLogger::MyAppLogger(QString outputFile)
{
  _debugFile = new QFile(outputFile);
}

void MyAppLogger::critical(char *expression)
{
  QString line("[MyAPP] \t critical \t SYS_TIME (12:45:00_12.12.2012) :: ");
  line.append(expression);
  
  // write line to a file

  // write line to STD output 
}

【问题讨论】:

  • 单身人士有其用途。没有人愿意将记录器传递给每个函数或在每个类中保留对记录器的引用。但是您不必使用单例,您可以简单地选择仅实例化一个全局记录器。但是您必须小心确保在其他人尝试使用它之前创建它。 Singleton 可以提供帮助。
  • 为什么需要重写QMessageLogger?通常定义 static void action(QtMsgType type, const QMessageLogContext &context, const QString &msg) 并调用 qInstallMessageHandler(action);
  • @demonplus 除了doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler,我还有另一个例子吗?
  • 基本上这就是您所需要的。您能否在帖子中分享更多详细信息,您在 MyAppLogger 中尝试做什么?
  • @demonplus 刚刚编辑了线程。我想要预先格式化的输出。

标签: c++ qt logging singleton qt5


【解决方案1】:

从我看你想要实现两件事:

  1. 更改所有日志记录输出的输出格式。
    你应该考虑使用qSetMessagePattern

  2. 将所有日志记录输出写入文件:
    不需要子类化 QMessageLogger。只需使用qInstallMessageHandler 安装自定义处理程序并将日志消息写入文件。

使用这两种方法的好处是可以使用 qt 自己的调试宏(qDebug()、qFatal() ...),而无需编写自己的 MessageLogger 或考虑 Singleton。

【讨论】:

  • 好的,听起来不错。我可以打开一个额外的命令窗口(cmd、shell)来显示它吗?如果是,我如何将该 Debugmessages 转发到该命令行外壳?
  • qInstallMessageHandler 将返回一个指向前一个 MessageHandler 的指针。在您的处理程序代码中,您可以在将日志消息写入文件之后/之前简单地调用前一个处理程序。这样,您将在 qtcreator 的控制台或终端中看到输出。
  • 您好,是否可以使用这种机制在单独的低优先级线程中打印消息?我担心执行时间,写入文件可能需要一段时间。我将不胜感激。
  • @Lukasz 当然。只需将消息保存到受互斥体保护的向量中,然后将该向量写入来自不同线程的文件。另一方面,如果您担心性能,您可能希望在发布版本中使用 QT_NO_DEBUG 进行编译。
  • @Lukasz 我通常也将此类用于发布日志记录。 (好吧,我没有直接使用这个类,而是'qDebug()','qWarning()'等等 - 但他们在内部使用这个类)
猜你喜欢
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
相关资源
最近更新 更多