Best practice per la registrazione [chiuso]


323

Mi piacerebbe avere storie su come le persone gestiscono la traccia e il log in applicazioni reali. Ecco alcune domande che potrebbero aiutare a spiegare la tua risposta.

Frameworks

Quali framework usi?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Registrazione del blocco applicazione
  • Altro?

Se usi la traccia, usi Trace.Correlation.StartLogicalOperation?

Scrivi questo codice manualmente o usi qualche forma di programmazione orientata all'aspetto per farlo? Vuoi condividere uno snippet di codice?

Offrite qualche forma di granularità rispetto alle fonti di traccia? Ad esempio, WPF TraceSources consente di configurarli a vari livelli:

  • System.Windows - impostazioni per tutto WPF
  • System.Windows.Animation: esegue l' override specifico per l'animazione.

Gli ascoltatori

Quali output di log usi?

  • File di testo
  • File XML
  • Registro eventi
  • Altro?

Se si utilizzano file, si utilizzano i log di scorrimento o solo un singolo file? Come si rendono disponibili i registri che le persone possono consumare?

Sta guardando

Quali strumenti usi per visualizzare i log?

  • Bloc notes
  • Coda
  • Visualizzatore eventi
  • Systems Center Operations Manager / Microsoft Operations Manger
  • Visualizzatore della traccia del servizio WCF
  • Altro?

Se stai costruendo una soluzione ASP.NET, usi anche ASP.NET Health Monitoring? Includete l'output di traccia negli eventi di monitoraggio dello stato? Che dire di Trace.axd?

Che dire dei contatori delle prestazioni personalizzati?


3
Sarebbe utile se le persone che chiudessero domande come questa con 300 voti positivi potessero suggerire un formato wiki o postare su programmers.stackexchange, oppure Quora se questo tipo di domanda non è il benvenuto. Ovviamente la domanda è in realtà molto costruttiva, non si adatta ai criteri che StackOverflow vuole. programmers.stackexchange.com/questions/57064/… ha 24 voti positivi. Forse StackOverflow manca di qualcosa?
Niall Connaughton,

Se questa domanda viola il formato Domande e risposte, c'è QUALCOSA DI SBAGLIATO nel formato Domande e risposte e non con questa domanda. A volte la decisione se una domanda debba essere chiusa dovrebbe essere una funzione delle risposte fornite, alcune domande aperte invitano al dibattito, ma altre invitano gli utenti a fornire contenuti preziosi, come questo!
Matthias Wolf,

1
Questa domanda - in particolare la risposta migliore - probabilmente costituirebbe un'ottima base per un post sul blog se qualcuno volesse usarlo come tale ... Come domanda obiettiva, non si adatta davvero - è strutturata esplicitamente come un sondaggio di paglia - ma ci sono alcune buone informazioni qui sotto, quindi il lucchetto.
Shog9

Risposte:


232

