【问题标题】:Immediately flushing log statements using the Cocoa Lumberjack logging framework, the way NSLog flushes to console使用 Cocoa Lumberjack 日志框架立即刷新日志语句,NSLog 刷新到控制台的方式
【发布时间】:2012-01-31 06:15:43
【问题描述】:

许多 iOS 开发人员发现 Cocoa Lumberjack Logging framework 可以满足简单的 NSLog 语句所不能满足的需求。这让人想起 Java 世界中的 Log4J。

无论如何,我已经为 Lumberjack 编写了自己的自定义格式化程序,但我没有看到任何关于如何立即刷新日志语句的文档。

例如,如果我在调试器中运行并点击了NSLog() 语句,它会立即将日志语句刷新到控制台。这就是我想从 Lumberjack 中的 DDLogVerbose() 调用中获得的行为。

现在,如果我希望它们在调试一段代码时立即吐出,我会返回并将这些语句更改为 NSLog() 语句。由于 Lumberjack 如此强大,我不得不认为有一种方法可以将其配置为无延迟地刷新。

有人知道怎么弄吗?

【问题讨论】:

    标签: ios logging flush nslog cocoalumberjack


    【解决方案1】:

    您可以等待日志队列超时完成:

    - (void)waitForLog {
      dispatch_semaphore_t sema = dispatch_semaphore_create(0);
      dispatch_async(DDLog.loggingQueue, ^{
        dispatch_semaphore_signal(sema);
      });
      dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)));
    }
    

    【讨论】:

      【解决方案2】:

      我在DDLog.h 文件中找到了答案。 Lumberjack 具有异步和同步日志记录的概念。在最初阅读时,我并没有意识到这是为了什么。

      基本上,如果您希望日志语句按顺序输出,则需要使其同步(尽管正如 Mike 所说,这会降低性能)。因此,这只能在调试情况下进行。理想情况下,我会将另一个标头和/或其他一些预处理器宏放在一起,以确保我不会让开关处于同步状态。

      这就是你要做的:

      1. 打开DDLog.h
      2. 转到#define LOG_ASYNC_ENABLED YES 的行。您可以在一个位置将其更改为 NO,以便全面同步日志记录,或者您可以更改各个级别,如下所示。

      请注意,标头不鼓励更改 DDLog.h 文件本身。因此,按照 Lumberjack wiki 页面 link 上的说明,他们解释了如何使用不同的头文件来表达这些覆盖自定义。

      使用它,这是我成功编写和测试的内容,作为“MyAppLumberjack.h”头文件,我在我的应用程序的预编译头文件中导入:

      #import "DDLog.h"
      #import "DDASLLogger.h"
      #import "DDTTYLogger.h"
      
      // ========================= Overrides ========================================
      // --> per https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels
      // ----------------------------------------------------------------------------
      
      // Are we in an optimized (i.e. Release) build?
      #ifdef __OPTIMIZE__
          // YES: Nothing to do from the default. (You could simplify this by using #ifndef above instead)
      #else
          // NO: We're in a Debug build. As such, let's configure logging to flush right away.
          // Undefine the asynchronous defaults:
          #undef LOG_ASYNC_VERBOSE
          #undef LOG_ASYNC_INFO
          #undef LOG_ASYNC_WARN
      
          // Define the logs levels to be synchronous:
          #define LOG_ASYNC_VERBOSE   (NO && LOG_ASYNC_ENABLED)   // Debug logging will be synchronous
          #define LOG_ASYNC_INFO      (NO && LOG_ASYNC_ENABLED)   // Info logging will be synchronous
          #define LOG_ASYNC_WARN      (NO && LOG_ASYNC_ENABLED)   // Warn logging will be synchronous
      #endif
      

      【讨论】:

        【解决方案3】:

        您可以尝试在 DDTTYLogger.m 的- (void)logMessage:(DDLogMessage *)logMessage 函数中的if (logMsg) 底部添加fflush(stderr);

        刷新每条日志消息的缺点是您可能会遇到性能下降,但如果您将其用于调试,则可能无关紧要。

        【讨论】:

        • 谢谢迈克。这是一个明智的假设。不幸的是,它没有用。我也尝试过刷新标准输出,但这也不起作用(这是有道理的 - 整个方法似乎正在建立对标准错误的输出)。
        猜你喜欢
        • 1970-01-01
        • 2016-11-07
        • 2013-12-11
        • 2011-04-20
        • 1970-01-01
        • 2013-09-17
        • 2013-05-14
        • 2017-01-16
        • 2012-10-21
        相关资源
        最近更新 更多