Configuring centralized logging from iOS or OS X apps

Papertrail can accept logs from any iOS or OS X application using either of the following methods.

Choose a meaningful sender name

Your code decides the name which Papertrail identifies each log sender as. After setup, see choosing sender name below.

Method A: Use PaperTrailLumberjack

PaperTrailLumberjack is a CocoaLumberjack logger that supports logging via messages sent over UDP and TCP. It can be easily integrated into your Cocoa project via CocoaPods or Carthage.

Installation Instructions

pod "PaperTrailLumberjack"   
use_frameworks!    
pod "PaperTrailLumberjack/Swift"

Follow this, by executing

pod install

CocoaPods will generate a new xcode workspace, with all your pod dependencies, which you can now use.

git "https://bitbucket.org/rmonkey/papertraillumberjack.git"

Usage

PaperTrailLumberjack is extremely simple to use. Logging is as simple as calling CocoaLumberjack’s various logging statements, once you have a papertrail logger configured and added to it.

Note: Plain text TCP must be manually enabled on the log destination when TLS is disabled

Objective-C

RMPaperTrailLogger *paperTrailLogger = [RMPaperTrailLogger sharedInstance];
paperTrailLogger.host = @"<host>.papertrailapp.com"; //Your host here
paperTrailLogger.port = XXXXX; //Your port number here    
[DDLog addLogger:paperTrailLogger];
DDLogVerbose(@"Hi papertrailapp.com);

By default, logging is via TCP w/TLS. To turn off TLS, add the following line (before adding the logger to DDLog)

paperTrailLogger.useTLS = NO;

To log via UDP instead of TCP, add the following line (before adding the logger to DDLog)

paperTrailLogger.useTcp = NO;

If you would like to set either a custom machine name or program name, to your log messages, you can do so by overriding the following properties

paperTrailLogger.machineName = @"CustomMachineName";
paperTrailLogger.programName = @"CustomProgramName";

Swift

let paperTrailLogger = RMPaperTrailLogger.sharedInstance() as RMPaperTrailLogger!
paperTrailLogger.host = "<host>.papertrailapp.com" //Your host here
paperTrailLogger.port = XXXXX //Your port number here
DDLog.addLogger(paperTrailLogger)
DDLogVerbose("Hi papertrailapp.com")

To disable TLS, add the following line (before adding the logger to DDLog)

paperTrailLogger.useTLS = false

To log via UDP instead of TCP, add the following line (before adding the logger to DDLog)

 paperTrailLogger.useTcp = false 

If you would like to override the default machine or program names, that are displayed on your log messages, you can override the following properties

paperTrailLogger.machineName = "CustomMachineName"
paperTrailLogger.programName = "CustomProgramName" 

In both cases, change XXXXX and <host>.papertrailapp.com to the values shown on log destinations

Method B: Use CocoaAsyncSocket

An example of how to transmit log data using CocoaAsyncSocket and its sendData method is shown below:

GCDAsyncUdpSocket *udpSocket ;
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

 NSData *data = [
                   [NSString stringWithFormat:@"the syslog message will go here"]
                    dataUsingEncoding:NSUTF8StringEncoding
                ];

[udpSocket sendData:data toHost:@"<host>.papertrailapp.com" port:XXXXX withTimeout:-1 tag:1];

Log message

Papertrail supports both common syslog formats. Examples below use the newer RFC 5424 format.

An example syslog string is:

<22>1 2014-06-18T09:56:21Z sendername componentname - - - the log message

Instead of:

[NSString stringWithFormat:@"the syslog message will go here"]

You could do this to get an ISO 8601 timestamp on a device in any locale:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];

and then this to generate the message:

[NSString stringWithFormat:@"<22>1 %@ some-app some-component - - - the log message",[dateFormatter stringFromDate:[NSDate date]]];

Of course, parts of this can be reused across multiple calls or log messages and variables can be used to provide the app and component names and log message contents.

Choosing sender name

In addition to the log message, your code provides 2 values to Papertrail: the sender name and the program/component name.

We recommend using one or a small number of distinct values for the sender name (which is some-app in the example above). Most iOS apps are deployed on tens of thousands of devices, and with that many, the device isn’t really the most meaningful identifier. Having tens of thousands of unique senders in Papertrail doesn’t do anything except clutter the interface.

Instead, use a sender name which is not device- or user-specific.

If you have a user-specific value (such as a user ID, device UUID, or IP address), use the component/program name for that value.

Here’s a sample message which uses the iOS version as the sender name and your app’s own user ID for the component/program name:

<22>1 2014-06-18T09:56:21Z iOS-5.1 user-123456789 - - - the log message

Or a simpler example which uses the app name as the sender:

<22>1 2014-06-18T09:56:21Z my-app user-123456789 - - - the log message

The user ID will still be fully searchable in Papertrail, and your internal staff dashboard can even link to requests from a given user. In the example above, your dashboard could link to the query program:user-123456789 to see logs generated by that user’s device(s).