Как перенаправить все ошибки, включая необработанные исключения, вызовы NSLog и другие журналы, в файл журнала в Mac OS X? - PullRequest
15 голосов
/ 02 декабря 2010

Я пытаюсь найти каркас журналирования для приложения Какао, написанный на ObjC.

То, что я пытался сделать до сих пор:

  1. Используйте NSLog, но потом поймите, что его очень сложно настроить и перенаправить. Я полагаю, что мог бы взломать его и написать макрос, который получает требуемую информацию, такую ​​как идентификатор потока, текущая функция, текущая строка, текущий файл, текущее время, сообщение и т. Д., А затем использует NSLog, однако ...
  2. В конечном итоге NSLog использует NSLogv, который в конечном итоге использует asl, поэтому я подумал, что это «фантастика», я вместо этого попробовал использовать asl с клиентом по умолчанию и контекстом (если бы я делал это правильно, мне пришлось бы создать нового клиента для каждого потока), однако, если я не создаю макрос, это также очень многословно, и я заметил, что журналы, отправленные через asl, получили широковещательную систему, тогда как NSLog зарегистрировался только в stderr, и я хочу, чтобы они оба переходили на одно и то же войти!
  3. Затем я заметил, что ошибки отформатированы по-другому (разные метки даты и т. Д.), Поэтому теперь существует третий контекст ведения журнала.

Какую настройку каркаса ведения журналов я могу использовать, чтобы ВСЕ сообщения регистрировались через эту платформу удобным способом, чтобы в случае проблем с приложением разработчик мог получить файлы журнала и выяснить, что пошло не так?

Я не хочу просто перенаправлять stderr, я хочу иметь структурированный вывод журнала, который содержит все журналы. Я не хочу, чтобы некоторые журналы поступали на стандартный вывод, я не хочу, чтобы какие-либо журналы отправлялись в syslogd, я просто хочу, чтобы все журналы были записаны в один файл, который надежно идентифицирует всю соответствующую информацию об этом сообщении журнала (например, ID потока, сообщение, функция, которая вызывает журнал, и т. д.) в формате, который легко просматривать и визуализировать.

Я хочу перенаправить все текущие журналы в новое место назначения.

У кого-нибудь есть предложения?

EDIT:

Фактически, то, что я хочу сделать, в терминах ObjC:

  1. Выполните "метод swizzling" в функции NSLog. Это возможно? Можно ли (повторно) настроить использование Apple System Logger для переопределения любой предыдущей конфигурации службы в том же приложении?
  2. Определите все места, где я должен ловить необработанные исключения. Это включает, но, возможно, не ограничивается: Необработанные исключения какао. Необработанные исключения ObjC. Необработанные исключения C ++. Unix Signals.
  3. Поймайте и зарегистрируйте стек для ошибок, подобных тем, которые возникли в CoreGraphics (Те, которые просто регистрируют сообщение «Добавить точку останова, используя ваш отладчик !!!»).

Ответы [ 3 ]

9 голосов
/ 06 декабря 2010

Вы можете перехватить NSLog() сообщения (но не ASL в целом), используя _NSSetLogCStringFunction(). Здесь задокументировано здесь для WebObjects 4 для Windows, но оно существует и в текущих версиях Mac OS и iOS. Однако это частная функция, которая может исчезнуть в любое время, поэтому вам не следует полагаться на нее в выпущенном коде.

Если вы хотите безопасно сделать это для не отладочных сборок, я предлагаю дублировать этот запрос на улучшение на Радар .

9 голосов
/ 02 декабря 2010

Вы можете использовать функцию Foundation NSSetUncaughtExceptionHandler, чтобы установить функцию обратного вызова, которая будет обрабатывать все неперехваченные исключения:

void CustomLogger(NSString *format, ...) {
   //do other awesome logging stuff here...
}

void uncaughtExceptionHandler(NSException *exception) {
   //do something useful, like this:
   CustomLogger(@"%@", [exception reason]);
}

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

Для NSLog вы можете использовать макрос дляпереопределить его:)

#define NSLog(...) CustomLogger(__VA_ARGS__);
6 голосов
/ 05 декабря 2011

Вы можете перенаправить стандартный вывод ошибок в файл.Вот метод, который перенаправляет вывод консоли в файл в папке «Документы» приложения.Это может быть полезно, когда вы хотите протестировать ваше приложение вне вашей студии разработки, отключенное от вашего mac.

-(void) redirectNSLogToDocuments {
 NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [allPaths objectAtIndex:0];
 NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:@"yourFile.txt"];
 freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}

После выполнения этого метода весь вывод, сгенерированный NSLog, будет перенаправлен в указанный файл.Чтобы получить сохраненный файл, откройте «Органайзер», просмотрите файлы приложения и сохраните данные приложения где-нибудь в вашей файловой системе, а затем просто перейдите в папку «Документы».

...