Quanto è veloce un metodo di registrazione log4net (debug, informazioni, ecc.)?
-
05-07-2019 - |
Domanda
Sono un grande fan di log4net , ma recentemente alcuni (nel mio dipartimento) hanno messo in discussione la sua inclusione nei nostri progetti a causa dell'apparente pesantezza di ciascun metodo di registrazione. Direi che esistono tecniche migliori di altre, ma questa è un'altra domanda.
Sono curioso di sapere qual è l'impatto tipico di una chiamata di tipo DebugFormat log4net sulle vostre applicazioni. Tralascerò variabili come il numero di istruzioni di registro per righe di codice, ecc., Perché sto solo cercando qualcosa che hai visto nel mondo reale.
E sono a conoscenza della semplice tecnica di aggiungere una clausola di guardia a lunghe dichiarazioni di valutazione, ad esempio:
if (log.IsDebug)
{
log.DebugFormat(...);
}
Quindi, per ora, escludiamolo dalle considerazioni.
Soluzione
Non ho familiarità con log4net o log.DebugFormat (...).
Ma il costo della registrazione è veramente in due aree.
Il primo è la chiamata di registrazione e il secondo è l'effettiva persistenza delle informazioni di registro.
Le protezioni aiutano a ridurre al minimo la chiamata di registrazione quando la registrazione non è effettivamente necessaria. Tende ad essere molto veloce, dal momento che è poco più di una chiamata di metodo e un confronto di due scalari.
Tuttavia, quando non si utilizzano le protezioni, il costo potrebbe diventare il prezzo della creazione degli argomenti di registrazione effettivi.
Ad esempio, in log4j, questo era un linguaggio comune:
log.debug("Runtime error. Order #" + order.getOrderNo() + " is not posted.");
Qui, il costo è la valutazione effettiva dell'espressione di stringa che crea il messaggio. Questo perché, indipendentemente dal livello di registrazione, vengono create quell'espressione e la stringa risultante. Immagina se invece avessi qualcosa del tipo:
log.debug("Something wrong with this list: " + longListOfData);
Ciò potrebbe creare una variabile stringa grande e costosa che, se il livello di registro non fosse impostato per DEBUG, verrebbe semplicemente sprecato.
Le guardie:
if (log.isDebug()) {
log.debug(...);
}
Elimina questo problema, poiché la chiamata isDebug è economica, soprattutto se confrontata con l'effettiva creazione dell'argomento.
Nel mio codice ho scritto un wrapper per la registrazione e posso creare registri come questo:
log.debug("Runtime error. Order # {0} is not posted.", order.getOrderNo());
Questo è un bel compromesso. Questo si basa su varargs Java e il mio codice controlla il livello di registrazione e quindi formatta il messaggio in modo appropriato. È veloce quasi quanto le guardie, ma molto più pulito da scrivere.
Ora, log.DebugFormat potrebbe fare una cosa simile, che non conosco.
Oltre a questo, ovviamente, c'è il costo effettivo della registrazione (sullo schermo, su un file, su un socket, ecc.). Ma questo è solo un costo che devi accettare. La mia migliore pratica per questo, quando è pratico, è di instradare i messaggi di registro effettivi a una coda, che viene quindi raccolta e trasmessa al canale appropriato utilizzando un thread separato. Questo, almeno, aiuta a mantenere la registrazione fuori linea rispetto all'elaborazione principale, ma ha costi e complessità propri.
Altri suggerimenti
So che questo è un vecchio thread, ma che ne dici di usare un approccio che eviti di riempire il codice con istruzioni if ??basate sul livello di registro, come questo: http://www.beefycode.com/post/Extension- metodi-per-Deferred-Message-formattazione-in-Log4Net.aspx
Usando l'espressione lambda per creare il messaggio, puoi evitare di valutarlo del tutto.
In breve: usa quelle clausole di guardia.
Dare alla risposta di Will Hartung una prospettiva .NET :)
Il codice DebugFormat è:
if (IsDebugEnabled)
{
Logger.Log(ThisDeclaringType, m_levelDebug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
Fondamentalmente è lo stesso, quindi credo che quando usi DebugFormat non devi usare la clausola di guardia (potresti avere ancora un piccolo overhead ma penso che sia abbastanza piccolo per essere ignorato)
avrebbe lasciato un commento ma non ho abbastanza reputazione: /