Turn off console logging for specific objects

2019-02-06 09:36发布

问题:

It's some kind of annoying: Since I started using the MPMoviePlayerController the console is overfilled with information from MPAVController. Eg:

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

This is some kind of annoying because I always have to search for my own logged information. Is there a way to turn off logging for specific objects or frameworks?

回答1:

I don't think such filtering is possible out of the box. But it's possible to redirect stderr (which is used by NSLog) into a pipe, read from that pipe in a background thread and then print messages that pass through the filter onto stdout (which is captured by the debugger as well). This code does the job:

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
}

Please note that this code is quite simple and doesn't handle all corner cases. First of all it captures all stderr output and not just NSLog. Maybe this could be filtered out by checking against the content. NSLog output always starts with the date and time.

Second problem with this code is that it doesn't try to split/join strings it reads from the pipe. There's no guarantee that there will be one NSLog per read. They could be coming together or be too long and would be split. To handle this it would require additional processing of the data read from the pipe.

Anyway, for many practical purposes this should be enough.



回答2:

You should look into NSLogger. While NSLog doesn't give you any selectivity about what you see from run to run, NSLogger can. NSLogger displays output from the device (or simulator) in its own window in OS X.

Basically it adds the concept of facility and level to output. Unix wizards might find fault with this comparison but I see it as very similar to syslog. The NSLogger viewer lets you display output messages for one or more facilities (which you define) which also meet the minimum level required.

Macros define what you see in the output window. Here's an excerpt:

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

When DEBUG is off, no messages appear. When on, if you have a LOG_GENERAL() statement in code and your viewer is configured to display facility "general" and your level is sufficient to be displayed, you get a message.

It's incredibly flexible and I like it a lot. It takes about five minutes to add to your project. Please take a look at the github page linked above for full details and download.

(This will not solve the problem of MPAVController filling the console with messages, but it does put the messages you want in a new window, making it much easier to control, filter and interpret what you are interested in.)



回答3:

Another option, if you can use it, is to run either a simulator or a device running iOS < 6.0.

The MPAVController log messages do not appear for me when using a 5.0 device or the 5.1 Simulator. But they definitely appear in the 6.0 Simulator.

Of course one should generally use the current OS, but if one is working on a video heavy section of a project, running an earlier simulator or device while working on that particular set of tasks is a way to alleviate this logging headache.

This also provides some backward compatibility testing as a bonus.