At last releasing SymbicLogKit. The kit is a simple logging/tracing framework polarized toward desktop (vs. server) development; an itch I’ve needed to scratch for quiet some time. I can already hear a poignant skeptic say that printf and NSLog do the job just fine, and that availability of other solutions such as Log4Coocoa and ASL (Apple System Logging) adds the insult to an injury.
I was not entirely happy with the existing solutions and the following points and decided to build my own framework.
- Tracing/logging/debugging code often serves a purpose long after its initial purpose, so it shouldn’t be removed much of the time following a debugging session. Instead logging code should be well thought out as to provide a developer with useful info in the future.
- If the above statement is accepted then we need a means of selectively blocking/enabling tracing code based on origin, level, thread, and other parameters. Without the ability to select what gets through we’ll simply get lost in the overly verbose output.
- Enabling/disabling parts of output should be snappy and should be done at runtime.
- A developer may want to do more useful things than
printfwith tracing output, so the output should be structured. - The framework should be UI centric, nice to look at, and should be easy to include and take advantage of in desktop applications.
The core of the framework is a singleton class called SYLogger. The instance of this class allows a user to add objects conforming to SYLoggerChannel protocol. Such objects are essentially output channels for a logger instance. There are two such objects provided by the framework: SYConsoleView and NSLoggingChannel.
SYConsoleView is an NSView that can be embedded into your application much the same way as any NSView subclass. The view is a tabular console for your output. On the other hand NSLoggingChannel is a simplistic channel that forwards your output to NSLog(...) call having formatted it nicely.
In order to make use of the framework the channels must be added to SYLogger instance. Messages are sent to the logger by invoking one of the following macros. There are 4 debugging levels defined at the moment (Debug, Info, Warning, Error) each assigning an immediacy level to a message. The variadic macros take NSString*s as parameters, the first being a format string (think [NSString stringWithFormat:...]).
#define elogDebug(str, ...)
#define elogInfo(str, ...)
#define elogWarn(str, ...)
#define elogError(str, ...)
There’s also an SYConfiguratorView which enables a user (a developer typically) to configure the logger. By configure I mean to provide a list of class-selector-level tripples describing which output should be blocked. The control is nothing more than a table with the first column hosting an ICU regular expression for class-name, the second hosting an ICU regular expression for selector-name (e.g. “dictionaryWithObjects:forKeys:count:”, “array”, etc.).
The above screenshot, for example, represents a configuration that blocks output from within drawRect: selectors of all classes whose names end in “View” as well as from all selectors whose name begins in “run” irrespective of a class they belong to.

[...] writing to a custom file. He has been looking // at SymbicLogKit return [NSURL urlWithString:@"http://www.fibrethread.com/blog/?p=20"]; } – (NSURL *)prettyNotPettyAds { // We talked about ads in apps and the web and we decided // [...]