Quali sono alcuni pattern e anti-pattern di registrazione delle applicazioni? [chiuso]

64

Recentemente ho dovuto esaminare un problema sul campo per la nostra applicazione aziendale di grandi dimensioni. Sono rimasto inorridito dai log che ho dovuto sfogliare nel tentativo di trovare il problema e alla fine della giornata i log non hanno affatto aiutato a identificare / isolare il bug.

Nota: capisco che non tutti i bug siano rilevabili tramite i registri. Questo non cambia il fatto che i registri sono orribili.

Ci sono alcuni problemi evidenti con la nostra registrazione che possiamo già provare a risolvere. Non voglio elencare quelli qui e non posso semplicemente mostrarti i nostri file di registro in modo da poter dare consigli su cosa fare.

Invece, per valutare quanto male stiamo facendo sul fronte del logging, vorrei sapere:

  1. Quali sono alcune linee guida , se presenti, quando si tratta della registrazione per un'applicazione, in particolare un'applicazione di grandi dimensioni.
  2. Ci sono dei pattern dovremmo seguire o anti-pattern di cui dovremmo essere a conoscenza?
  3. È una cosa importante da risolvere o può anche essere riparata o tutti i file di log sono semplicemente enormi e hai bisogno di script supplementari per analizzarli?

Nota a margine: usiamo log4j.

    
posta c_maker 04.10.2011 - 22:24
fonte

9 risposte

53

Alcuni punti che la mia pratica si è rivelata utile:

  • Mantieni tutto il codice di registrazione nel codice di produzione. Avere la possibilità di abilitare la registrazione più / meno dettagliata in produzione, preferibilmente per sottosistema e senza riavviare il programma.

  • Rendi i registri facili da analizzare in base a grep e a occhio. Attenersi a diversi campi comuni all'inizio di ogni riga. Identifica ora, gravità e sottosistema in ogni riga. Formulare chiaramente il messaggio. Rendi facile associare ogni messaggio di registro alla sua linea di codice sorgente.

  • Se si verifica un errore, prova a raccogliere e registrare quante più informazioni possibili. Potrebbe richiedere molto tempo, ma va bene perché l'elaborazione normale ha comunque fallito. Non dover aspettare quando la stessa condizione si verifica in produzione con un debugger collegato non ha prezzo.

I log sono principalmente necessari per il monitoraggio e la risoluzione dei problemi. Mettiti nei panni di uno strumento per la risoluzione dei problemi e pensa che tipo di registri ti piacerebbe avere quando qualcosa di sbagliato sta accadendo o è successo nel cuore della notte.

    
risposta data 05.10.2011 - 01:20
fonte
27

La mia risorsa pubblica preferita per le linee guida per la registrazione è Buone pratiche di Apache JCL .

Best practices for JCL are presented in two categories: General and Enterprise. The general principles are fairly clear. Enterprise practices are a bit more involved and it is not always as clear as to why they are important.

Enterprise best-practice principles apply to middleware components and tooling that is expected to execute in an "Enterprise" level environment. These issues relate to Logging as Internationalization, and fault detection. Enterprise requires more effort and planning, but are strongly encouraged (if not required) in production level systems. Different corporate enterprises/environments have different requirements, so being flexible always helps...

Nonostante il targeting JCL, questi sembrano abbastanza generici da essere adottati per il logging in generale.

  • Le mie "linee guida" personali per la registrazione sono che a livello di debug, provo a rendere i registri letti come una storia, con logica comprensibile e dettagli sufficienti (ma non sovraccarichi).

Il più famoso anti-pattern è probabilmente "ingoiare le eccezioni": cerca solo nel web.

Per quanto riguarda i file di registrazione enormi, nella mia pratica questo era per lo più il caso normale. E sì, script supplementari come li chiami e / o strumenti come Chainsaw danno anche un'occhiata normale per me.

  • Above non significa però che devi sempre mettere ciecamente tutti i registri in un unico file enorme. A volte potrebbe essere utile scrivere / copiare alcuni registri in file separati. Ad esempio, nel mio recente progetto, i ragazzi del QA hanno richiesto file dedicati per metriche e dati temporali e per brevi rapporti sulle operazioni di sistema. Hanno detto che trarranno beneficio da ciò e che dev lo ha fatto (beneficiano di un breve report che risulta davvero significativo).

