it-swarm.it

Best practice per la registrazione e la traccia in .NET

Ho letto molto su traccia e registrazione, cercando di trovare qualche regola d'oro per le migliori pratiche in materia, ma non ce ne sono. La gente dice che i bravi programmatori producono una buona traccia, ma la mettono così e deve provenire dall'esperienza.

Ho anche letto domande simili qui e attraverso Internet e non sono proprio la stessa cosa che sto chiedendo o non hanno una risposta soddisfacente, forse perché le domande mancano di qualche dettaglio.

Quindi, la gente dice che la traccia dovrebbe replicare l'esperienza di debug dell'applicazione nei casi in cui non è possibile collegare un debugger. Dovrebbe fornire un contesto sufficiente in modo da poter vedere quale percorso viene preso in ciascun punto di controllo nell'applicazione.

Andando più in profondità, puoi persino distinguere tra traccia e registrazione degli eventi, in quanto "la registrazione degli eventi è diversa dalla traccia in quanto cattura gli stati principali piuttosto che un flusso dettagliato di controllo".

Ora, supponiamo di voler eseguire la traccia e la registrazione utilizzando solo le classi .NET standard, quelle nella System.Diagnostics namespace. Ho pensato che la classe TraceSource fosse migliore per il lavoro rispetto alla classe Trace statica, perché voglio differenziare tra i livelli di traccia e usando la classe TraceSource posso passare un parametro che informa il tipo di evento, mentre usando la classe Trace devo usare Trace.WriteLineIf e quindi verificare cose come SourceSwitch.TraceInformation e SourceSwitch.TraceErrors e non ha nemmeno proprietà come TraceVerbose o TraceStart.

Con tutto ciò in mente, considereresti una buona pratica fare come segue:

  • Traccia un evento "Start" all'avvio di un metodo, che dovrebbe rappresentare una singola operazione logica o una pipeline, insieme a una rappresentazione in formato stringa dei valori dei parametri passati al metodo.
  • Traccia un evento "Informazioni" quando si inserisce un elemento nel database.
  • Traccia un evento "Informazioni" quando segui un percorso o un altro in un'istruzione if/else importante.
  • Traccia un "Critico" o "Errore" in un blocco catch a seconda che si tratti di un errore recuperabile.
  • Traccia un evento "Stop" al termine dell'esecuzione del metodo.

Inoltre, chiarire quando è meglio rintracciare i tipi di eventi dettagliati e di avviso. Se hai esempi di codice con Nice trace/logging e sei disposto a condividere, sarebbe eccellente.

Nota: Ho trovato alcune buone informazioni qui, ma ancora non quello che sto cercando: http://msdn.Microsoft. com/it-it/magazine/ff714589.aspx

53
Levidad

L'importanza dei tipi di traccia non deve essere scelta a causa di dove si trova la traccia nel codice, ma perché il messaggio tracciato è più o meno importante. Esempio:

Traccia un evento "Start" all'avvio di un metodo, che dovrebbe rappresentare una singola operazione logica o una pipeline, insieme a una rappresentazione in stringa dei valori dei parametri passati al metodo.

Utilizzare il tipo di avvio quando si avvia un'operazione logica. Ciò non significa che la traccia iniziale deve essere all'inizio di un metodo, né significa che un metodo deve avere una traccia iniziale.

Detto questo, nella maggior parte dei casi, un'operazione logica inizierà effettivamente all'inizio del metodo. Altrimenti, dovresti chiederti se il codice è stato refactored correttamente.

Tracciare i parametri può anche essere una cattiva idea. Devi pensare a cosa rintracciare, caso per caso. Ad esempio, è davvero male tracciare i parametri di un metodo void Authenticate(string userName, string plainPassword).

Traccia un evento "Informazioni" quando si inserisce un elemento nel database.

Dipende. Alcuni elementi devono essere tracciati, ma non tutti gli articoli.

  • Ad esempio, immagina di inserire effettivamente un elemento del registro nel tuo database. Tracceresti i registri? E poi registra le tracce? E quindi tracciare la registrazione della traccia?
  • Un altro esempio: stai inserendo dati sensibili. Ciò richiede il controllo. Poiché hai verificato l'inserimento, perché tracciarlo?

Traccia un evento "Informazioni" quando segui un percorso o un altro in un'istruzione if/else importante.

Ancora una volta, dipende.

Traccia un "Critico" o "Errore" in un blocco di cattura a seconda del tempo, si tratta di un errore recuperabile.

L'azione intrapresa dopo un errore non recuperabile può essere più che traccia. Ad esempio sul lato server, si desidera archiviare l'eccezione nel database per ulteriori analisi. Inoltre, alcune eccezioni sono meno importanti di altre e non richiedono traccia.

Traccia un evento "Stop" al termine dell'esecuzione del metodo.

Vedi il primo punto.

chiarire quando è meglio rintracciare i tipi di eventi verbose e di avviso.

verbose:

Il verbose viene utilizzato per tracciare ciò che è necessario tracciare quando qualcosa va davvero storto. Ciò significa che nella maggior parte dei casi disabiliterai la traccia dei messaggi dettagliati, ma a volte devi eseguire il debug di alcune parti del codice per capire perché qualcosa non funziona in un caso Edge.

