Немедленная очистка операторов журналов с использованием каркаса ведения журнала Cocoa Lumberjack, как NSLog сбрасывает на консоль - PullRequest
14 голосов
/ 01 января 2012

Многие разработчики iOS обнаружили, что Cocoa Lumberjack Logging Framework удовлетворяет потребность, которой нет в простых NSLog заявлениях.Это напоминает Log4J в мире Java.

В любом случае, я написал свой собственный форматер для Lumberjack, но я не вижу никакой документации о том, как немедленно очистить операторы журнала.

Например, если я иду по отладчику и нажимаю на оператор NSLog(), он немедленно сбрасывает оператор log на консоль.Именно такое поведение я хотел бы получить от вызова DDLogVerbose() в «Дровосеке».

Прямо сейчас я возвращаюсь и заменяю эти операторы на операторы NSLog(), если я хочу, чтобы они выплевывали сразу же, как я.м отладка сегмента кода.Поскольку Lumberjack настолько крепок, я подумал, что есть способ настроить его так, чтобы он мгновенно сбрасывался.

Кто-нибудь знает, как это сделать?

Ответы [ 3 ]

28 голосов
/ 01 января 2012

Я нашел ответ в файле DDLog.h. Дровосек имеет концепцию асинхронной и синхронной регистрации. При первоначальном прочтении меня не поразило, для чего это.

По сути, если вы хотите, чтобы оператор log выводился последовательно, необходимо синхронизировать его (хотя, как упоминал Майк, это снизит производительность). Таким образом, это должно быть сделано только в ситуации отладки. В идеале я собираю другой заголовок и / или какой-нибудь другой макрос препроцессора, чтобы не оставлять переключатель включенным как синхронный.

Вот что вы делаете:

  1. Открыть DDLog.h
  2. Перейти к строке с #define LOG_ASYNC_ENABLED YES. Вы можете изменить это значение на NO в одном месте для синхронной регистрации по всем направлениям или изменить отдельные уровни в следующих строках.

Обратите внимание, что заголовок не рекомендует изменять сам файл DDLog.h. Итак, следуя инструкциям на вики-странице Lumberjack ссылка , они объясняют, как использовать другой заголовочный файл для определения этих настроек переопределения.

Используя это, вот что я успешно написал и протестировал в виде заголовочного файла «MyAppLumberjack.h», который я импортировал в предварительно скомпилированный заголовок моего приложения:

#import "DDLog.h"
#import "DDASLLogger.h"
#import "DDTTYLogger.h"

// ========================= Overrides ========================================
// --> per https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels
// ----------------------------------------------------------------------------

// Are we in an optimized (i.e. Release) build?
#ifdef __OPTIMIZE__
    // YES: Nothing to do from the default. (You could simplify this by using #ifndef above instead)
#else
    // NO: We're in a Debug build. As such, let's configure logging to flush right away.
    // Undefine the asynchronous defaults:
    #undef LOG_ASYNC_VERBOSE
    #undef LOG_ASYNC_INFO
    #undef LOG_ASYNC_WARN

    // Define the logs levels to be synchronous:
    #define LOG_ASYNC_VERBOSE   (NO && LOG_ASYNC_ENABLED)   // Debug logging will be synchronous
    #define LOG_ASYNC_INFO      (NO && LOG_ASYNC_ENABLED)   // Info logging will be synchronous
    #define LOG_ASYNC_WARN      (NO && LOG_ASYNC_ENABLED)   // Warn logging will be synchronous
#endif
1 голос
/ 29 января 2016

Вы можете подождать, пока очередь регистрации завершится с таймаутом:

- (void)waitForLog {
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  dispatch_async(DDLog.loggingQueue, ^{
    dispatch_semaphore_signal(sema);
  });
  dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)));
}
0 голосов
/ 01 января 2012

вы можете попробовать добавить fflush(stderr); в нижней части if (logMsg) в функции - (void)logMessage:(DDLogMessage *)logMessage в DDTTYLogger.m.

Недостатком очистки всех сообщений журнала является то, что вы можете столкнуться с попаданиемк производительности, хотя, если вы используете его для отладки, это, вероятно, не имеет значения.

...