My background is J2EE and one of the things that has been bugging me about the iPhone platform is that nobody seems to care about logging. When you have a complicated application with many layers and subsystems, it is very handy to be able to turn on and off logging for different sections of code.
Log4J is pretty much the industry standard implementation of the commons logging framework for Java. It allows you to have hierarchical logging categories that turn on/off logging at various levels (info,warn,error, etc). There’s a Cocoa port called log4cocoa, but I couldn’t find any documentation describing how to get it to work in an iPhone project.
Here are the steps I took to get log4cocoa to work in my projects
Create a New View-based Application Project



Check out log4cocoa and Custom Categories
Check out log4cocoa:
svn co https://log4cocoa.svn.sourceforge.net/svnroot/log4cocoa/trunk log4cocoa
A log4cocoa/lib3rd
A log4cocoa/lib3rd/OCMock.tgz
A log4cocoa/Log4Cocoa_Prefix.pch
A log4cocoa/source
A log4cocoa/source/L4StringMatchFilter.h
A log4cocoa/source/L4LevelRangeFilter.h
A log4cocoa/source/L4LevelMatchFilter.h
A log4cocoa/source/L4RollingFileAppender.m
A log4cocoa/source/L4LoggerStore.h
A log4cocoa/source/L4SimpleLayout.m
A log4cocoa/source/L4LoggingEvent.m
A log4cocoa/source/L4DenyAllFilter.h
A log4cocoa/source/L4FileAppender.h
A log4cocoa/source/L4StringMatchFilter.m
A log4cocoa/source/L4LevelRangeFilter.m
A log4cocoa/source/L4LevelMatchFilter.m
A log4cocoa/source/L4LoggerStore.m
A log4cocoa/source/L4FileAppender.m
A log4cocoa/source/L4AppenderProtocols.h
A log4cocoa/source/L4AppenderSkeleton.h
A log4cocoa/source/L4DenyAllFilter.m
A log4cocoa/source/L4BasicConfigurator.h
A log4cocoa/source/L4PropertyConfigurator.h
A log4cocoa/source/L4AppenderAttachable.h
A log4cocoa/source/L4Level.h
A log4cocoa/source/L4AppenderSkeleton.m
A log4cocoa/source/L4BasicConfigurator.m
A log4cocoa/source/L4PatternLayout.h
A log4cocoa/source/L4PropertyConfigurator.m
A log4cocoa/source/L4AppenderAttachable.m
A log4cocoa/source/L4Level.m
A log4cocoa/source/L4Layout.h
A log4cocoa/source/L4PatternLayout.m
A log4cocoa/source/L4ConsoleAppender.h
A log4cocoa/source/L4Layout.m
A log4cocoa/source/L4LogLog.h
A log4cocoa/source/L4LoggerProtocols.h
A log4cocoa/source/L4Filter.h
A log4cocoa/source/L4ConsoleAppender.m
A log4cocoa/source/L4Logging.h
A log4cocoa/source/L4LogLog.m
A log4cocoa/source/L4Filter.m
A log4cocoa/source/L4Logging.m
A log4cocoa/source/L4WriterAppender.h
A log4cocoa/source/L4Properties.h
A log4cocoa/source/L4WriterAppender.m
A log4cocoa/source/L4Properties.m
A log4cocoa/source/L4DailyRollingFileAppender.h
A log4cocoa/source/Log4CocoaDefines.h
A log4cocoa/source/Log4Cocoa.h
A log4cocoa/source/Tests
A log4cocoa/source/Tests/TestL4StringMatchFilter.m
A log4cocoa/source/Tests/TestL4LevelMatchFilter.m
A log4cocoa/source/Tests/TestL4LevelRangeFilter.m
A log4cocoa/source/Tests/TestL4PatternLayout.m
A log4cocoa/source/Tests/TestL4Properties.m
A log4cocoa/source/Tests/TestL4DenyAllFilter.m
A log4cocoa/source/Tests/data
A log4cocoa/source/Tests/data/test.properties
A log4cocoa/source/L4DailyRollingFileAppender.m
A log4cocoa/source/NSObject+Log4Cocoa.h
A log4cocoa/source/L4Logger.h
A log4cocoa/source/NSObject+Log4Cocoa.m
A log4cocoa/source/L4RootLogger.h
A log4cocoa/source/L4Logger.m
A log4cocoa/source/L4RollingFileAppender.h
A log4cocoa/source/L4SimpleLayout.h
A log4cocoa/source/L4LoggingEvent.h
A log4cocoa/source/L4RootLogger.m
A log4cocoa/xcconfig
A log4cocoa/xcconfig/Release.xcconfig
A log4cocoa/xcconfig/ReleaseLeopardOrLater.xcconfig
A log4cocoa/xcconfig/FrameworkTigerOrLater.xcconfig
A log4cocoa/xcconfig/Application.xcconfig
A log4cocoa/xcconfig/TigerOrLater.xcconfig
A log4cocoa/xcconfig/Debug.xcconfig
A log4cocoa/xcconfig/DebugLeopardOrLater.xcconfig
A log4cocoa/xcconfig/Coverage.xcconfig
A log4cocoa/xcconfig/CoverageLeopardOrLater.xcconfig
A log4cocoa/xcconfig/Framework.xcconfig
A log4cocoa/xcconfig/General.xcconfig
A log4cocoa/xcconfig/LeopardOrLater.xcconfig
A log4cocoa/xcconfig/Unittest.xcconfig
A log4cocoa/TODO.txt
A log4cocoa/demo
A log4cocoa/demo/AppController.m
A log4cocoa/demo/main.m
A log4cocoa/demo/Log4CocoaDemo-Info.plist
A log4cocoa/demo/LoggingThread.h
A log4cocoa/demo/log4cocoa.properties
A log4cocoa/demo/LoggingThread.m
A log4cocoa/demo/AppController.h
A log4cocoa/demo/English.lproj
A log4cocoa/demo/English.lproj/InfoPlist.strings
A log4cocoa/demo/English.lproj/MainMenu.xib
A log4cocoa/Info.plist
A log4cocoa/Tests-Info.plist
A log4cocoa/doc
A log4cocoa/doc/Doxyfile
A log4cocoa/COPYRIGHT.txt
A log4cocoa/Log4Cocoa.xcodeproj
A log4cocoa/Log4Cocoa.xcodeproj/treaves.pbxuser
A log4cocoa/Log4Cocoa.xcodeproj/eric.perspectivev3
A log4cocoa/Log4Cocoa.xcodeproj/treaves.mode1v3
A log4cocoa/Log4Cocoa.xcodeproj/treaves.mode2v3
A log4cocoa/Log4Cocoa.xcodeproj/eric.pbxuser
A log4cocoa/Log4Cocoa.xcodeproj/project.pbxproj
A log4cocoa/Log4Cocoa.xcodeproj/treaves.perspectivev3
A log4cocoa/readme.txt
A log4cocoa/English.lproj
A log4cocoa/English.lproj/InfoPlist.strings
U log4cocoa
Checked out revision 111.
Check out my category for NSDate to make int compliant with the missing NSCalendarDate:
git clone git://github.com/jeremyprz/categories.git
Initialized empty Git repository in /Users/jeremy/dev/sandbox/L4C-iPhone/categories/.git/
remote: Counting objects: 16, done.
Receiving objects: 100% (16/16), done.ceiving objects: 6% (1/16)
remote: Compressing objects: 100% (13/13), done.
remote: Total 16 (delta 7), reused 7 (delta 3)
Resolving deltas: 100% (7/7), done.
Add Empty Source Groups to your Project
- One for ‘Categories’
- Another for ‘Log4Cocoa’
‘Add > Existing Files…’ to the Categories Group
Add existing files to the Categories group by selecting the categories/NSDate-Calendar.* files.


