Thursday, May 24, 2012

Does your Xcode do this?

Screen Shot 2013-08-23 at 10.30.09 AM

Take a look at the screenshot above. Notice anything different in the Xcode console? Yup, those log statements have color!

When I'm implementing a new feature, or tracking down some odd bug, I end up writing a bunch of log statements. This helps me check all my assumptions, and trace the code flow. Ultimately it helps me narrow down the location of the problem.

But one thing I've noticed is that, when I have a bunch of debug log statements flying by in my console, it becomes easier to miss error messages. I think most developers have experienced this. The simple solution is to do something like this:

NSLog(@"*************** I'm going to see this log statement ***************");

But this only goes so far. I mean, it only works if you know what log statement you're looking for. What if things go wrong in other parts of the application, and some warning is spit out.

The problem becomes easier if you use a professional logging framework like Lumberjack. That way your error statements are different from your debugging statements.

DDLogError(@"Some important error message");
DDLogDebug(@"Just some debug message");

Using a tool like Lumberjack you could automatically format error messages differently than debug messages. (No changes needed to your log statements, just add a formatter.) In fact, if you wanted to, you could automatically add all those asterisks to any error messages.

But you know what would be better?  Color.

Color naturally catches your eye. You don't even have to think about it. For example, can you spot the error below?

2012-05-24 02:10:58:101 Printer[51197:403] Warming up printer
2012-05-24 02:10:58:101 Printer[51197:403] Checking toner levels
2012-05-24 02:10:58:101 Printer[51197:403] Spooling document
2012-05-24 02:10:58:101 Printer[51197:403] Dispatching paper
2012-05-24 02:10:58:101 Printer[51197:403] Paper jam
2012-05-24 02:10:58:101 Printer[51197:403] Spooling document
2012-05-24 02:10:58:101 Printer[51197:403] Printer warmed
2012-05-24 02:10:58:101 Printer[51197:403] Toner levels OK
2012-05-24 02:10:58:101 Printer[51197:403] Saving document

This is possible with the help of the XcodeColors plugin for Xcode!

And it gets even better with Lumberjack. Because Lumberjack now natively supports XcodeColors! Just tell Lumberjack what colors you'd like to use, for what log levels, and you're done!

And if color isn't available (e.g. XcodeColors isn't installed), then the framework just automatically does the right thing. So if you install XcodeColors on your machine, and enable colors in your team project, your teammates (without XcodeColors) won't suffer, or even notice.

Plus Lumberjack colors automatically work if you run your application from within a terminal! (E.g., not Xcode) If your terminal supports color (xterm-color or xterm-256color) like the in Lion, then Lumberjack automatically maps your color customizations to the closest available color supported by the shell!

Still using NSLog?!? Switch to Lumberjack. First, it's actually faster than NSLog. Second, most every other development community is already using a professional logging framework. Isn't it time the Apple development community caught up?


SAKrisT said...

Yes!! Thanks!

Igor Khomenko said...

Thanks! Looks like Android Log :)

Anonymous said...

Very Nice!

Adam Iredale said...


You are pure awesome. Thank you for your generous work of most admirable code quality.


neowinston said...

Great! Thanks for sharing!

Angelika Ophagen said...

This sounds so great, I want it for my project.

However, I could not get it installed...

Steve Cothern said...

Hi Robbie,

I am loving Lumberjack and XCodeColors, but am still having a little trouble -- this is an iOS setup. I have "XcodeColors=YES" set in my scheme's run env variables as described in your github instructions. During DDTTYLogger's initialize invocation, the call to getenv("TERM") returns "xterm-256color". I don't believe that this is the intent based upon the method comments about the treatment of the XcodeColors env var. If I comment out the "if" part of the TERM test and default to the "else" condition then coloring works as expected; otherwise, I get the escape sequence printing.

I discovered this during a separate test plugging Lumberjack into your TestXcodeColors project and adding a simple DDLogError statement. In that test, if I "unset TERM" at the console prompt prior to starting Xcode, then the DDLogError statement works as expected -- i.e., in red. However, this approach doesn't work for the iOS-based project.


Thanks for your great work,


Neale Morison said...

Robbie, I'm a technical writer for an IoT company called Zentri. We noticed your blog/github post CocoaAsyncSocket/wiki/CommonPitfalls and we liked the way you explained viewing TCP as a stream. We would like to include this information in our wiki with an attribution to you.

Can you let me know if this is OK? Thanks, neale dot morison at zentri dot com

Robbie Hanson said...

> We would like to include this information in our wiki with an attribution to you. Can you let me know if this is OK?

No problem.