Сразу же сбрасывая записи журнала, используя фреймворк Cocoa Lumberjack, способ NSASH сбрасывается на консоль

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

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

Например, если я иду через отладчик, и я попал в оператор NSLog(), он немедленно сбрасывает оператор журнала на консоль. Это поведение, которое я хотел бы получить от вызова DDLogVerbose() в Lumberjack.

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

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

Ответы

Ответ 1

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

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

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

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

Обратите внимание, что заголовок препятствует изменению самого файла DDLog.h. Итак, следуя инструкциям на странице wiki-страницы 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 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

Ответ 2

Вы можете дождаться окончания очереди регистрации:

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

Ответ 3

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

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