‘Add > Existing Files…’ to the Log4Cocoa Group
Add existing files to the Categories group by selecting the log4cocoa/source/*.* files.


Modify _Prefix.pch File
You will need to add a single line to your project’s .pch file. In this project, the file is named ‘L4C_iPhone_Prefix.pch’. We are adding a single line to the file: #import "NSDate-Calendar.h"
This line will ensure that the unmodified log4cocoa files will our NSDate category instead of the NSCalendarDate, which is not available on the iPhone.

Add Log4Cocoa Code to the Application
At this point, your project should be fully able to use log4cocoa. Here is the plain vanilla AppDelegate from this example: #import "L4C_iPhoneAppDelegate.h"
#import "L4C_iPhoneViewController.h"
#import "Log4Cocoa.h"
@implementation L4C_iPhoneAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[[L4Logger rootLogger] setLevel:[L4Level all]];
[[L4Logger rootLogger] addAppender: [[L4ConsoleAppender alloc]
initTarget:YES
withLayout:[L4Layout simpleLayout]]];
L4Logger *theLogger = [L4Logger loggerForClass:[L4FunctionLogger class]];
[theLogger setLevel:[L4Level debug]];
log4CDebug(@"The logging system has been initialized.");
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end

Run your App
You should now be able to run the application and see log4cocoa output in the console.
