2012-01-01 5 views
14

Molti sviluppatori iOS hanno rilevato che lo Cocoa Lumberjack Logging framework non soddisfa le semplici istruzioni NSLog. Ricorda Log4J nel mondo di Java.Estrarre immediatamente le dichiarazioni del registro utilizzando il framework di registrazione di Cocoa Lumberjack, il modo in cui NSLog si svuota sulla console

In ogni caso, ho scritto il mio formattatore personalizzato per Lumberjack, ma quello che non vedo è una documentazione su come svuotare immediatamente le dichiarazioni del registro.

Ad esempio, se passo il debugger e prendo un'istruzione NSLog(), svuota immediatamente l'istruzione del registro nella console. Questo è il comportamento che mi piacerebbe ottenere da una chiamata DDLogVerbose() in Lumberjack.

In questo momento, torno indietro e cambio queste affermazioni alle dichiarazioni NSLog() se voglio che sputino immediatamente mentre sto eseguendo il debug di un segmento di codice. Visto che Lumberjack è così robusto, devo pensare che c'è un modo per configurarlo per svuotare senza ritardi.

Qualcuno sa come farlo?

risposta

27

Ho trovato la risposta nel file DDLog.h. Lumberjack ha il concetto di registrazione asincrona e sincrona. Alla prima lettura, non mi ha colpito per quello che questo era per.

In sostanza, se si desidera che l'istruzione del registro venga emessa in sequenza, è necessario renderla sincronizzata (sebbene, come detto da Mike, ciò rallenterà le prestazioni). Quindi, questo dovrebbe essere fatto solo in una situazione di debug. Idealmente, inserirò un'altra intestazione e/o qualche altra macro di pre-processore per assicurarmi di non lasciare lo switch acceso come sincrono.

Ecco cosa dovete fare:

  1. Aprire DDLog.h
  2. Vai alla linea con #define LOG_ASYNC_ENABLED YES. È possibile modificare questo in NO in un punto per la registrazione sincrona su tutta la scheda, oppure è possibile modificare i singoli livelli, nelle righe che seguono.

Si noti che l'intestazione scoraggia la modifica del file DDLog.h stesso. Quindi, seguendo le istruzioni sulla pagina wiki Lumberjack link, spiegano come utilizzare un diverso file di intestazione per articolare queste personalizzazioni di sostituzione.

Utilizzando questo, ecco quello che ho scritto e testato con successo, come file di intestazione "MyAppLumberjack.h" che ho importare in intestazione precompilata di mia app:

#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 
0

è possibile provare ad aggiungere fflush(stderr); nella parte inferiore di if (logMsg) nella funzione - (void)logMessage:(DDLogMessage *)logMessage in DDTTYLogger.m.

lo svantaggio dello svuotamento su ogni messaggio di registro è che si può verificare un calo delle prestazioni, tuttavia se lo si utilizza per il debugging probabilmente non ha importanza.

+0

Grazie Mike. Questa era una supposizione ragionevole. Purtroppo non ha funzionato. Ho provato anche a svuotare lo stdout, ma non ha funzionato (è logico - l'intero metodo sembra aumentare l'output su stderr). – idStar

1

è possibile attendere la coda di registrazione per terminare con un timeout:

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