Architettura multilivello: dove dovrei implementare la registrazione degli errori \ gestione?

13

Attualmente sto rifattorizzando un sottosistema di grandi dimensioni con un'architettura a più livelli e sto tentando di progettare un efficace registro degli errori \ strategia di gestione.

Diciamo che la mia architettura è composta dai seguenti tre livelli:

  • Interfaccia pubblica (I.E un controller MVC)
  • Domain Layer
  • Livello di accesso ai dati

La mia fonte di confusione è dove dovrei implementare la registrazione degli errori \ handling:

  1. La soluzione più semplice sarebbe implementare la registrazione al livello più alto (I.E l'interfaccia pubblica \ Controller MVC). Tuttavia questo sembra sbagliato perché significa far ribollire l'eccezione attraverso i diversi livelli e quindi registrarlo; piuttosto che registrare l'eccezione alla fonte.

  2. Registrare l'eccezione alla fonte è ovviamente la soluzione migliore perché ho più informazioni. Il mio problema con questo è che non riesco a catturare tutte le eccezioni alla fonte senza catturare TUTTE le eccezioni, e nel livello di dominio / interfaccia pubblica, questo porterà a catturare le eccezioni che sono già state catturate, registrate e ri-generate dal livello sottostante .

  3. Un'altra possibile strategia è un mix di # 1 e # 2; per cui rilevo eccezioni specifiche al livello che è più probabile che vengano lanciate (I.E Catching, logging e re-throwing SqlExceptions nel livello di accesso ai dati) e quindi registra eventuali ulteriori eccezioni non rilevate al livello più alto. Tuttavia, ciò richiede anche che io rileggi e rilogassi tutte le eccezioni al livello superiore, perché non riesco a distinguere tra errori che sono già stati registrati \ gestiti rispetto a quelli che non lo sono stati.

Ora, ovviamente questo è un problema nella maggior parte delle applicazioni software, quindi ci deve essere una soluzione standard a questo problema che si traduce in eccezioni catturate all'origine e registrate una volta; tuttavia non riesco a vedere come farlo da solo.

Nota, il titolo di questa domanda è molto simile a " Registrazione delle eccezioni in un'applicazione multilivello "", tuttavia le risposte in questo post mancano di dettagli e non sono sufficienti per rispondere alla mia domanda.

    
posta KidCode 22.10.2017 - 22:19
fonte

2 risposte

13

Per le tue domande:

The easiest solution would be to implement the logging at the top level

Avere l'eccezione fino al livello più alto è un approccio assolutamente corretto e plausibile. Nessuno dei metodi di livello superiore tenta di continuare un processo dopo l'errore, che in genere non può avere esito positivo. E un'eccezione ben equipaggiata contiene tutte le informazioni necessarie per la registrazione. E non fare nulla sulle eccezioni ti aiuta a mantenere il tuo codice pulito e focalizzato sull'attività principale invece che sugli errori.

Logging the exception at it's source is obviously the best solution because I have the most information.

Questo è per metà corretto. Sì, la maggior parte delle informazioni utili sono disponibili qui. Ma raccomanderei di mettere tutto questo nell'oggetto eccezione (se non è già lì) invece di loggarlo immediatamente. Se si accede a un livello basso, è comunque necessario generare un'eccezione per comunicare ai chiamanti che non è stato completato il lavoro. Questo finisce in più registri dello stesso evento.

Eccezioni

La mia linea guida principale è catturare e registrare le eccezioni solo al livello più alto. E tutti gli strati sottostanti dovrebbero assicurarsi che tutte le informazioni necessarie sull'errore vengano trasportate fino al livello più alto. All'interno di un'applicazione a processo singolo, ad es. in Java, ciò significa principalmente non provare / catturare o registrare tutto al di fuori del livello più alto.

A volte, desideri includere alcune informazioni di contesto nel log delle eccezioni che non sono disponibili nell'eccezione originale, ad es. l'istruzione SQL ei parametri che sono stati eseguiti quando è stata generata l'eccezione. Quindi puoi catturare l'eccezione originale e rilanciarne una nuova, contenente quella originale più il contesto.

Naturalmente, la vita reale a volte interferisce:

  • In Java, a volte devi catturare un'eccezione e avvolgerla in un tipo di eccezione diverso solo per obbedire ad alcune firme di metodo fisse. Ma se rilanciate un'eccezione, assicuratevi che la nuova generazione contenga tutte le informazioni necessarie per la registrazione successiva.

  • Se si attraversa un confine tra processi, spesso tecnicamente non è possibile trasferire l'oggetto di eccezione completo inclusa la traccia dello stack. E naturalmente la connessione potrebbe perdersi. Quindi, ecco un punto in cui un servizio dovrebbe registrare le eccezioni e quindi fare del suo meglio per trasmettere il maggior numero possibile di informazioni di errore sulla linea al proprio client. Il servizio deve assicurarsi che il client riceva un avviso di errore, ricevendo una risposta di errore o eseguendo un timeout in caso di connessione interrotta. In genere, lo stesso errore viene registrato due volte, una volta all'interno del servizio (con maggiori dettagli) e una volta nel livello superiore del client.

Accesso

Sto aggiungendo alcune frasi sul logging in generale, non solo sulla registrazione delle eccezioni.

Oltre alle situazioni eccezionali, desideri anche che attività importanti della tua applicazione vengano registrate nel registro. Quindi, usa un framework di registrazione.

Prestare attenzione ai livelli di log (la lettura dei registri in cui le informazioni di debug e gli errori gravi non sono contrassegnati con diversi di conseguenza è un problema!). I livelli di registro tipici sono:

  • ERRORE: alcune funzioni sono fallite in modo irrecuperabile. Ciò non significa necessariamente che l'intero programma si è bloccato, ma alcune attività non possono essere completate. In genere, si dispone di un oggetto di eccezione che descrive l'errore.
  • AVVISO: è successo qualcosa di strano, ma non ha causato il fallimento di alcuna attività (configurazione strana rilevata, interruzione temporanea della connessione che ha causato alcuni tentativi, ecc.)
  • INFO: Vuoi comunicare alcune azioni significative del programma all'amministratore di sistema locale (iniziando un servizio con la sua configurazione e versione del software, importando i file di dati nel database, gli utenti che accedono al sistema, hai l'idea ...) .
  • DEBUG: cose che lo sviluppatore vuole vedere quando si esegue il debug di alcuni problemi (ma non si saprà mai in anticipo di cosa si ha realmente bisogno in caso di questo o di quel bug specifico - se è possibile prevederlo, si correggi il bug). Una cosa che è sempre utile è registrare le attività su interfacce esterne.

