【问题标题】:Logging facilities and Qt日志记录设施和 Qt
【发布时间】:2010-12-05 07:04:43
【问题描述】:

您在 Qt 中使用哪些日志记录工具?

你会选择 qDebug()、qWarning()、qCritical()、qFatal() 方法,还是 Log4cpp(Log4cplus 等)之类的方法,或者一些自定义代码?

【问题讨论】:

    标签: c++ qt logging


    【解决方案1】:

    如果您只是在单线程中工作,qDebug 和类似的工作非常好,或者您可以通过在 QT 5.0+ 中使用 qInstallMessageHandler 或在旧版本中使用 qInstallMsgHandler 安装自己的处理程序来对其进行一些修改。

    注意:旧版本的 qDebug() 等,您使用 qInstallMsgHandler(现已弃用,例如http://doc.qt.io/archives/4.6/qtglobal.html#qDebug)不是线程安全的。如果您使用线程,它们会严重崩溃/中断。它在内部使用 QTextStream,它是可重入的,但不是线程安全的。

    【讨论】:

    • -1 qDebug() 是线程安全的。 QTextStream 的线程安全无关紧要,因为没有共享的 QTextStream。每次调用qDebug() 都会获得自己的QTextStream
    • @Oktalist:我不同意你的观点:stackoverflow.com/a/23517726/1202500 - 那里的答案/正是我的经验......
    • @mozzbozz 谢谢。如果qDebug 不安全,则不是因为 DarrylC 给出的原因。如果您安装自己的线程安全QtMessageHandler,那么qDebug 将是线程安全的。默认处理程序可能会交错输出,但我不相信存在数据竞争/UB,尽管我无法证明这一点。
    • @Oktalist 很惊讶你知道这一点,因为没有多少人可以访问 Meego 设备和在 2010 年末/2011 年初展示它的资源。那是当时的失败(也是如果我没记错的话,在 Symbian 上)。我不知道现在会发生什么,但是如果您希望该软件不仅仅用于一次性原型,那么您仍然不应该依赖未记录为线程安全的线程安全的东西。这就是代码腐烂的原因:依赖于当今实现的意外行为,而不是规范。
    • qDebug 和朋友现在被证明是线程安全的(至少在 Qt 4 中,他们一直是线程安全的,至少 5 次):doc.qt.io/qt-5/qtglobal.html#qDebug
    【解决方案2】:

    由于 Qt 5.2 支持分类日志记录:http://qt-project.org/doc/qt-5/qloggingcategory.html。这允许您将日志消息拆分为(层次结构)类别,并微调哪些记录,哪些不记录。

    【讨论】:

      【解决方案3】:

      现有的 C++ 日志库对我来说太重了,所以我根据 Logging in C++ 的想法为 Qt qInstallMsgHandlerq 后端创建了一个自定义前端。它是跨平台和线程安全的。总有一天我会清理代码并将其发布给全世界:)

      Qt 的一个有趣替代方案是QxtLogger

      【讨论】:

      • 也许 QxtLogger 是基于 Qt 的项目的最佳解决方案。唯一的缺点(在我看来),这个记录器是相当大的库的一部分。不管怎样,谢谢你的建议。
      • @vnm:我已经在bitbucket.org/razvanpetru/qt-components/downloads发布了我的日志库
      • 只是为了更新 - 现在有一个官方developer.nokia.com/Community/Wiki/…
      • 可惜现在所有链接都坏了,我希望看看。
      • 这篇文章如何成为答案 “现有的 C++ 日志库对我来说太重了,所以我根据 Logging in C++ 中的想法创建了一个自定义前端用于 Qt qInstallMsgHandlerq 后端。它是跨平台和线程安全的。总有一天我会清理代码并将其发布给世界:)".. 现有的 " C++ 日志库” 你指的是什么?为什么它们“太重”?另外,您的自定义库如何解决问题?有什么基准吗?最重要的是,如果它不可用,它如何解决读者的问题?
      【解决方案4】:

      Log4Qt 是著名的 log4j 到 Qt 世界的一个端口。

      【讨论】:

        【解决方案5】:

        QDebug 是最好的选择,因为它提供了与框架其余部分的开箱即用集成,不会让您依赖第 3 方代码并且几乎涵盖了所有日志记录需求。

        【讨论】:

        • 但它不会记录到文件或系统事件日志中。
        • 默认情况下它不会这样做,但这对我来说不是一个好的默认值。如果你想重新路由 qDebug,参考这篇文章stackoverflow.com/questions/4954140/…
        • 我知道你可以重新路由 qDebug。对于成熟的应用程序来说,它仍然不够灵活。
        【解决方案6】:

        我没有使用 Qt,但对于日志记录,我使用的是 Dr'Dobb 的 Logging in C++ 的修改版本。原代码可以在here找到。

        我的修改是针对 Microsoft Windows 平台的(fopen 不允许文件读取共享),可以在 here 找到。

        【讨论】:

        • 在 Qt 中,有几个类具有非常舒适的人类可读的序列化工具,应该由一个好的 Qt 日志库隐式调用。一个通用的 C++ 日志框架在这里还不够好。
        【解决方案7】:

        关于“不幸的是 qDebug() 等不是线程安全的。如果你使用线程,它们会严重崩溃/中断。在内部它使用 QTextStream,它是可重入的,但不是线程安全的。”

        我严重怀疑,qDebug 被设计为同时使用。如果不是这样,请提交错误。

        【讨论】:

        • 来源好像是qtcentre.org/threads/…
        • 怀疑与否——没关系。 2011 年,至少在 1 个平台上,从多个线程中使用它确实会崩溃。如果它没有被记录为线程安全的,那么应该假设它不是线程安全的,因为实现可能会发生变化——这意味着如果它不起作用,它就不是一个错误。如果您想确保实现不会改变,那么您需要复制功能,这意味着无论如何您都在有效地编写自己的版本(只是有一个良好的开端)。如果文档说它在特定版本中是线程安全的,那么您可以使用它。
        【解决方案8】:

        取决于您希望如何使用该日志数据。

        如果在运行时用于调试,qWarning() 就可以了。

        如果您需要调试回顾(通常是服务器端代码),纯旧文本文件是最好的。最好按照日志写入的日期来组织这些日志文件。

        【讨论】:

          【解决方案9】:

          你可以看看:https://github.com/netresultsit/uniqlogger

          • LGPL
          • 线程安全
          • 多个后端:文件、彩色控制台、网络、rsyslog
          • 按文件大小和文件数量轮换文件
          • 支持压缩以前的文件 等

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-05
            • 2011-06-17
            • 1970-01-01
            • 1970-01-01
            • 2012-09-03
            • 1970-01-01
            • 2011-01-28
            • 2012-12-16
            相关资源
            最近更新 更多