【问题标题】:Turn off console logging for specific objects关闭特定对象的控制台日志记录
【发布时间】:2012-10-09 16:28:56
【问题描述】:

这有点烦人: 自从我开始使用 MPMoviePlayerController 以来,控制台中充满了来自 MPAVController 的信息。 例如:

[MPAVController] Autoplay: _streamLikelyToKeepUp: 1 -> 1
[MPAVController] Autoplay: Disabling autoplay

这有点烦人,因为我总是要搜索自己记录的信息。 有没有办法关闭特定对象或框架的日志记录?

【问题讨论】:

    标签: iphone objective-c xcode logging mpmovieplayercontroller


    【解决方案1】:

    我不认为这种过滤是开箱即用的。但是可以将stderrNSLog 使用)重定向到管道,在后台线程中从该管道读取,然后将通过过滤器的消息打印到 stdout(由调试器捕获为好)。这段代码完成了这项工作:

    int main(int argc, char *argv[])
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void) {
            size_t const BUFFER_SIZE = 2048;
    
            // Create a pipe
            int pipe_in_out[2];
            if (pipe(pipe_in_out) == -1)
                return;
    
            // Connect the 'in' end of the pipe to the stderr
            if (dup2(pipe_in_out[1], STDERR_FILENO) == -1)
                return;
    
            char *buffer = malloc(BUFFER_SIZE);
            if (buffer == 0)
                return;
    
            for (;;)
            {
                // Read from the 'out' end of the pipe
                ssize_t bytes_read = read(pipe_in_out[0], buffer, BUFFER_SIZE);
                if (bytes_read <= 0)
                    break;
    
                // Filter and print to stdout
                if (should_show(buffer)) // TODO: Apply filters here
                    fwrite(buffer, 1, bytes_read, stdout);
            }
    
            free(buffer);
            close(pipe_in_out[1]);
        });
    
        // Rest of main
    }
    

    请注意,此代码非常简单,并不能处理所有极端情况。首先,它捕获所有stderr 输出,而不仅仅是NSLog。也许这可以通过检查内容来过滤掉。 NSLog 输出始终以日期和时间开头。

    此代码的第二个问题是它不会尝试拆分/连接从管道中读取的字符串。不能保证每次阅读都会有一个NSLog。他们可能会聚在一起,也可能会太长而分裂。要处理这个问题,需要对从管道读取的数据进行额外处理。

    无论如何,对于许多实际用途,这应该足够了。

    【讨论】:

      【解决方案2】:

      您应该查看NSLogger。虽然 NSLog 没有给你任何关于你在运行中看到的内容的选择性,但 NSLogger 可以。 NSLogger 在 OS X 自己的窗口中显示来自设备(或模拟器)的输出。

      基本上它在输出中添加了设施和级别的概念。 Unix 向导可能会发现这种比较有问题,但我认为它与 syslog 非常相似。 NSLogger 查看器允许您显示一个或多个设施(您定义)的输出消息,这些设施也满足所需的最低级别。

      宏定义了您在输出窗口中看到的内容。摘录如下:

      #ifdef DEBUG
          #define LOG_GENERAL(level, ...)    LogMessageF(__FILE__,__LINE__,__FUNCTION__,@"general",level,__VA_ARGS__)
      #else
          #define LOG_GENERAL(...)    do{}while(0)
      #endif
      

      当 DEBUG 关闭时,不会出现任何消​​息。启用时,如果您在代码中有 LOG_GENERAL() 语句,并且您的查看器配置为显示设施“一般”并且您的级别足以显示,您会收到一条消息。

      它非常灵活,我非常喜欢它。添加到您的项目大约需要五分钟。请查看上面链接的 github 页面以获取完整详细信息并下载。

      (这并不能解决 MPAVController 用消息填充控制台的问题,但它确实将您想要的消息放在一个新窗口中,从而更容易控制、过滤和解释您感兴趣的内容。)

      【讨论】:

      • 谢谢,这很好。将来可以派上用场。
      【解决方案3】:

      如果可以的话,另一个选择是运行模拟器或运行 iOS

      当我使用 5.0 设备或 5.1 模拟器时,MPAVController 日志消息不会出现。但它们肯定会出现在 6.0 模拟器中。

      当然,通常应该使用当前的操作系统,但如果您正在处理项目的视频繁重的部分,则在处理特定任务集的同时运行早期的模拟器或设备是缓解这种日志记录问题的一种方法。

      这还提供了一些向后兼容性测试作为奖励。

      【讨论】: