Sunteți pe pagina 1din 27

All Topics Find tutorials, courses, and more...

Code Categories Learning Guides

IOS SDK

CocoaLumberjack:
Logging on Steroids
by Bart Jacobs 4 Mar 2013
8 Comments

1 3

Logging is one of the most useful instruments to inspect, understand, and debug
iOS and OS X applications. You are probably familiar with the NSLog function
provided by the Foundation framework, but have you ever felt the need for
something more powerful? CocoaLumberjack is an open source library created and
maintained by Robbie Hanson. CocoaLumberjack takes logging to a whole new
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
maintained by Robbie Hanson. CocoaLumberjack takes logging to a whole new
level, and in this tutorial I will show you how to setup and use CocoaLumberjack in
an iOS application.

Logging? Who Needs Logging?


Logging diagnostic information to a console, file, or remote server is widely used in
almost any type of software development. It is one of the simplest forms of
debugging, which is probably why it is so widespread. It is the first tool that I use
when I am debugging or trying to understand a complex piece of logic regardless of
the language. It is easy, fast, and comes with very little overhead.

Why should you use CocoaLumberjack if all it does is send pieces of data to the
console or a file? One reason is that CocoaLumberjack is (mostly) faster than the
NSLog function that the Foundation framework provides us with. Thanks to a
number of convenient macros provided by CocoaLumberjack, switching from NSLog
to CocoaLumberjack is as easy as replacing your NSLog with DDLog statements.

Another benefit of CocoaLumberjack is that one log statement can be sent to


multiple loggers (console, file, remote database, etc.). You can configure
CocoaLumberjack in such a way that it behaves differently depending on the build
configuration (Debug, Release, etc.). There is much more that CocoaLumberjack
can do for you so let me show you how to get started with this nifty library.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Step 1: Setting Up CocoaLumberjack
Create a new project in Xcode by selecting theSingle View Application template
from the list of available templates (figure 1). Name your application Logging, enter
a company identifier, set iPhone for the device family, and then check Use
Automatic Reference Counting. The rest of the checkboxes can be left
unchecked for this project (figure 2). Tell Xcode where you want to save the project
and hit the Create button.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Adding the CocoaLumberjack library to your project is as easy as downloading the
latest version from GitHub, extracting the archive, and dragging the folder named
Lumberjack into your project. The core files are DDLog.h/.m, DDASLLogger.h/.m,
DDTTYLogger.h/.m, and DDFileLogger.h/.m. The other files in the folder are stubs
for more advanced uses of CocoaLumberjack, which I won't cover in this tutorial.
You can ignore or delete these files.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
If you take a peak inside DDLog.h and DDLog.m, you may be surprised by the
number of lines of code in these files. As I said, CocoaLumberjack has a lot of
really useful features. CocoaLumberjack is more powerful than NSLog because it
takes advantage of multi-threading, Grand Central Dispatch, and the power of the
Objective-C runtime.

You will also notice that there are a surprising number of macros defined in
DDLog.h. We won't use the majority of these macros. The macros that we will use
in this tutorial are DDLogError , DDLogWarn , DDLogInfo , and DDLogVerbose. They
all perform the same task, but each macro is associated with a log level. I will talk
more about log levels in a few moments.

Before we start using CocoaLumberjack, it is a good idea to add an import


statement to the project's precompiled header file. Open Logging-Prefix.pch and
add an import statement for DDLog.h. This ensure that the macros defined in
DDLog.h are available throughout the project.

01 #import <Availability.h>
02
03 #ifndef __IPHONE_4_0
04 #warning "This project uses features only available in iOS SDK 4.0 and later."
05 #endif
06
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
06
07 #ifdef __OBJC__
08 #import <UIKit/UIKit.h>
09 #import <Foundation/Foundation.h>
10
11 #import "DDLog.h"
12 #endif

Step 2: Adding a Logger


Configuring CocoaLumberjack is easy. First, however, we need to import several
classes of the CocoaLumberjack library. At the top of MTAppDelegate.m, add an
import statement for DDASLLogger.h, DDTTYLogger.h, and DDFileLogger.h (see
below). The first two classes are in charge of sending log messages to the Console
application (Console.app) and Xcode's Console. The DDFileLogger class takes
care of writing log messages to a file on disk.

1 #import "MTAppDelegate.h"
2
3 #import "DDASLLogger.h"
4 #import "DDTTYLogger.h"
5 #import "DDFileLogger.h"
6 #import "MTViewController.h"

In the application delegate's application:didFinishLaunchingWithOptions:


open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
method, we add two loggers as shown below. Both DDASLLogger and DDTTYLogger
are singletons as you may have noticed. With this setup, we mimic the behavior of
the NSLog function, that is, log messages are sent to the Console application
(Console.app) and Xcode's Console.

01 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions


02 // Configure CocoaLumberjack
03 [DDLog addLogger:[DDASLLogger sharedInstance]];
04 [DDLog addLogger:[DDTTYLogger sharedInstance]];
05
06 // Initialize View Controller
07 self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewControlle
08
09 // Initialize Window
10 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen
11
12 // Configure Window
13 [self.window setRootViewController
:self.viewController];
14 [self.window makeKeyAndVisible];
15
16 return YES;
17 }

This is all that we have to do to get started with CocoaLumberjack. You can test this
out by adding the following log statements to the viewDidLoad method of the
MTViewController class. Build and run the project in the iOS Simulator to see if
everything works as expected.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
1 - (void)viewDidLoad {
2 [super viewDidLoad];
3
4 DDLogError(@"This is an error."
);
5 DDLogWarn(@"This is a warning."
);
6 DDLogInfo(@"This is just a message."
);
7 DDLogVerbose(@"This is a verbose message."
);
8 }

Did you also run into a compiler error? The compiler error readsUse of undeclared
identifier 'ddLogLevel'. It seems that we need to declare ddLogLevel before we
can make use of CocoaLumberjack. This is actually a feature of CocoaLumberjack.
By declaring and dynamically assigning a value to ddLogLevel we can configure
CocoaLumberjack in such a way that log statements are executed based on the
build configuration. To understand what I mean, amend the precompiled header file
of our project (Logging-Prefix.pch) as shown below.

01 #import <Availability.h>
02
03 #ifndef __IPHONE_4_0
04 #warning "This project uses features only available in iOS SDK 4.0 and later."
05 #endif
06
07 #ifdef __OBJC__
08 #import <UIKit/UIKit.h>
09 #import <Foundation/Foundation.h>

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
#import <Foundation/Foundation.h>
10
11 #import "DDLog.h"
12 #endif
13
14 #ifdef DEBUG
15 static const int ddLogLevel = LOG_LEVEL_VERBOSE;
16 #else
17 static const int ddLogLevel = LOG_LEVEL_ERROR;
18 #endif

By default, CocoaLumberjack defines four log levels, (1) error, (2) warning, (3) info,
and (4) verbose. Defining log levels is very common in logging libraries (e.g., log4j
and log4php). By assigning a log level to a log statement, it can be categorized,
which is very useful as you will see in a moment. In the precompiled header file, we
declare ddLogLevel and assign a value to it. The value of ddLogLevel determines
which log statements are executed and which are ignored. In other words, if the
build configuration is equal to Debug (read: if the preprocessor macro DEBUG is
defined), then ddLogLevel is equal to LOG_LEVEL_VERBOSE, the highest log level.
This means that every log statement will be executed. However, if the build
configuration is not equal to Debug, then only log statements with a log level of
error are executed. It is important to know that the log levels are ordered as you
can see in DDLog.h where they are defined.

Why is this useful? This provides a very easy mechanism to control what is being
logged based on the build configuration. You can try this out by changing the
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
current active scheme in Xcode. Stop the application and click the active scheme
named Logging on the right of the stop button (figure 3). SelectEdit Scheme...
from the menu and click Run Logging on the left (figure 4). Under the Info tab, set
the Build Configuration to Release (figure 4). With this option, you select the build
configuration that Xcode should use when the application runs in the iOS Simulator.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
If you now build and run your project in the iOS Simulator, you should only see log
statements with a log level of error printed to Xcode's Console. All log statements
with a log level higher than error are ignored. Keep in mind that the DEBUG
preprocessor macro is named CONFIGURATION_DEBUG in Xcode 3. You can read
more about this on the CocoaLumberjack's Wiki.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Step 3: Logging to a File
Logging to a file is a piece of cake with CocoaLumberjack. Not only is it easy to set
up, CocoaLumberjack comes with a number of useful options, such as limiting the
file size of log files and setting a rolling frequency. You can even tell
CocoaLumberjack to remove old log files as new log files are created. Let me show
you how this works.

Revisit the application delegate's application:didFinishLaunchingWithOptions:


method and update its implementation as shown below. After initializing an instance
of DDFileLogger, we configure it by (1) setting the maximum file size of each log
file (in bytes), (2) setting the rolling frequency to 24 hours, and (3) setting the
maximum number of log files that should be kept to seven. Don't forget to add the
file logger as we did earlier.

01 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions


02 // Configure CocoaLumberjack
03 [DDLog addLogger:[DDASLLogger sharedInstance]];
04 [DDLog addLogger:[DDTTYLogger sharedInstance]];
05
06 // Initialize File Logger
07 DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
08
09 // Configure File Logger
10 [fileLogger setMaximumFileSize:(1024 * 1024)];
11 [fileLogger setRollingFrequency:(3600.0 * 24.0)];
12 [[fileLogger logFileManager] setMaximumNumberOfLogFiles
:7];
13 [DDLog addLogger:fileLogger];
14
15 // Initialize View Controller
16 self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewControlle
17
18 // Initialize Window
19 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen
20
21 // Configure Window
22 [self.window setRootViewController
:self.viewController];
23 [self.window makeKeyAndVisible];
24
25 return YES;
26 }

Before you build and run the project, open the Finder and browse to the following
location, ~/Library/Application Support/iPhone
Simulator//Applications//Library/Caches/. As you can see, the path might be
slightly different depending on which version of the iOS Simulator you are using.
Run the application in the iOS Simulator and inspect the contents of the Caches
directory. It should now have a folder named Logs containing one text file named
log-XXXXXX.txt. The last six characters of the file name are unique to prevent log
files from being overwritten. It is possible to specify the location where the log files

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
are stored. Keep in mind that he Caches directory can be emptied by the operating
system at any time. If you want to store your application's log files in a safer
location, then I suggest storing them in the application's Documents directory.

Bonus: Colors
Even though colors seem like nothing more than eye candy, every developer knows
how important colors are when working in a code editor. With CocoaLumberjack,
you can add color to Xcode's Console. Robbie Hanson, the creator of
CocoaLumberjack, also contributed to an Xcode plugin named Xcode Colors.
CocoaLumberjack works very well with Xcode Colors. Download the latest version
of Xcode Colors, extract the archive, and put its contents in Xcode's plug-ins folder
(located at ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/
),
and restart Xcode. Note that it might be necessary to manually create the plug-ins
folder if it isn't present.

To enable colors in Xcode's Console, head back to the


method and tell the shared
application:didFinishLaunchingWithOptions:
instance of the TTYLogger class to enable colors (see below). CocoaLumberjack
uses default colors if you don't specify a color for a specific log level. Overriding the
default color settings is easy as shown below. Run the application in the iOS
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Simulator and inspect Xcode's Console window to see the result (figure 5).

01 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions


02 // Configure CocoaLumberjack
03 [DDLog addLogger:[DDASLLogger sharedInstance]];
04 [DDLog addLogger:[DDTTYLogger sharedInstance]];
05
06 // Enable Colors
07 [[DDTTYLogger sharedInstance] setColorsEnabled:YES];
08 [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor greenColor
09
10 // Initialize File Logger
11 DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
12
13 // Configure File Logger
14 [fileLogger setMaximumFileSize:(1024 * 1024)];
15 [fileLogger setRollingFrequency:(3600.0 * 24.0)];
16 [[fileLogger logFileManager] setMaximumNumberOfLogFiles
:7];
17 [DDLog addLogger:fileLogger];
18
19 // Initialize View Controller
20 self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewControlle
21
22 // Initialize Window
23 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen
24
25 // Configure Window
26 [self.window setRootViewController
:self.viewController];
27 [self.window makeKeyAndVisible];
28
29 return YES;

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
29 return YES;
30 }

I already mentioned that CocoaLumberjack defines four log levels by default. It is


