Enchilada
Enchilada

Reputation: 3919

Getting Console Logs for My Cocoa App

I'm making a crash reporter, and I can read the crash reporter files just fine within ~/Library/Logs/CrashReporter.

However, I want to also send along with the report any console (NSLog) information that was printed to the console (the stuff that one can see both in Xcode and in Console.app). However, I want to make sure I get only the logs for my app. I don't want logs from other apps.

How does one get the console logs for a specific app?

Upvotes: 2

Views: 3352

Answers (3)

Enchilada
Enchilada

Reputation: 3919

To make the app store the last few PIDs in an array in the user defaults, I wrote the following updateLastPids method. First, make sure to do, say,

#define kMaxNumberOfPids 5 //should be integer greater than zero!
#define ENLastPidsUserDefault @"ENLastPidsUserDefault";

By the way, I'm using 5 because I'm gonna let the app send me the logs for the last 5 runs, just in case the crash was a result of something getting messed up even earlier than on the last run; you can change 5 to 1 if you wish.

- (void)updateLastPids
{
  NSInteger currentPid = [[NSProcessInfo processInfo] processIdentifier];
  NSNumber *currentPidNumber = [NSNumber numberWithInt:currentPid];
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

  NSMutableArray *lastPidsArray = [[userDefaults arrayForKey:ENLastPidsUserDefault]
                                   mutableCopy];
  if (!lastPidsArray)
  {
    NSArray *newLastPidsArray = [NSArray arrayWithObject:currentPidNumber];
    [userDefaults setObject:newLastPidsArray forKey:ENLastPidsUserDefault];
  }
  else
  {
    if ([lastPidsArray count] == kMaxNumberOfPids)
    {
      [lastPidsArray removeObjectAtIndex:0]; //get rid of the oldest PID
      [lastPidsArray addObject:currentPidNumber];
      NSAssert([lastPidsArray count] == kMaxNumberOfPids, @"invalid count");
    }
    //In case I decrease kMaxNumberOfPids later on. (Or some PITA user added
    //stuff into the array by himself or herself!)
    else if ([lastPidsArray count] > kMaxNumberOfPids) 
    {
      [lastPidsArray removeObjectAtIndex:0];
      while ([lastPidsArray count] >= kMaxNumberOfPids)
        [lastPidsArray removeLastObject];
      [lastPidsArray addObject:currentPidNumber];
      NSAssert([lastPidsArray count] == kMaxNumberOfPids, @"invalid count");
    }
    else
    {
      [lastPidsArray addObject:currentPidNumber];
      NSAssert([lastPidsArray count] <= kMaxNumberOfPids, @"invalid count");
    }

    [userDefaults setObject:lastPidsArray forKey:ENLastPidsUserDefault];
  }
}

In my next answer I will show how I used the ASL Cocoa wrapper to get the console logs from the last PIDs (the PIDs should now be in the user defaults after running the above method).

Upvotes: 0

Peter Hosey
Peter Hosey

Reputation: 96323

Use the Apple System Logger API to search the system log for messages sent by your application.

Jim Dovey has published a Cocoa wrapper for ASL under a BSD license.

Note that the system log normally goes back about 24 hours, and may include multiple sessions and multiple runs of your app. Search for messages whose sender name is your app's name and whose process ID is your process's (getpid()).

Upvotes: 4

user23743
user23743

Reputation:

NSLog messages reported to the console go via a facility called asl (Apple System Logger). You can run a query to only get messages recorded by your processes: have a look at the asl_set_query(3) API.

Upvotes: 2

Related Questions