PS. Riguardo agli anti-schemi, altri che vengono in mente sono "inondazioni" e messaggi privi di senso.

  • Lo chiamo flooding quando vedo più messaggi simili provenienti da un ciclo con molte iterazioni. Per me, l'allagamento è abbastanza fastidioso da cercare di liberarmene quando lo rilevo nel codice sorgente. Solitamente il miglioramento richiede un po 'di arte - perché, beh, le cose che accadono all'interno del ciclo possono essere interessanti. Quando non ho il tempo di migliorarlo più a fondo, cerco di modificare almeno il livello di registrazione di tali messaggi al livello più basso per semplificare il filtraggio.

  • I messaggi senza senso sembrano essere spazzatura piuttosto popolare. Questi sembrano innocui se letti nel codice sorgente - Immagino che si debba passare attraverso il dolore dell'analisi dell'output di debug come ...

    step #1
    step #2
    step #3
    

    ... per apprezzare profondamente la loro bruttezza intrinseca. La mia euristica preferita per rilevare questo tipo di problemi a livello di codice sorgente (proposta da un collega in uno dei miei progetti precedenti) consiste nel calcolare il numero di occorrenze di simboli spaziali in stringhe letterali utilizzate nella registrazione. Nella mia esperienza, zero spazi sostanzialmente garantisce che la dichiarazione di registrazione sia priva di senso, uno spazio è anche un buon indicatore del potenziale problema.

risposta data 04.10.2011 - 22:41
fonte
27

Lavoro con sistemi di sicurezza in tempo reale critici e il logging è spesso l'unico modo per catturare bug rari che si presentano una volta una luna blu ogni 53esimo martedì quando è una luna piena, se riesci a cogliere la mia direzione. Questo ti rende ossessivo riguardo all'argomento, quindi mi scuserò ora se comincio a schiumare alla bocca. Quanto segue è stato scritto per i log di debug del codice nativo, ma la maggior parte è applicabile anche al mondo gestito ...

Usa i file di log di testo. Sembra ovvio, ma alcune persone cercano di generare file di log binari: è semplicemente stupido perché non ho bisogno di cercare uno strumento di lettura quando sono fuori sul campo. Inoltre, se si tratta di testo e il debug è prolisso, ci sono buone probabilità che l'ingegnere sul campo possa leggere il file e diagnosticare il problema senza mai tornare da me. Tutti vincono.

Ho progettato sistemi in grado di registrare praticamente tutto, ma non accendo tutto per impostazione predefinita. Le informazioni di debug vengono inviate a una finestra di debug nascosta che la marca e la stampa in una listbox (limitata a circa 500 righe prima della cancellazione), e la finestra di dialogo mi consente di fermarla, salvarla automaticamente in un file di log o deviarla su un debugger allegato. Quel diversivo mi permette di vedere l'output di debug di più applicazioni tutte ordinatamente serializzate, che a volte può essere un risparmiatore di vita. Io usato per usare i livelli di registrazione numerica (più alto è il livello, più acquisisci):

off
errors only
basic
detailed
everything

ma questo è troppo inflessibile - mentre ti dirigi verso un bug è molto più efficiente essere in grado di focalizzare l'accesso esattamente su ciò di cui hai bisogno senza dover attraversare tonnellate di detriti, e potrebbe essere un tipo particolare di transazione o operazione che causa l'errore. Se ciò richiede di attivare tutto, stai solo rendendo più difficile il tuo lavoro. Hai bisogno di qualcosa di più fine.

Quindi ora sto passando alla registrazione basata su un sistema di flag. Tutto ciò che viene registrato ha un flag che indica in dettaglio il tipo di operazione, e c'è un set di checkbox che mi permette di definire cosa viene registrato. Solitamente questo elenco ha il seguente aspetto:

#define DEBUG_ERROR          1
#define DEBUG_BASIC          2
#define DEBUG_DETAIL         4
#define DEBUG_MSG_BASIC      8
#define DEBUG_MSG_POLL       16
#define DEBUG_MSG_STATUS     32
#define DEBUG_METRICS        64
#define DEBUG_EXCEPTION      128
#define DEBUG_STATE_CHANGE   256
#define DEBUG_DB_READ        512
#define DEBUG_DB_WRITE       1024
#define DEBUG_SQL_TEXT       2048
#define DEBUG_MSG_CONTENTS   4096

Questo sistema di registrazione viene fornito con la build release , attivata e salvata su file per impostazione predefinita. È troppo tardi per scoprire che dovresti aver effettuato la registrazione DOPO che il bug si è verificato, se quel bug si verifica solo una volta ogni sei mesi in media e non hai modo di riprodurlo. La registrazione che funziona solo con le build di debug è giusta. pianura. muto.