possible, however, to define custom log levels. I won't discuss custom log levels in
this tutorial, but if you want to know more about this feature, then I suggest that you
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
read the article about custom log levels on CocoaLumberjack's Wiki.

Combining colors with custom log levels results in a very powerful tool to collect
data and debug an application. Keep in mind that CocoaLumberjack has a lot more
to offer than what I have shown in this short tutorial. With CocoaLumberjack, you
can create custom loggers as well as custom formatters. Custom loggers are
especially useful if you want to log to a database or send log files to a remote
server at regular time intervals. CocoaLumberjack really is a powerful library that
has become an indispensable tool in my toolbox.

Conclusion
Logging application data and diagnostic information to the console or a file can be
very useful when debugging problems both during development and production.
Having a solid logging solution in place is therefore essential. Along with many other
developers, I have created custom logging solutions for many projects, but
CocoaLumberjack is an ideal replacement and it has a lot more to offer.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Advertisement

Difficulty: Suggested Tuts+ Course


Beginner
Length:
Short
Categories:

iOS SDK Mobile Development

Translations Available:

Tuts+ tutorials are translated by our community


members. If you'd like to translate this post into
another language, let us know! The Swift Programming Language Start
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Download Attachment
Related Tutorials

View Debugging in Xcode 6


Code
About Bart Jacobs
Bart Jacobs runs Code Foundry, a mobile
and web development company based in
Belgium and writes about iOS Building a Logger Mixin in Sass
development on his blog. Bart is also the mobile Web Design
editor of Tuts+.

10 Xcode Plugins for iOS


Development
Code

Jobs

Web Developer / Site Management


at Zanes Law in Phoenix, AZ, USA

Advertisement
PHP Coder with Magento Knowledge
at Yoginet Web Solutions in New Delhi,
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Delhi, India

Envato Market Item

8 Comments Mobiletuts+

Sort by Best

Join the discussion

Robin a year ago

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
If you also have problems with the colors in Xcode you maybe forgot the same thing. You have to add (in
AppDelegate or wherever..) the following line to activate the coloring plugin:
setenv("XcodeColors", "YES", 0);
4 Reply Share

Bart Jacobs Mod > Robin 10 months ago


Thanks for pointing this out, Robin.
1 Reply Share

Jose Ines Cantu Arrambide a month ago


Do system log notifications get written to the file as well ?
Reply Share

isa56k 6 months ago


Great tutorial, I got this working a charm on iOS but I'm having some issues with an OSX command line a
I'm writing.

The build error I'm getting is...

Undefined symbols for architecture x86_64:


"_OBJC_CLASS_$_DDASLLogger", referenced from:
objc-class-ref in BTLECentral.o
"_OBJC_CLASS_$_DDLog", referenced from:
objc-class-ref in BTLECentral.o
"_OBJC_CLASS_$_DDTTYLogger", referenced from:
objc-class-ref in BTLECentral.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Am I wrong in thinking LumberJack supports OSX as well as iOS development?
Reply Share

isa56k > isa56k 6 months ago


Figured it out... I had dragged and dropped the LumberJack headers into my project... turns out thi
good. I deleted them and then added using File>Add Files and all works ok now.
Reply Share

Purna Chandra rao a year ago


Nice introduction to logging tool. Thanks you very much.
Reply Share

Anam a year ago


How can we restrict to not print logs on console? I mean I just want to have logs in file.
Reply Share

steven marks a year ago


Greets - thanks for the awesome tutorial!
Reply Share

Subscribe d Add Disqus to your site Privacy

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Advertisement

18,889 Tutorials 461 Video Courses


Teaching skills to millions worldwide.

Follow Us Email Newsletters

Get Tuts+ updates, news, surveys &


offers.

Email Address
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Help and Support Email Address

FAQ
Subscribe
Terms of Use
Contact Support Privacy Policy
About Tuts+
Advertise
Teach at Tuts+

Custom digital services like logo design, WordPress installation, video


production and more.
Check out Envato Studio

Build anything from social networks to file upload systems. Build faster
with pre-coded PHP scripts.
Browse PHP on CodeCanyon

2014 Envato Pty Ltd. Trademarks and brands are the property of their respective
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
owners.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com

S-ar putea să vă placă și