Aggiornamento: per le estensioni di System.Diagnostics, fornendo alcuni dei listener mancanti che potresti desiderare, vedi Essential.Diagnostics su CodePlex ( http://essentialdiagnostics.codeplex.com/ )


Frameworks

D: Quali framework utilizzi?

A: System.Diagnostics.TraceSource, integrato in .NET 2.0.

Fornisce funzionalità di registrazione potenti, flessibili e ad alte prestazioni per le applicazioni, tuttavia molti sviluppatori non sono a conoscenza delle sue capacità e non le sfruttano appieno.

Ci sono alcune aree in cui è utile funzionalità aggiuntiva, o talvolta esiste la funzionalità ma non è ben documentata, tuttavia ciò non significa che l'intero framework di registrazione (progettato per essere estensibile) debba essere gettato via e sostituito completamente come alcune alternative popolari (NLog, log4net, Common.Logging e persino EntLib Logging).

Invece di cambiare il modo in cui aggiungi le istruzioni di registrazione alla tua applicazione e reinventando la ruota, hai appena esteso il framework System.Diagnostics nei pochi punti in cui ne hai bisogno.

Mi sembra che gli altri framework, anche EntLib, soffrano semplicemente della sindrome di Non inventato qui, e penso che abbiano perso tempo a reinventare le basi che funzionano già perfettamente in System.Diagnostics (come il modo in cui scrivi le dichiarazioni del registro), piuttosto che colmare le poche lacune esistenti. In breve, non usarli - non sono necessari.

Funzionalità che potresti non conoscere:

  • L'uso dei sovraccarichi di TraceEvent che accettano una stringa di formato e args può aiutare le prestazioni poiché i parametri vengono mantenuti come riferimenti separati fino a quando Filter.ShouldTrace () non è riuscito. Ciò significa che nessuna chiamata costosa a ToString () sui valori dei parametri fino a quando il sistema non avrà confermato che il messaggio verrà effettivamente registrato.
  • Trace.CorrelationManager consente di correlare le istruzioni di registro relative alla stessa operazione logica (vedere di seguito).
  • VisualBasic.Logging.FileLogTraceListener è utile per scrivere su file di registro e supporta la rotazione dei file. Sebbene nello spazio dei nomi di VisualBasic, può essere facilmente utilizzato in un progetto C # (o altro linguaggio) semplicemente includendo la DLL.
  • Quando si utilizza EventLogTraceListener se si chiama TraceEvent con più argomenti e con una stringa di formato vuota o nulla, gli arg vengono passati direttamente a EventLog.WriteEntry () se si utilizzano risorse di messaggi localizzate.
  • Lo strumento Service Trace Viewer (da WCF) è utile per visualizzare grafici di file di registro correlati alle attività (anche se non si utilizza WCF). Questo può davvero aiutare a eseguire il debug di problemi complessi in cui sono coinvolti più thread / attività.
  • Evita le spese generali cancellando tutti i listener (o rimuovendo Predefinito); altrimenti Default passerà tutto al sistema di traccia (e incorrerà in tutte quelle spese generali di ToString ()).

Aree che potresti voler estendere (se necessario):

  • Listener di tracce del database
  • Listener di tracce console colorato
  • Listener di tracce MSMQ / Email / WMI (se necessario)
  • Implementare un FileSystemWatcher per chiamare Trace.Refresh per modifiche dinamiche alla configurazione

Altre raccomandazioni:

Usa gli ID di eventi strutturati e mantieni un elenco di riferimenti (ad es. Documentali in un enum).

Avere ID evento univoci per ogni (significativo) evento nel tuo sistema è molto utile per correlare e trovare problemi specifici. È facile risalire al codice specifico che registra / utilizza gli ID evento e può semplificare fornire indicazioni per errori comuni, ad esempio errore 5178 significa che la stringa di connessione al database è errata, ecc.

Gli ID evento dovrebbero seguire una sorta di struttura (simile alla Teoria dei codici di risposta utilizzati in e-mail e HTTP), che consente di trattarli per categoria senza conoscere codici specifici.

ad es. la prima cifra può indicare in dettaglio la classe generale: 1xxx può essere utilizzato per le operazioni di "Avvio", 2xxx per il comportamento normale, 3xxx per il tracciamento delle attività, 4xxx per gli avvisi, 5xxx per gli errori, 8xxx per le operazioni di "Stop", 9xxx per errori irreversibili, eccetera.

La seconda cifra può specificare l'area, ad es. 21xx per le informazioni sul database (41xx per gli avvisi del database, 51xx per gli errori del database), 22xx per la modalità di calcolo (42xx per gli avvisi di calcolo, ecc.), 23xx per un altro modulo, ecc.

Gli ID evento strutturati e assegnati ti consentono anche di utilizzarli nei filtri.

D: Se si utilizza la traccia, si utilizza Trace.Correlation.StartLogicalOperation?

A: Trace.CorrelationManager è molto utile per correlare le istruzioni di registro in qualsiasi tipo di ambiente multi-thread (che è praticamente qualcosa al giorno d'oggi).

È necessario almeno impostare ActivityId una volta per ogni operazione logica per correlare.

Start / Stop e LogicalOperationStack possono quindi essere utilizzati per un semplice contesto basato su stack. Per contesti più complessi (ad es. Operazioni asincrone), l'utilizzo di TraceTransfer nel nuovo ActivityId (prima di modificarlo), consente la correlazione.

Lo strumento Service Trace Viewer può essere utile per visualizzare i grafici delle attività (anche se non si utilizza WCF).

D: Scrivi questo codice manualmente o usi qualche forma di programmazione orientata all'aspetto per farlo? Vuoi condividere uno snippet di codice?

A: Potresti voler creare una classe di ambito, ad esempio LogicalOperationScope, che (a) imposta il contesto quando viene creato e (b) reimposta il contesto quando viene eliminato.

Ciò consente di scrivere codice come il seguente per concludere automaticamente le operazioni:

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

Al momento della creazione, l'ambito potrebbe prima impostare ActivityId, se necessario, chiamare StartLogicalOperation e quindi registrare un messaggio TraceEventType.Start. Su Dispose potrebbe registrare un messaggio Stop, quindi chiamare StopLogicalOperation.

D: Fornite qualche forma di granularità rispetto alle fonti di traccia? Ad esempio, WPF TraceSources consente di configurarli a vari livelli.

A: Sì, più origini di traccia sono utili / importanti man mano che i sistemi diventano più grandi.

Mentre probabilmente si desidera registrare in modo coerente tutti i messaggi di avviso e sopra, o tutti i messaggi Informazioni e sopra, per qualsiasi sistema di dimensioni ragionevoli, il volume di Activity Tracing (Start, Stop, ecc.) E la registrazione dettagliata diventano semplicemente troppo.

Piuttosto che avere un solo interruttore per accenderlo o spegnerlo, è utile poter attivare queste informazioni per una sezione del sistema alla volta.

In questo modo, è possibile individuare problemi significativi dalla registrazione di solito (tutti gli avvisi, errori, ecc.), Quindi "ingrandire" le sezioni desiderate e impostarle su Traccia attività o anche su livelli di debug.

Il numero di origini di traccia necessarie dipende dall'applicazione, ad esempio è possibile che si desideri una fonte di traccia per assembly o per sezione principale dell'applicazione.

Se è necessario un controllo ancora più preciso, aggiungere singoli interruttori booleani per attivare / disattivare la traccia di volumi elevati specifici, ad esempio i dump di messaggi non elaborati. (O potrebbe essere utilizzata una sorgente di traccia separata, simile a WCF / WPF).

È inoltre possibile prendere in considerazione origini di traccia separate per la traccia attività e la registrazione generale (altro), poiché può rendere un po 'più semplice configurare i filtri esattamente come li si desidera.

Tieni presente che i messaggi possono comunque essere correlati tramite ActivityId anche se vengono utilizzate origini diverse, quindi utilizza tutti quelli di cui hai bisogno.


Gli ascoltatori

D: Quali output di log usi?

Ciò può dipendere dal tipo di applicazione che stai scrivendo e dalle cose che vengono registrate. Di solito cose diverse vanno in luoghi diversi (cioè uscite multiple).

In genere classifico le uscite in tre gruppi:

(1) Eventi - Registro eventi di Windows (e file di traccia)

ad esempio, se si scrive un server / servizio, la migliore procedura su Windows è utilizzare il registro eventi di Windows (non si dispone di un'interfaccia utente per la segnalazione).

In questo caso, tutti gli eventi di informazioni irreversibili, di errore, di avviso e (a livello di servizio) devono andare nel registro eventi di Windows. Il livello Informazioni dovrebbe essere riservato per questo tipo di eventi di alto livello, quelli che si desidera inserire nel registro eventi, ad esempio "Servizio avviato", "Servizio interrotto", "Connesso a Xyz" e forse anche "Pianificazione avviata" , "Utente connesso", ecc.

In alcuni casi è possibile che si desideri rendere la scrittura nel registro eventi parte integrante dell'applicazione e non tramite il sistema di traccia (ovvero scrivere direttamente le voci del Registro eventi). Ciò significa che non può essere accidentalmente disattivato. (Notare che si desidera anche annotare lo stesso evento nel sistema di traccia in modo da poter essere correlati).

Al contrario, un'applicazione GUI di Windows in genere li segnala all'utente (sebbene possano anche accedere al registro eventi di Windows).

Gli eventi possono anche avere contatori delle prestazioni correlati (ad es. Numero di errori / sec) e può essere importante coordinare qualsiasi scrittura diretta nel registro eventi, contatori delle prestazioni, scrittura nel sistema di tracciamento e segnalazione all'utente in modo che si verifichino lo stesso tempo.

cioè se un utente vede un messaggio di errore in un determinato momento, dovresti essere in grado di trovare lo stesso messaggio di errore nel registro eventi di Windows e quindi lo stesso evento con lo stesso timestamp nel registro di traccia (insieme ad altri dettagli di traccia).

(2) Attività: file di registro dell'applicazione o tabella del database (e file di traccia)

Questa è l'attività regolare svolta da un sistema, ad esempio la pubblicazione di una pagina Web, la negoziazione di una borsa, l'ordine preso, il calcolo eseguito, ecc.

L'attività di tracciamento (avvio, arresto, ecc.) È utile qui (alla granularità corretta).

Inoltre, è molto comune utilizzare un registro applicazione specifico (a volte chiamato registro di controllo). Di solito si tratta di una tabella di database o di un file di registro dell'applicazione e contiene dati strutturati (ovvero un insieme di campi).

Le cose possono essere un po 'sfocate qui a seconda dell'applicazione. Un buon esempio potrebbe essere un server Web che scrive ogni richiesta in un registro Web; esempi simili potrebbero essere un sistema di messaggistica o un sistema di calcolo in cui ogni operazione è registrata insieme a dettagli specifici dell'applicazione.

Un esempio non altrettanto positivo sono le negoziazioni di borsa o un sistema di ordini di vendita. In questi sistemi probabilmente stai già registrando l'attività in quanto hanno un valore commerciale importante, tuttavia il principio di correlarli ad altre azioni è ancora importante.

Oltre ai registri delle applicazioni personalizzati, le attività hanno spesso contatori delle prestazioni correlati, ad esempio il numero di transazioni al secondo.

In generale, è necessario coordinare la registrazione delle attività tra sistemi diversi, ovvero scrivere nel registro dell'applicazione contemporaneamente all'aumento del contatore delle prestazioni e al registro nel sistema di traccia. Se si eseguono tutti contemporaneamente (o immediatamente uno dopo l'altro nel codice), i problemi di debug sono più facili (che se si verificano tutti in momenti / posizioni diverse nel codice).

(3) Traccia di debug: file di testo o XML o database.

Si tratta di informazioni a livello dettagliato e inferiore (ad esempio switch booleani personalizzati per attivare / disattivare i dump di dati non elaborati). Ciò fornisce il coraggio o i dettagli di ciò che un sistema sta facendo a livello di attività secondaria.

Questo è il livello che vuoi essere in grado di attivare / disattivare per le singole sezioni della tua applicazione (da qui le molteplici fonti). Non vuoi che queste cose ingombrino il registro eventi di Windows. A volte viene utilizzato un database, ma è più probabile che stiano eseguendo il rollup dei file di registro che vengono eliminati dopo un determinato periodo di tempo.

Una grande differenza tra queste informazioni e un file di registro dell'applicazione è che non è strutturato. Mentre un registro applicazioni può contenere campi per A, Da, Importo, ecc., Le tracce di debug dettagliate possono essere qualunque cosa inserisca un programmatore, ad esempio "verifica valori X = {valore}, Y = falso" o commenti / marcatori casuali come " Fatto, riprovando ".

Una pratica importante consiste nell'assicurarsi che le cose inserite nei file di registro dell'applicazione o nel registro eventi di Windows vengano registrate nel sistema di traccia con gli stessi dettagli (ad es. Timestamp). Ciò consente di correlare i diversi registri durante le indagini.

Se si prevede di utilizzare un particolare visualizzatore di registri perché si dispone di una correlazione complessa, ad esempio il Service Trace Viewer, è necessario utilizzare un formato appropriato, ad es. XML. Altrimenti, un semplice file di testo di solito è abbastanza buono: ai livelli più bassi le informazioni sono in gran parte non strutturate, quindi potresti trovare dump di array, stack dump, ecc. A condizione che tu possa essere correlato a registri più strutturati a livelli più alti, le cose dovrebbero stare bene.

D: Se si utilizzano file, si utilizzano i log di scorrimento o solo un singolo file? Come si rendono disponibili i registri che le persone possono consumare?

A: Per i file, in genere si desidera eseguire il rolling dei file di registro da un punto di vista della gestibilità (con System.Diagnostics è sufficiente utilizzare VisualBasic.Logging.FileLogTraceListener).

La disponibilità dipende nuovamente dal sistema. Se stai parlando solo di file, allora per un server / servizio, è possibile accedere ai file in rotazione quando necessario. (Il registro eventi di Windows o i registri applicazioni di database avrebbero i propri meccanismi di accesso).

Se non si ha un facile accesso al file system, la traccia di debug su un database potrebbe essere più semplice. [ovvero implementare un database TraceListener].

Una soluzione interessante che ho visto per un'applicazione GUI di Windows era che registrava informazioni di traccia molto dettagliate su un "registratore di volo" mentre era in esecuzione e poi quando lo chiudevi se non aveva problemi, semplicemente cancellava il file.

Se, tuttavia, si è bloccato o si è verificato un problema, il file non è stato eliminato. O se rileva l'errore, o alla successiva esecuzione noterà il file e quindi può agire, ad esempio comprimerlo (ad esempio 7zip) e inviarlo via email o renderlo altrimenti disponibile.

Oggigiorno molti sistemi incorporano la segnalazione automatica di guasti a un server centrale (dopo aver verificato con gli utenti, ad esempio per motivi di privacy).


Sta guardando

D: Quali strumenti utilizzare per visualizzare i registri?

A: Se hai più registri per diversi motivi, utilizzerai più visualizzatori.

Notepad / vi / Notepad ++ o qualsiasi altro editor di testo è la base per i registri di testo normale.

Se hai operazioni complesse, ad esempio attività con trasferimenti, allora, ovviamente, utilizzeresti uno strumento specializzato come Service Trace Viewer. (Ma se non ne hai bisogno, un editor di testo è più facile).

Dato che in genere registro informazioni di alto livello nel registro eventi di Windows, allora fornisce un modo rapido per ottenere una panoramica, in modo strutturato (cercare le graziose icone di errore / avviso). Devi solo iniziare a cercare i file di testo se non ce n'è abbastanza nel registro, sebbene almeno il registro ti dia un punto di partenza. (A questo punto, assicurarsi che i log abbiano coordinato gli impegni diventa utile).

Generalmente il registro eventi di Windows rende disponibili questi eventi significativi anche a strumenti di monitoraggio come MOM o OpenView.

Altri --

Se si accede a un database, può essere facile filtrare e ordinare le informazioni (ad es. Ingrandire un particolare ID attività (con i file di testo è possibile utilizzare Grep / PowerShell o simile per filtrare il GUID particolare che si desidera)

MS Excel (o un altro programma per fogli di calcolo). Ciò può essere utile per analizzare informazioni strutturate o semi-strutturate se è possibile importarle con i delimitatori corretti in modo che valori diversi vadano in colonne diverse.

Quando eseguo un servizio in debug / test di solito lo ospito in un'applicazione console per semplicità trovo utile un logger di console colorato (ad esempio rosso per errori, giallo per avvisi, ecc.). È necessario implementare un listener di tracce personalizzato.

Si noti che il framework non include un logger di console colorato o un logger di database, quindi, al momento, è necessario scriverli se ne hanno bisogno (non è troppo difficile).

Mi dà davvero fastidio il fatto che diversi framework (log4net, EntLib, ecc.) Abbiano perso tempo a reinventare la ruota e reimplementare la registrazione di base, il filtro e la registrazione in file di testo, il registro eventi di Windows e i file XML, ognuno nel proprio modo diverso (le istruzioni di registro sono diverse in ciascuna); ognuno ha quindi implementato la propria versione di, ad esempio, un registratore di database, quando la maggior parte di quello esisteva già e tutto ciò che serviva era un paio di listener in più per System.Diagnostics. Parla di un grande spreco di sforzi duplicati.

D: Se stai creando una soluzione ASP.NET, usi anche ASP.NET Health Monitoring? Includete l'output di traccia negli eventi di monitoraggio dello stato? Che dire di Trace.axd?

Queste cose possono essere attivate / disattivate secondo necessità. Trovo Trace.axd abbastanza utile per il debug di come un server risponde a determinate cose, ma non è generalmente utile in un ambiente fortemente utilizzato o per la traccia a lungo termine.

D: E i contatori delle prestazioni personalizzati?

Per un'applicazione professionale, in particolare un server / servizio, mi aspetto di vederlo completamente strumentato con entrambi i contatori di Performance Monitor e la registrazione nel registro eventi di Windows. Questi sono gli strumenti standard di Windows e devono essere utilizzati.

È necessario assicurarsi di includere i programmi di installazione per i contatori delle prestazioni e i registri eventi utilizzati; questi dovrebbero essere creati al momento dell'installazione (durante l'installazione come amministratore). Quando l'applicazione è in esecuzione normalmente, non dovrebbe avere privilegi di amministrazione (e quindi non sarà in grado di creare registri mancanti).

Questa è una buona ragione per esercitarsi nello sviluppo come non amministratore (avere un account amministratore separato per quando è necessario installare servizi, ecc.). Se si scrive nel registro eventi, .NET creerà automaticamente un registro mancante la prima volta che si scrive su di esso; se si sviluppa come un non amministratore, lo si capisce presto ed si evita una brutta sorpresa quando un cliente installa il sistema e quindi non può utilizzarlo perché non è in esecuzione come amministratore.


Cordiali saluti: ho riscontrato un problema a causa del quale la traccia di Microsoft in un file si arresta in modo anomalo. Se si hanno più processi (o thread) che scrivono nello stesso file e si scontrano, viene visualizzato un errore di blocco dell'accesso esclusivo al file system nel file di registro.
Jay,

1
L'infrastruttura System.Diagnostics è thread-safe; il comportamento predefinito prevede il blocco del framework, tuttavia è possibile ignorare TraceListener.IsThreadSafe se si fornisce il proprio blocco. Vedi msdn.microsoft.com/en-us/library/… . Per più processi normalmente si scrive su file separati, ma si noti che Service Viewer Trace può caricare più file di traccia (ad es. Da più macchine) e correlarli tramite ActivityId.
Sly Gryphon,

1
Potresti essere in grado di suggerire come utilizzare TraceEvent () per registrare le eccezioni?
Dmitriy Sosunov,

1
Non è uno dei maggiori inconvenienti di System.Diagnostics.Traceciò che è decorato con [Conditional("TRACE")]ciò che lo rende inutilizzabile negli ambienti di produzione, dove raramente è stato compilato il codice con la TRACEbandiera?
Asbjørn Ulsberg,

2
@asbjornu La configurazione di build di rilascio predefinita in Visual Studio ha TRACE definito (è DEBUG che è disattivato per i build di rilascio); se si crea dalla riga di comando, tuttavia, è necessario attivarlo.
Sly Gryphon,

40

Devo unirmi al coro raccomandando log4net, nel mio caso, dal punto di vista della flessibilità della piattaforma (desktop .Net / Compact Framework, 32/64-bit).

Tuttavia, avvolgendolo in un'API con etichetta privata è un anti-modello importante . log4net.ILoggerè già la controparte .Net dell'API wrapper Commons Logging , quindi l'accoppiamento è già minimizzato per te, e dal momento che è anche una libreria Apache, di solito non è nemmeno un problema perché non stai cedendo alcun controllo: biforca se tu dovere.

La maggior parte delle librerie di wrapper per casa che ho visto commettono anche una o più di una litania di guasti:

  1. Utilizzo di un logger singleton globale (o equivalentemente un punto di ingresso statico) che perde la risoluzione fine del modello di logger per classe consigliato per nessun altro guadagno di selettività.
  2. Impossibile esporre l' Exceptionargomento facoltativo , causando più problemi:
    • Rende ancora più difficile mantenere una politica di registrazione delle eccezioni, quindi nulla viene fatto coerentemente con le eccezioni.
    • Anche con una politica coerente, la formattazione dell'eccezione in una stringa perde prematuramente i dati. Ho scritto un ILayoutdecoratore personalizzato che esegue il drill-down dettagliato su un'eccezione per determinare la catena di eventi.
  3. Impossibile esporre le proprietàIsLevelEnabled , il che elimina la possibilità di saltare la formattazione del codice quando le aree o i livelli di registrazione sono disattivati.

1
Mi è stato affidato il compito di refactoring di un (orribile) involucro interno attorno a log4j in qualcosa di un po 'meno orribile (è ancora piuttosto male, ma questo è il risultato di soddisfare i requisiti che mi sono stati dati in log4j). Ho cercato di eliminare il punto di accesso statico globale, ma sono stato abbattuto. Davvero non capisco il punto. Nella nostra configurazione, log4j è così pesantemente ampliato e distorto che in realtà viene utilizzato come dispatcher di eventi; lo stiamo usando solo perché qualcuno ha chiesto "come possiamo usare log4j per questo?" Usa log4whatever direttamente o semplicemente scrivi il tuo framework. La strada di mezzo è dolorosa.
Adam Jaskiewicz,

25
Non sono d'accordo con la tua raccomandazione di non avvolgere log4net. Il wrapping con una sottile API modello provider consente agli utenti delle librerie di classi di collegare il proprio framework di registrazione preferito. YMMV ovviamente, ma descriverlo come un "grande anti-schema" è un po 'dogmatico. Anche il fatto che esistano librerie wrapper con "una litania di errori" non è un buon argomento contro un wrapper ben scritto.
Joe,

1
Definire qualcosa come un anti-pattern non significa che sia sempre una cattiva idea al 100% - solo che crea una tendenza a dipingersi in un angolo se non stai attento. Inoltre, ILog / LogManager è di per sé una mini-libreria wrapper ben scritta nell'immagine di registrazione dei beni di consumo raggruppata nell'assemblaggio log4net, ma non c'è motivo per cui non possa essere estratta e trasformata in una registrazione di beni comuni per CLR.
Jeffrey Hantin,

18

Spesso non sviluppo in asp.net, tuttavia quando si tratta di logger penso che molte delle migliori pratiche siano universali. Ecco alcuni dei miei pensieri casuali sulla registrazione che ho imparato negli anni:

Frameworks

  • Utilizza un framework di astrazione del logger, come slf4j (o esegui il roll-roll), in modo da disaccoppiare l'implementazione del logger dalla tua API. Ho visto un numero di framework di logger che vanno e vengono e che è meglio essere in grado di adottarne uno nuovo senza troppi problemi.
  • Prova a trovare un framework che supporti una varietà di formati di output.
  • Prova a trovare un framework che supporti plugin / filtri personalizzati.
  • Utilizzare un framework che può essere configurato da file esterni, in modo che i vostri clienti / consumatori possano modificare facilmente l'output del log in modo che possa essere letto facilmente dalle applicazioni di gestione dei log commerciali.
  • Assicurati di non esagerare con i livelli di registrazione personalizzati, altrimenti potresti non essere in grado di passare a diversi framework di registrazione.

Uscita logger

  • Cerca di evitare i log in stile XML / RSS per la registrazione che potrebbe incontrare errori catastrofici. Questo è importante perché se l'interruttore di alimentazione viene spento senza che il logger scriva il </xxx>tag di chiusura , il log viene interrotto.
  • Discussioni di registro. Altrimenti, può essere molto difficile tenere traccia del flusso del programma.
  • Se devi internazionalizzare i tuoi registri, potresti volere che uno sviluppatore acceda solo in inglese (o nella tua lingua preferita).
  • A volte la possibilità di inserire istruzioni di registrazione nelle query SQL può essere un vero toccasana in situazioni di debug. Ad esempio:
    - Classe di invocazione: com.foocorp.foopackage.FooClass: 9021
    SELEZIONA * DA foo;
  • Si desidera la registrazione a livello di classe. Normalmente non si vogliono anche istanze statiche di logger - non vale la microottimizzazione.
  • Contrassegnare e classificare le eccezioni registrate è talvolta utile perché non tutte le eccezioni sono uguali. Pertanto, conoscere un sottoinsieme di eccezioni importanti è utile se si dispone di un monitor di registro che deve inviare notifiche su stati critici.
  • I filtri di duplicazione salveranno la vista e il disco rigido. Vuoi davvero vedere la stessa dichiarazione di registrazione ripetuta 10 ^ 10000000 volte? Non sarebbe meglio solo ricevere un messaggio come: This is my logging statement - Repeated 100 times

Vedi anche questa mia domanda .


5
i filtri di duplicazione sono un'ottima idea
Paul Stovell,

ero d'accordo sul problema del tag rotto, ma la maggior parte dei bravi scrittori XML non usano comunque l'XML completo (cioè nessun elemento root) in modo che possano accedere senza caricare il DOM XML. nel caso non comune si verifica un problema da una voce parzialmente scritta, è possibile risolverlo manualmente
Paul Stovell,

Vado avanti e indietro sulla registrazione XML da anni. Ora, mi sembra eccessivo. Se avessi bisogno di un feed RSS dello stato di un'applicazione, penso che sia meglio implementato con un'utilità di monitoraggio dei log.
Elia il

Sono d'accordo su RSS. Sto pensando di più agli strumenti di visualizzazione che ti consentono di comprendere meglio la voce. con i file di testo generalmente si desidera mantenere una voce su una riga; ma a volte vuoi includere tracce di stack o oggetti serializzati. è qui che un registro XML (usato da WCF) è utile
Paul Stovell,

+1 per menzionare la strumentazione di query SQL. Questo è davvero molto utile per la correlazione delle tracce del database e delle tracce dell'applicazione. Lo sto facendo manualmente nel mio DAL, ma mi chiedo che tipo di supporto per gli strumenti esiste per questa tecnica?
Constantin,

17

Non sono qualificato per commentare la registrazione per .Net, poiché il mio pane e burro è Java, ma negli ultimi 8 anni abbiamo avuto una migrazione nella nostra registrazione, potresti trovare un'analogia utile alla tua domanda.

Abbiamo iniziato con un logger Singleton utilizzato da ogni thread all'interno della JVM e impostato il livello di registrazione per l'intero processo. Ciò ha comportato enormi registri se avessimo dovuto eseguire il debug anche di una parte molto specifica del sistema, quindi la lezione numero uno è quella di segmentare la registrazione.

La nostra attuale incarnazione del logger consente più istanze con una definita come predefinita. È possibile creare un'istanza di un numero qualsiasi di logger figlio con livelli di registrazione diversi, ma l'aspetto più utile di questa architettura è la capacità di creare logger per singoli pacchetti e classi semplicemente modificando le proprietà di registrazione. La lezione numero due è quella di creare un sistema flessibile che consenta di sovrascriverne il comportamento senza modificare il codice.

Stiamo usando la libreria di registrazione dei beni comuni di Apache racchiusa in Log4J.

Spero che questo ti aiuti!

* Modificare *

Dopo aver letto il post di Jeffrey Hantin qui sotto, mi sono reso conto che avrei dovuto notare cosa è diventato il nostro wrapper di registrazione interno. Ora è essenzialmente una fabbrica ed è strettamente utilizzato per ottenere un logger funzionante utilizzando il file delle proprietà corretto (che per motivi legacy non è stato spostato nella posizione predefinita). Poiché ora puoi specificare il file di configurazione della registrazione sulla riga di comando, sospetto che diventerà ancora più snello e se stai avviando una nuova applicazione, sarei sicuramente d'accordo con la sua affermazione che non dovresti nemmeno preoccuparti di avvolgere il logger.


Grazie per la risposta. crei i logger secondari manualmente nel codice (ovvero, sono codificati in modo rigido) o attraverso una sorta di cosa automatica / implicita?
Paul Stovell,

No ... se aggiungiamo una configurazione di registrazione ai file logging.properties per un pacchetto o una classe, verranno registrati per quella configurazione ma qualsiasi pacchetto o classe non specificamente configurato verrà registrato ai livelli predefiniti.
Steve Moyer,

9

Usiamo Log4Net al lavoro come provider di logging, con un wrapper singleton per l'istanza di log (sebbene il singleton sia in fase di revisione, chiedendosi se siano una buona idea o meno).

L'abbiamo scelto per i seguenti motivi:

  • Semplice configurazione / riconfigurazione su vari ambienti
  • Buon numero di appendici precostruite
  • Uno dei CMS che usiamo lo aveva già integrato
  • Bel numero di livelli di registro e configurazioni intorno a loro

Dovrei menzionare, questo sta parlando da un punto di vista di sviluppo ASP.NET

Riesco a vedere alcuni meriti nell'uso della traccia che si trova nel framework .NET ma non ci vendo del tutto, principalmente perché i componenti con cui lavoro non eseguono chiamate Trace. L'unica cosa che uso di frequente è System.Net.Mailciò che posso dire.

Quindi abbiamo una libreria che avvolge log4net e nel nostro codice abbiamo solo bisogno di cose come questa:

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

All'interno dei metodi eseguiamo un controllo per vedere se il livello di registrazione è abilitato, quindi non hai chiamate ridondanti all'API log4net (quindi se Debug non è abilitato, le istruzioni di debug vengono ignorate), ma quando ricevo del tempo Lo aggiornerò per esporre quelli in modo che tu possa fare tu stesso i controlli. Ciò impedirà che vengano eseguite valutazioni quando non dovrebbero, ad esempio:

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Questo diventerà:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Risparmia un po 'di tempo di esecuzione)

Per impostazione predefinita accediamo a due posizioni:

  1. File system del sito Web (in un'estensione di file non servita)
  2. Invio e-mail per errore e fatale

I file vengono eseguiti come rolling di ogni giorno o 10 MB (IIRC). Non utilizziamo EventLog in quanto può richiedere una sicurezza più elevata di quanto spesso desideriamo fornire un sito.

Trovo che Blocco note funzioni perfettamente per la lettura dei registri.


I framework di registrazione sono uno dei pochi casi in cui il singleton non è un uso improprio.
mmcdole,

Può essere se si desidera fornire un contesto attorno al proprio logger. Ma aiuta a gestire la concorrenza
Aaron Powell,

7
Avrei sicuramente strappato il singleton. Puoi certamente avere una singola istanza che viene passata in giro (preferibilmente nel contenitore IOC / DI). Vorrei anche provare a spostare la registrazione in un intercettore ...
yfeldblum,

2
Nemmeno un fan della singola istanza. Preferisco assegnare a ciascuna classe un logger con un nome univoco, quindi attivare o disattivare la registrazione in base al modulo è facile.
Jeffrey Hantin,

8

Quali framework usi?

Utilizziamo un mix del blocco dell'applicazione di registrazione e un helper di registrazione personalizzato che lavora attorno ai bit del framework .Net. LAB è configurato per produrre file di registro abbastanza estesi, inclusi file di traccia generali separati per l'immissione / uscita del metodo di servizio e file di errore specifici per problemi imprevisti. La configurazione include data / ora, thread, pId ecc. Per l'assistenza di debug, nonché i dettagli e lo stack completi delle eccezioni (nel caso di un'eccezione imprevista).

L'helper di registrazione personalizzato utilizza Trace.Correlation ed è particolarmente utile nel contesto della registrazione in WF. Ad esempio, abbiamo una macchina a stati che invoca una serie di flussi di lavoro sequenziali. Ad ognuna di queste attività di richiamo registriamo l'inizio (usando StartLogicalOperation) e poi alla fine interrompiamo l'operazione logica con un gestore di eventi di ritorno gereric.

Ciò si è rivelato utile alcune volte quando si è tentato di eseguire il debug degli errori in sequenze aziendali complesse in quanto ci consente di determinare più rapidamente le decisioni relative alle filiali If / Else ecc. In base alla sequenza di esecuzione dell'attività.

Quali output di log usi?

Utilizziamo file di testo e file XML. I file di testo sono configurati tramite il blocco app ma abbiamo anche output XML dal nostro servizio WF. Ciò ci consente di acquisire gli eventi di runtime (persistenza, ecc.) Nonché le eccezioni di tipo aziendale generico. I file di testo sono registri di scorrimento che vengono spostati per giorno e dimensione (credo che la dimensione totale di 1 MB sia un punto di rollover).

Quali strumenti usi per visualizzare i log?

Stiamo usando Notepad e WCF Service Trace Viewer a seconda del gruppo di output che stiamo esaminando. Il servizio WCF Trace Viewer è davvero utile se hai configurato correttamente l'output e puoi rendere la lettura dell'output molto più semplice. Detto questo, se so all'incirca dove si trova l'errore, anche solo leggere un file di testo ben annotato è buono.

I registri vengono inviati a una singola directory che viene quindi suddivisa in sottodirectory in base al servizio di origine. La directory principale è esposta tramite un sito Web il cui accesso è controllato da un gruppo di utenti del supporto. Questo ci consente di dare un'occhiata ai registri di produzione senza dover inserire richieste e passare lunghi processi burocratici per i dati di produzione.


6

Come autori dello strumento, utilizziamo ovviamente SmartInspect per la registrazione e la traccia delle applicazioni .NET. Di solito utilizziamo il protocollo pipe denominato per la registrazione live e i file di registro binari (crittografati) per i registri dell'utente finale. Usiamo la SmartInspect Console come visualizzatore e strumento di monitoraggio.

Esistono in realtà alcuni framework e strumenti di registrazione per .NET. C'è una panoramica e un confronto dei diversi strumenti su DotNetLogging.com .


5

Ci sono molti ottimi consigli nelle risposte.

Una buona pratica generale è considerare chi leggerà il registro. Nel mio caso sarà un amministratore nel sito client. Quindi registro i messaggi che danno loro qualcosa su cui possono agire. Ad esempio, "Impossibile inizializzare l'applicazione. Questo di solito è causato da ......"


1

Usiamo log4net sulle nostre applicazioni web.

La sua capacità di personalizzare la registrazione in fase di esecuzione modificando il file di configurazione XML è molto utile quando un'applicazione non funziona in fase di esecuzione e è necessario visualizzare ulteriori informazioni.

Consente inoltre di scegliere come target classi o attributi specifici per accedere. Questo è molto utile quando hai un'idea di dove si sta verificando l'errore. Un classico esempio è NHibernate in cui si desidera vedere solo l'SQL che va nel database.

Modificare:

Scriviamo tutti gli eventi in un database e nel sistema di traccia. Il registro eventi che utilizziamo per errori o eccezioni. Registriamo la maggior parte degli eventi su un database in modo da poter creare report personalizzati e consentire agli utenti di visualizzare il registro se lo desiderano direttamente dall'applicazione.


Puoi fornire maggiori dettagli su come lo usi? Accedete a un file o al registro eventi? È un file di registro a rotazione? Cosa fai per proteggerlo o eseguirne il backup? Sono interessato all'utilizzo nella vita reale.
Paul Stovell,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.