Il software in genere viene fornito con ERRORE, BASIC, STATE_CHANGE ed EXCEPTION attivati, ma può essere modificato nel campo tramite la finestra di dialogo debug (o un'impostazione di registro / ini / cfg, dove tali elementi vengono salvati).

Oh e una cosa: il mio sistema di debug genera un file al giorno. I tuoi requisiti potrebbero essere diversi. Ma assicurati che il tuo codice di debug inizi con ogni file con la data, la versione del codice che stai utilizzando e, se possibile, qualche indicatore per l'ID cliente, la posizione del sistema o altro. Puoi ottenere una mistura di file di registro che arrivano dal campo e hai bisogno di un registro di ciò che è venuto da dove e di quale versione del sistema stavano girando che è effettivamente nei dati stessi, e non puoi fidarti del cliente / Field Engineer per dirti quale versione hanno - potrebbero solo dirti quale versione PENSANO che hanno. Peggio ancora, potrebbero riportare la versione exe presente sul disco, ma la vecchia versione è ancora in esecuzione perché hanno dimenticato di riavviarsi dopo la sostituzione. Chiedi al tuo codice di darti.

Infine, non vuoi che il tuo codice generi i suoi problemi, quindi metti una funzione timer per eliminare i file di log dopo tanti giorni o settimane (basta controllare la differenza tra ora e ora della creazione del file). Questo è OK per un'app server che viene eseguita in qualsiasi momento, su un'app client che è possibile eliminare eliminando i vecchi dati all'avvio. Normalmente, dopo circa 30 giorni di interruzione, su un sistema senza frequenti visite di un ingegnere, dovremmo lasciarlo più a lungo. Ovviamente questo dipende anche dalla dimensione dei tuoi file di registro.

    
risposta data 06.10.2011 - 00:42
fonte
11

Registra l'eccezione solo una volta!

Uno dei punti dolenti più comuni che ho notato è il logging e il risveglio di un'eccezione. Di conseguenza, i file di registro contengono le stesse eccezioni più volte su diversi livelli di stack.

    
risposta data 05.10.2011 - 19:44
fonte
5

Ecco un anti-pattern: creare due dozzine di campi "genericavariabili" in una tabella di database per tracciare tutto ciò che è concepibile e avere 88 (e contare) valori di enumerazione diversi per diversi tipi di log.

    
risposta data 05.10.2011 - 19:08
fonte
4

La mia esperienza con i log è tanto più grande quanto migliore, ma è abbastanza coerente da renderlo filtrabile per macchina ed è possibile configurare un livello di gravità per ogni componente della singola applicazione.

Inoltre, è molto difficile prevedere quale registro sarà necessario per trovare un bug futuro. La maggior parte dei luoghi ovvi da registrare per i bug vengono risolti prima che il prodotto vada fuori dalla porta. Non è raro che il risultato di una segnalazione di bug sia che hai appena aggiunto la registrazione per diagnosticare se succede di nuovo.

    
risposta data 05.10.2011 - 00:51
fonte
2

Un paio di note dal lato operazioni della casa qui:

1) Assicurarsi che i registri siano configurabili localmente, preferibilmente con uno strumento non più pesante di un editor di testo. La maggior parte delle volte non vogliamo ottenere il logging di livello TRACE, ma ci piace poterlo attivare.

2) Se possibile, assicurati che i registri possano essere letti con uno strumento non più pesante di un editor di testo. Niente è peggio di dover andare a caccia di strumenti in un'ora strana quando il sistema di produzione sta fallendo.

    
risposta data 06.10.2011 - 01:14
fonte
1

Dalla mia esperienza personale di lavoro con le applicazioni web:

(e considerando che lo spazio di archiviazione è molto economico ora)

  • Accedi quante più informazioni disponibili (in quel momento) possibile.
  • Includo sempre DateTime.Now nelle mie stringhe di registro.
  • Io sempre (se è possibile) log tempo-durata di qualche specifica "azione".
  • Sii coerente con le tue stringhe di log. Da sempre uso questo tipo di schema:

    • "[Info X] [Info Y] [Info Z] [etc.]"
risposta data 05.10.2011 - 09:49
fonte
1

Oltre allo stacktrace, registra lo stato dell'applicazione corrente e l'input.

Il software è deterministico, questi due sono di solito l'unica cosa di cui hai bisogno per riprodurre il bug. Memorizzare lo stato completo potrebbe in alcuni casi essere fastidioso, quindi anche i modi per riprodurre lo stato corrente, ad esempio gli input precedenti, sono buoni.

Ovviamente più dati sono sempre migliori ma almeno questi due sono un buon inizio per i crash più facili.

    
risposta data 05.10.2011 - 21:38
fonte

Leggi altre domande sui tag