• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Now available -- Re: [ANN] UKCrashReporter 0.1
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Now available -- Re: [ANN] UKCrashReporter 0.1


  • Subject: Re: Now available -- Re: [ANN] UKCrashReporter 0.1
  • From: Alan Shouls <email@hidden>
  • Date: Thu, 9 Feb 2006 13:26:58 +0000

from cocoadev

Alan


On 8 Feb 2006, at 12:18, Scott Anguish wrote:

A copy of Uli Kusterer's UKCrashReporter v 0.1 is now available at http://www.stepwise.com/temp/UKCrashReporter_21-35-21.zip

Uli's original announcement follows
...
UKCrashReporter is a simple function that you can call at application startup to send crash reports for your application to a CGI on your server. No patches, no daemons, no helper applications.

In case people are interested, I attach below some code I used in a program of my own (built for household use, never released). Rather than polling on start-up I used launchd to watch the crash log and had it send the log back to my web server immediately when the program crashed.


This method has both advantages and disadvantages over Uli's code.
There are two core advantages as I see it. Firstly, in the case of programs like share-ware, it's not uncommon for people to never run the program again if it crashes soon after it's first started. If you only check for crashes on a subsequent run you may miss useful information. Secondly, if the program is crashing early on in the start-up process then the report might never get sent. (In the case of my program, which was crashing on my mother at one point, the problem was a corrupt preferences file and I think that that would stop Uli's code looking up the last crash date and it would never send the report).


The flip side of this is that my code requires a secondary helper application to send the report. I used a simply command line utility (which I'm not including because it's rubbish code I wrote years ago and the guts of Uli's code would be a much better place to start from than my thing). That said, the helper app can reside inside your application and the code below copes with the user moving or renaming your application and it is removed cleanly by deleting the application.

Anyway, the code is below.  Enjoy!

	Nicko


=====================

//
//  NvSCrashReporter.m
//
//  Created by Nicko van Someren on 08/02/2006.
//  Copyright 2006 nicko.org. All rights reserved.
//

// This code is free for anyone to use for commercial or non-commercial purposes.

// Caveat Machinator!
// No guarantee is expressed or implied. This code may or may not do what you need.
// Read it, understand it and only then use it if you think it might be useful.


// When the application's crash log is updated the reportProg program is called with
// the program name, the URL to which to send the files, the crash log file name and
// optionally a list of extra files (e.g. preferences or support files).


#import "NvSCrashReporter.h"

static BOOL reporterStarted = NO;
static NSString *launchctlPath = @"/bin/launchctl";

@implementation NvSCrashReporter

+ (BOOL) registerCrashReporter: (NSString *) reportProg // Null means HttpPoster in the main bundle
URLString: (NSString *) target // Must be specified
applicationName: (NSString *) name // Null means the main bundle name
crashLog: (NSString *) logFile // Log file to watch, or NULL for the default
extraFiles: (NSArray *) extras { // Optional extra files to be sent (e.g. preferences)


    if (reporterStarted) {
        NSLog(@"Reporter already started");
        return NO;
    }

    NSFileManager *defMan = [NSFileManager defaultManager];
    NSString *launchFile;

// Start by getting hold of various information about the bundle of the calling application
NSBundle *b = [NSBundle mainBundle];
NSDictionary *info = [b infoDictionary];


    // Can't post, won't post
    if (!target)
        return NO;

    // Default name for the crash posting porgram
    if (!reportProg)
        reportProg = @"HttpPoster";
    if (![reportProg hasPrefix: @"/"])
        reportProg = [b pathForResource: reportProg ofType: Nil];

    // Get the name of the program if we're not already given it
    if (!name)
        name = [[b infoDictionary] objectForKey: @"CFBundleName"];
    if (!name)
        name = [b bundleIdentifier];
    if (!name)
        return NO;

// Make sure that the log file exists (launchd needs this)
if (!logFile)
logFile = [[NSString stringWithFormat: @"~/Library/Logs/CrashReporter/%@.crash.log", [info objectForKey: @"CFBundleExecutable"] ] stringByExpandingTildeInPath];
if (![defMan fileExistsAtPath: logFile]) {
NSLog(@"Crash log does not exist; touching the file");
if (![@"" writeToFile: logFile atomically: YES]) {
NSLog(@"Cound not touch crash log file");
return NO;
}
}


NSLog(@"Parameters after defaulting:\ntarget=%@\nreportProg=%@\nname=%@\nlogFile=%@", target, reportProg, name, logFile);

// Ensure the presence of the directory for the launch files
launchFile = [@"~/Library/Application Support/NvSCrashReporter" stringByExpandingTildeInPath];
BOOL isDir;
if ([defMan fileExistsAtPath: launchFile isDirectory: &isDir]) {
if (!isDir)
return NO;
} else {
if (![defMan createDirectoryAtPath: launchFile attributes: Nil])
return NO;
}


    NSLog(@"Reporter directory looks OK");

// Construct the launch file path
launchFile = [launchFile stringByAppendingPathComponent: [NSString stringWithFormat: @"%@.launch.plist", name]];


if ([defMan fileExistsAtPath: launchFile]) {
// There seems to be an existing launch file, so we ask launchd to unload it
// since it my be an old version or the user moved the application elsewhere.
NSLog(@"Unloading old launcher");
[[NSTask launchedTaskWithLaunchPath: launchctlPath arguments: [NSArray arrayWithObjects: @"unload", launchFile, nil]] waitUntilExit];
}


// Now we can build a new launchd plist
NSMutableDictionary *ld = [NSMutableDictionary dictionaryWithCapacity: 6];
[ld setObject: [NSString stringWithFormat: @"org.nicko.CrashReporter.%@.%@", [b bundleIdentifier], NSUserName() ] forKey: @"Label"];
[ld setObject: [NSNumber numberWithBool: YES] forKey: @"OnDemand"];
NSMutableArray *progArgs = [NSMutableArray arrayWithCapacity: 8];
[progArgs addObject: reportProg];
[progArgs addObject: name];
[progArgs addObject: target];
[progArgs addObject: logFile];
if (extras)
[progArgs addObjectsFromArray: extras];
[ld setObject: progArgs forKey: @"ProgramArguments"];
[ld setObject: [NSArray arrayWithObject: logFile] forKey: @"WatchPaths"];


    NSLog(@"Created new launch file: %@", ld);

    // Write the plist into the launch file
    if (![ld writeToFile: launchFile atomically: YES])
        return NO;

    NSLog(@"Launch file saved; trying to load into launchd");

// Finally, ask launchd to load the file
NSTask *t = [NSTask launchedTaskWithLaunchPath: launchctlPath arguments: [NSArray arrayWithObjects: @"load", launchFile, nil]];
[t waitUntilExit];
if ([t terminationStatus]) {
NSLog(@"Launchd failed to register crash reporter; returned %d", [t terminationStatus]);
return NO;
}


    NSLog(@"Success!");

    reporterStarted = YES;

    return YES;
}

@end

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Prev by Date: my text goes under a the scrollers....
  • Next by Date: Re: Core Data and @count keypath
  • Previous by thread: [solved] my text goes under a the scrollers....
  • Next by thread: UTI tree
  • Index(es):
    • Date
    • Thread