2010-07-09 7 views
18

Attualmente sto esaminando varie possibilità di registrazione per progetti .net e non riesco a decidere tra le funzioni System.Diagnostics.Debug/Trace e le librerie di terze parti come log4net, MS Enterprise Library, NLog, ecc
al momento ho scoperto questo:System.Diagnostics.Debug namespace vs Altre soluzioni di registrazione (log4net, MS Enterprise Library, ecc.)

  • System.Diagnostics è piuttosto difficile da configurare e da usare poiché è necessario configurare in modo esplicito tutti ascoltatori, filtri, sorgenti, ecc. Sembra che manchi anche l'inserimento di massa nel DB (pensate di scrivere 100.000 voci di log ciascuna con il proprio Insert, orribile, vero?). Ma da alcune persone è considerato "bello" non utilizzare librerie aggiuntive per una cosa "rudimentale" come la registrazione (ovviamente, a un certo punto, ha senso ridurre la quantità di librerie di terze parti su cui si basa il progetto, ma non questa volta, suppongo)
  • le terze parti sono molto più potenti, spesso più veloci, molto più facili da usare, ma la configurazione a volte può essere anche dolorosa e spesso queste librerie sono meno affidabili (come il misterioso arresto improvviso della registrazione da EntLib, ecc.)
  • che dire di Common.Logging? vale la pena provare (poiché, come ho sentito, offre l'inserimento di vari framework di registrazione e si comporta come un'interfaccia tra l'app e la lib desiderata)?


sarei davvero grato se qualcuno mi potrebbe indicare la direzione giusta o corretta (o aggiungere qualcosa) al mio confronto di cui sopra! Forse se mi incoraggerei a usare terze parti, potresti consigliarne una particolare (tenendo conto che le nostre applicazioni molto probabilmente non avranno bisogno di cose di fantasia come UDP, file rotanti, ecc. - solo file, email, DB e registro eventi)?
Grazie in anticipo!

+0

Is non System.Diagnostics.Debug/Trace rilevante solo (o anche compilato nel codice) ogni volta che le costanti DEBUG/TRACE sono incorporati nel codice (vale a dire un debug, non un rilascio, costruire)? Quindi il vantaggio derivante dall'utilizzo di S.D.Debug è piuttosto ridotto rispetto a un framework di registrazione completo. – Andreas

+0

Come noto, S.D.Debug funziona solo quando si crea l'applicazione in modalità di debug, ma se la si genera in modalità di rilascio, si ottengono solo i messaggi registrati con S.D.Trace (che sembra quasi lo stesso di Debug). – timurso

risposta

23

È possibile trovare molte informazioni su log4net e NLog sia qui su StackOverflow che su googling in generale.

È inoltre possibile trovare molte informazioni su System.Diagnostics. Una cosa da notare su System.Diagnostics, penso che su StackOverflow troverai molti riferimenti sull'uso di Debug.Write/WriteLine e Trace.Write/WriteLine. Un modo forse "migliore" è usare TraceSources. TraceSources sono analoghi ai logger in log4net e NLog. TraceSources ti consente di avere un grado più elevato di granularità per i tuoi messaggi di registrazione, rendendo più semplice accendere alcuni logging e altri off (per classe o categoria, oltre per livello). TraceSources presenta uno svantaggio, rispetto a log4net e NLog, in quanto ogni TraceSource creata nel codice deve essere configurata in modo esplicito in app.config (se si desidera che registri effettivamente).

log4net e NLog hanno un concetto gerarchico in cui se il logger esatto richiesto non è configurato in modo esplicito, il suo "ancestry" viene controllato per vedere se sono stati configurati eventuali "antenati" e, in tal caso, il logger richiesto "eredita" quelle impostazioni. Gli antenati sono semplicemente le parti del nome del logger delimitato da ".". Quindi, se si richiede un logger chiamato "ABC.DEF.GHI", gli antenati sarebbero "ABC.DEF" e "ABC". È anche possibile (richiesto?) per avere una configurazione del logger "root" nell'app.config che tutte le richieste di logger ricadranno su se non sono configurate esplicitamente e non sono stati configurati antenati. Pertanto, è possibile configurare solo un logger "root" per accedere a un determinato livello e tutti i logger del proprio codice si collegheranno a tale livello. In alternativa, è possibile configurare il logger "root" su "off" e quindi attivare uno o più logger esplicitamente (o configurando un antenato). In questo modo, nessun registratore registrerà EXCEPT per quelli che sono configurati.

Se si guarda here, si troverà un involucro interessante attorno a System.Diagnostics TraceSources che fornisce una capacità di ereditarietà molto simile a log4net e NLog.

Facciamo un esempio:

Un modello di utilizzo comune per logger in log4net e NLog è quello di ottenere un logger come questo:

//log4net 
static ILog logger = LogManager.GetLogger(
        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

//NLog 
static Logger logger = LogManager.GetCurrentClassLogger(); 

In entrambi i casi il nome del registratore sarà il nome di tipo completo.

Nel file app.config, è possibile, se lo si desidera, configurare solo il logger "root" ed entrambi i logger erediteranno le impostazioni del logger root (livello, appenders/target, ecc.). In alternativa è possibile configurare un logger per alcuni spazi dei nomi. Qualsiasi logger il cui tipo è definito in quel namespace erediterà quelle impostazioni del logger.

Basta con log4net e NLog, probabilmente già sai come funzionano.

Il collegamento sopra illustra un wrapper basato su TraceSource che consente una configurazione simile. Quindi, se si voleva, si potrebbe fare qualcosa di simile nelle classi:

static TraceSource ts = new TraceSource(
       System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

Con l'involucro linkato sopra, si potrebbe configurare un TraceSource a un livello superiore (classe/spazio dei nomi gerarchico-saggio, non a livello) e ereditare quelle impostazioni nei logger di livello inferiore.

Quindi, se il nome del tipo completo è simile a questo: ABC.DEF.GHI, è possibile configurare un TraceSource per ABC o ABC.DEF (livello spazio dei nomi) e la classe "GHI" erediterà le impostazioni. Questo potrebbe davvero ridurre la quantità di configurazione che devi fare.

Si noti che non si è limitato (con nessuna di queste piattaforme di registrazione) all'utilizzo del nome del tipo o del tipo della classe per ottenere il registratore. È possibile definire il proprio schema di denominazione del logger, possibilmente basato su aree funzionali ("Comunicazione", "Comunicazione.Invia", "Comunicazione.Ricezione", ecc.). Anche in questo caso, è possibile richiedere un logger/TraceSource al massimo grado di granularità (o meno) e quindi configurare a qualunque livello di granularità abbia senso.

Quindi, si potrebbe richiedere logger nel codice come questo:

ILog logger = LogManager.GetLogger("Communication.Receive"); 
ILog logger = LogManager.GetLogger("Communication.Send"); 

Logger logger = LogManager.GetLogger("Communication.Receive"); 
Logger logger = LogManager.GetLogger("Communication.Send"); 

TraceSource ts = new TraceSource("Communication.Receive"); 
TraceSource ts = new TraceSource("Communication.Send"); 

Se si configura solo "comunicazione" nel file app.config, quindi tutti i logger erediteranno le impostazioni (dal momento che sono discendenti di "Comunicazione"). Se si configura solo "Commuincation.Receive", verranno registrati solo i logger "Communication.Receive". I logger "Communication.Send" saranno disabilitati. Se si configura sia "Comunicazione" che "Comunicazione", i registratori "Comunicazione.Ricezione" registreranno le impostazioni "Comunicazione.Ricezione" mentre i logger "CommunicationSender" effettueranno il log nelle impostazioni "Comunicazione". In log4net e NLog possono esserci più ereditarietà di questo, ma non ne so abbastanza per approfondire.

Una cosa che ti manca quando usi System.La diagnostica è la flessibilità per formattare il formato di output di registrazione molto facilmente. Esiste una libreria di terze parti che fornisce una formattazione configurabile molto bella per la registrazione basata su TraceSource. Lo puoi trovare here.

Ho usato Common.Logging alcuni. Principalmente nella prototipazione, ma potrei usarlo nel nostro prossimo progetto. Funziona abbastanza bene ed è relativamente facile scrivere la propria astrazione di logging per collegarlo (come se si volesse scrivere un'astrazione di TraceSource simile a quella che ho linkato sopra). Due cose importanti che mancano da Common.Logging in questo momento (anche se il loro sito dice che sono programmate per la "prossima" versione) sono i contesti di log (come log4net e NDog/MDC/GDC e System.Diagnostics.CorrelationManger.LogicalOperationStack) e compatibilità Silverlight. Puoi ancora interagire con gli oggetti di contesto log4net o NLog nel tuo codice mentre usi Common.Logging, ma questo tipo di sconfigge lo scopo di esso, non è vero?

Non so se ho aiutato o no!

Ecco alcuni punti principali che vorrei fare circa log4net, NLog, e TraceSource:

log4net - molto popolare, probabilmente ha bisogno di alcuni aggiornamenti - almeno in costruzione su .NET 4.0, ultima release pochi anni fa, molto flessibile.

NLog - molto simile a log4net per molti aspetti, nuova versione ora (beta di NLog 2,0 appena uscito)

TraceSource - nessuna terza dipendenza parti, senza qualche sforzo da parte vostra (o qualcun) non potente come log4net o NLog (carenze chiave - gerarchia del logger, formattazione dell'output - entrambi facilmente indirizzabili tramite un link sopra), Microsoft utilizza molti dei suoi componenti con System.Diagnostics in modo da poter ottenere l'output di registrazione di Microsoft e l'output di registrazione intercalato. (In genere, è abbastanza facile acquisire System.Diagnostics in altri sistemi di registrazione, quindi potrebbe non essere un problema enorme).

Anche se non ho usato molto né log4net né NLog, tra i due mi piacerei indirizzare verso NLog, principalmente a causa della nuova versione appena uscita (beta). Penso che TraceSource sia anche una scelta ragionevole, se più rudimentale, soprattutto se si implementa la gerarchia del logger e si utilizza la libreria Ukadc.Diagnostics collegata in precedenza.

Oppure utilizzare Common.Logging ed è possibile evitare o ritardare la decisione per la piattaforma di registrazione sottostante finché non si è pronti. Un aspetto molto utile di Common.Logging, a mio avviso, è che è possibile "testare" le piattaforme di registrazione mentre si sta sviluppando il prodotto senza dover modificare alcun codice dell'applicazione. Non devi aspettare fino a quando non hai deciso su una piattaforma di registrazione specifica per aggiungere la registrazione al tuo codice. Aggiungilo ora tramite l'API Common.Logging. Quando ti avvicini alla consegna, dovresti restringere la scelta della piattaforma di registrazione. Consegnare con quella piattaforma (se si ridistribuisce la piattaforma di registrazione) e il gioco è fatto. Puoi ancora cambiare in seguito, se lo desideri.

-1

Da un punto di vista dello sviluppatore riguarda la registrazione, simile a orm, non dovrebbe essere scritta a mano. Ci sono molte buone solide librerie di terze parti. Certo, a volte c'è un po 'di lavoro di configurazione da fare, ma paragonalo al fatto che rotolando a mano sei proprio le soluzioni è una semplice goccia nell'acqua.

La mia preferenza personale è log4net ma dipende dalle vostre esigenze. Il mio miglior consiglio è dare un'occhiata alla documentazione di soluzioni come log4net o EntLib Logging Application Block e prendere una decisione su ciò che è meglio per voi.

-1

La registrazione e la tracciatura sono preoccupazioni diverse. La registrazione riguarda il feedback operativo. La traccia (inclusa quella fornita dai metodi di debug) riguarda lo sviluppo e il test. Il codice di traccia non deve essere compilato negli assembly di rilascio. Le classi Trace e Debug ottengono questo risultato con le annotazioni del compilatore (ConditionalAttribute). Tale codice dovrebbe essere ottimizzato per raccogliere molti dati, non per le prestazioni. D'altra parte, la registrazione operativa deve essere ottimizzata per le prestazioni e per una più ampia varietà di meccanismi di archiviazione, come richiesto dal team sysadmin/operations.

Quindi consiglio di utilizzare sia Trace/Debug per lo sviluppo sia pacchetti di registrazione più robusti per le operazioni.

+1

Dubito davvero che alcune java-porte di terze parti siano più robuste di quella parte del BCL – vittore

0

So che questo è vecchio, ma System.Diagnostics.Trace è abbastanza facile da configurare se si mantiene semplice.Ho usato il blocco di configurazione del writer di testo semplice per anni, copiato direttamente dai documenti MSDN.

Non si parla di questo, molto spesso, ma nel tuo codice, è possibile utilizzare il built-in Trace.TraceInformation, Trace.TraceWarning, e Trace.TraceError di separare facilmente 3 livelli di output di analisi e quindi nella configurazione file scegli quale livello di output (vedi configurazione di seguito). Se scegli Informazioni nel "EventTypeFilter" della configurazione, ottieni tutti e 3 i tuoi risultati. Se si seleziona Errore, verranno visualizzati solo i messaggi TraceError nell'output. Il più delle volte, lascio il mio su Errore, quindi se qualcosa accade nella mia applicazione, avrò già quell'output nel mio file di traccia. All'interno dei miei blocchi Catch, aggiungo il codice TraceError per generare informazioni utili. TraceInformation è utile per l'output di elementi come il timing o gli spot nel codice che hai passato e lo scarico di valori variabili lungo il percorso. TraceWarning fa bene a cose che sono maneggiabili, ma non desiderabili - come forse un servizio web impiega molto tempo per essere completato, oppure il numero di record di dati restituiti supera una soglia che potrebbe causare problemi futuri.

C'è un piccolo svantaggio, in quello all queste righe di codice di traccia ancora eseguite indipendentemente dal livello di compilazione. Se sono impostati per non emettere, ciò dovrebbe ridurre un po 'l'overhead. Ma se stai scrivendo un codice ad alte prestazioni, potresti voler avvolgere quelle linee in marcatori di compilazione condizionali.

<system.diagnostics> 
    <sharedListeners> 
    <add name="MyTraceListener" traceOutputOptions="DateTime" type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="MyApplicationName_Trace.log"> 
    <!-- 
     Off - Does not allow any events through. 
     Error - Allows Error events through. 
     Warning - Allows Error, and Warning events through. 
     Information - Allows Error, Warning, and Information events through. 
    --> 
    <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error" /> 
    </add> 
    </sharedListeners> 
    <trace autoflush="true" indentsize="4"> 
    <listeners> 
     <add name="MyTraceListener" /> 
    </listeners> 
    </trace> 
</system.diagnostics> 
Problemi correlati