In produzione, imposta il livello del registro su INFO. I risultati dovrebbero essere utili a un amministratore di sistema in modo che sappia cosa sta succedendo. Aspettati che ti chiami per assistenza o correzione dei bug per ogni ERRORE nel registro e metà degli AVVISI.

Abilita il livello DEBUG solo durante le sessioni di debug reale.

Raggruppa le voci di registro in categorie appropriate (ad es. con il nome classe completo del codice che genera la voce), consentendo di attivare i registri di debug per parti specifiche del tuo programma.

    
risposta data 23.10.2017 - 15:34
fonte
-1

Mi sto preparando per i downvotes, ma ho intenzione di uscire su un arto e dire che non sono sicuro di essere d'accordo con questo.

Borbolare le eccezioni, molto meno la registrazione di nuovo, è uno sforzo extra con poco beneficio. Catch l'eccezione all'origine (sì, più semplice), loggala, ma poi non rilanciare l'eccezione, basta segnalare "error" al chiamante. "-1", null, stringa vuota, qualche enum, qualunque cosa. Il chiamante deve solo sapere che la chiamata è fallita, quasi mai i dettagli raccapriccianti. E quelli saranno nel tuo registro, giusto? Nel raro caso in cui il chiamante abbia bisogno dei dettagli, vai avanti e fai un salto di qualità, ma non come predefinito automatico non pensante.

    
risposta data 26.04.2018 - 23:48
fonte

Leggi altre domande sui tag