Di solito hai molti messaggi dettagliati che ti permettono di capire davvero bene il flusso dell'applicazione. Significa anche che quei messaggi devono essere disabilitati il ​​più delle volte perché:

  • altrimenti, il registro crescerà molto velocemente,
  • non ti servono per la maggior parte del tempo,
  • possono contenere dati sensibili sul flusso dell'applicazione.

Pensa al prolisso come uno strumento che devi usare quando non hai accesso al debugger.

Attenzione:

La traccia del tipo di avviso viene utilizzata quando succede qualcosa di sbagliato e importante, ma non è troppo cruciale per essere trattata come un errore. Ad esempio basso RAM può emettere un avviso, ma non vi è motivo di tracciare un errore, poiché l'applicazione può continuare, anche se sarà più lenta del solito.

Esempi:

  • Esempio 1: l'applicazione non è riuscita ad aprire il file che l'utente ha richiesto di aprire. Il file esiste e non è in uso, le autorizzazioni sono impostate correttamente, ma qualcosa blocca l'apertura di un file. In questo caso, verrà tracciato un errore, poiché l'applicazione non è in grado di gestire questo caso e continua a funzionare come previsto dall'utente (ovvero leggere effettivamente il file).

  • Esempio 2: dopo l'ispezione dell'errore nel primo esempio, si scopre che l'errore è causato dal fatto che il percorso del file è più lungo di 259 caratteri. Quindi refatti il ​​tuo codice per catturare PathTooLongException. Quando, la volta successiva, l'utente tenta di aprire lo stesso file, la nuova versione dell'applicazione mostra un messaggio che spiega che il file è troppo lungo e deve essere spostato in un'altra cartella per accorciare il percorso completo al fine di aprire questo file in questa applicazione. Traccia anche un messaggio.

  • Esempio 3: l'applicazione ha impiegato venti secondi per aprire e analizzare un piccolo file mentre la maggior parte dei file impiegava da dieci a cento millisecondi per aprirsi e analizzarsi. Si traccia un avviso con informazioni rilevanti: il tipo di disco in cui si trova effettivamente il file, il file system, la dimensione del file, il tempo esatto trascorso, il tempo in cui il computer era acceso, ecc. Quando l'utente si lamenta che ci vogliono venti secondi per aprire il file, prendi la traccia per trovare cosa succede. Ad esempio, potresti trovare che il caricamento dei file da una condivisione di rete richiede così tanto tempo quando il computer è appena stato avviato. Spieghi all'utente che il ritardo è dovuto alla rete e non è correlato alla tua applicazione.

  • Esempio 4: il file aperto viene visualizzato in modo errato. Abiliti verbose trace dove vedi effettivamente come i dati vengono caricati dal file e quindi analizzati, passo dopo passo.

17
Arseni Mourzenko
 > say I want to do my tracing and logging using only the standard .NET classes

System.Diagnostics è fantastico perché è possibile configurare la destinazione delle informazioni di traccia (file, registro eventi, database, ....)

Sfortunatamente, se vuoi usare System.Diagnostics devi sapere in anticipo (in fase di progettazione), quali tracce di traccia dovrebbe essere possibile seguire. (Nell'articolo di esempio si tratta di Trasferimento, Riprendi, Sospendi, ...). Questi possono essere configurati su Disabilitato, Debuglevel o Errorlevel.

Preferisco avere un sistema di registrazione in cui posso decidere in fase di esecuzione su classlevel/namespacelevel, quanto dettagliato dovrebbe essere la registrazione. Ad esempio, tutto il debug e sopra da MyNamespace.Business.* ma no MyNamespace.Business.Calculations.

Se si utilizza log4net (o Common.logging) ogni classe ottiene il proprio logger in modo da poter decidere facilmente quali classi vengono registrate a quale livello.

Poiché le operazioni del database sono in una classe separata, non è più necessaria una regola distinta

Trace an "Information" event when inserting an item into the database.

Preferisco invece avere queste linee guida:

  • Tracelevel dovrebbe mostrare il flusso di lavoro di base
  • Il debuglevel dovrebbe mostrare dati dettagliati ed elaborazione all'interno del flusso di lavoro, comprese le decisioni nel flusso di programma con motivazioni (Creazione di un nuovo elemento perché l'elemento non esisteva nel DB)
  • Infolevel per l'avvio/arresto dei servizi e una voce per ogni flusso di lavoro/azione della GUI avviata
5
k3b

Puoi provare Story framework , ha un approccio unico alla registrazione in quanto "fa" scrivere tutti i registri (e aggiungere altre informazioni pertinenti) nel contesto, quindi quando devi leggerlo in seguito ottieni tutto ciò di cui hai bisogno.

Aggiungerà automaticamente i concetti "inizio" e "arresto" come l'inizio e la fine di una storia.

E con un sistema basato su regole puoi controllare cosa fare di ogni storia (contesto) in base alle informazioni che ha, ad esempio stampare tutte le storie che hanno un errore o provengono dall'utente "admin".

Ulteriori informazioni su questo post sul blog

4
Amit Apple