2010-04-04 3 views
2

Я делаю репортера аварийной ситуации, и я могу читать файлы репортера аварии, просто отлично в ~/Library/Logs/CrashReporter.Получение журналов консоли для моего приложения Cocoa

Однако я хочу также отправить вместе с сообщением любую информацию о консоли (NSLog), которая была напечатана на консоли (материал, который можно увидеть как в Xcode, так и в Console.app). Тем не менее, я хочу убедиться, что у меня есть только журналы для моего приложения. Мне не нужны журналы из других приложений.

Как получить журналы консоли для конкретного приложения?

ответ

3

Используйте the Apple System Logger API для поиска в системном журнале сообщений, отправляемых приложением.

Jim Dovey опубликовал a Cocoa wrapper for ASL under a BSD license.

Обратите внимание, что системный журнал обычно возвращается около 24 часов и может включать в себя несколько сеансов и несколько прогонов вашего приложения. Поиск сообщений, имя отправителя которых - ваше имя приложения и, идентификатор процесса которого является вашим процессом (getpid()).

+0

Хорошо, какао-обертка звучит хорошо для меня :) Однако у вас есть образец кода, который демонстрирует, как я буду использовать его в моем случае? Кроме того, вы уверены, что это хорошая идея, что я согласен с ним PID? Я спрашиваю, потому что обычно, когда журналы будут отправлены мне, это будет в следующем запуске приложения, когда он разбился раньше. PID изменяется при последовательном запуске приложения? – Enchilada

+0

Нет, у меня нет образца кода. Прочитайте мои сообщения в блоге, чтобы понять концепции на работе, затем прочитайте заголовки для обертки Дови. API, который он ему дал, в точности соответствует стандарту ASL API. И да, PID отличается для последовательных процессов; поэтому вы хотите его искать, так что вы получите только результат последнего процесса. Вы можете сохранить свой последний PID в настройках по умолчанию пользователя. –

+0

Хорошо, спасибо. Кажется, работает нормально. Для дальнейшего использования я отправлю код здесь, чтобы показать, как я сделал то, что мне было нужно. – Enchilada

2

NSLog сообщения, сообщенные на консоль, проходят через объект под названием asl (регистратор системы Apple). Вы можете запускать запрос только для получения сообщений, записанных вашими процессами: посмотрите на API asl_set_query(3).

0

Чтобы приложение хранило последние несколько идентификаторов PID в массиве по умолчанию пользователя, я написал следующий метод updateLastPids. Во-первых, убедитесь, что делать, скажем,

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

Кстати, я использую 5, потому что я собираюсь позволить приложению отправить мне журналы за последние 5 прогонов, только в случае аварии был результат чего-то запутался даже раньше, чем на последнем прогоне; вы можете изменить 5 к 1, если хотите.

- (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]; 
    } 
} 

В следующем ответе я покажу, как я использовал ASL какао обертку, чтобы получить консоль журналы из последних PIDs (ИКИ должны теперь быть по умолчанию пользователя после выполнения описанной выше методы).

+0

«В следующем ответе ...». Вы можете просто отредактировать ответ, включив его, и получите один полный ответ. –

+0

'removeLastObject' удаляет последний объект. Если вы хотите, чтобы массив содержал последние пять, а не четыре самых старых и последних, то вам нужно удалить * первый * объект (ы) (как и в другом месте этого кода). Более того, вы можете вырезать большую часть этого дерева 'if' и цикла. Решение состоит в том, чтобы проверить, больше ли счетчик, чем максимальный, а затем, если это так, используйте 'removeObjectsInRange:', чтобы отменить разницу от начала массива. –

+0

Ok спасибо :) Однако, к моему вниманию, PID не уникальны. Они могут быть повторно использованы в любое время, скажем, после перезапуска или при переполнении счетчика ПИД. Поиск таких PID, как это, таким образом, не кажется очень безопасным способом и может привести к тому, что я получаю журналы из других приложений, кроме своего собственного приложения, чего я не хочу. Я, таким образом, думаю о первом поиске имени моего приложения, и * затем * фильтрует эти результаты, чтобы показывать только самые 5 PID этих. Я думаю, что это безопаснее вместо хранения PID и позже полагаться на них. Как вы думаете? – Enchilada

Смежные вопросы