Strategie per analizzare le eccezioni raccolte

4

Vogliamo aggiungere un feedback di errore alla nostra applicazione. Ho dato un'occhiata alle soluzioni esistenti (ad esempio raygun.io), ma queste funzionano "nel cloud", che è un no-go per noi:

  • la maggior parte delle installazioni della nostra applicazione sono offline, quindi sarà necessario esportare i registri raccolti in un file e quindi inviarli via email.
  • Non mi sento a mio agio nel caricare i dettagli delle eccezioni su un server di terze parti a causa di problemi di privacy. (alcuni dei nostri clienti probabilmente ci ucciderebbero).

Ora, la sola registrazione di queste eccezioni non è difficile. Ho collegato i gestori a AppDomain.UnhandledException e AppDomain.FirstChanceException e poi li ho scritti su un piccolo DB SQLite.

Ma la domanda per me è come analizzarli al meglio. Analizzarli a mano costerebbe troppo tempo, quindi dobbiamo almeno essere in grado di raggrupparli in "bucket" e ordinarli in base al numero di occorrenze, ecc.

Ho alcune idee in mente dove confronto i callstack e i messaggi, ecc., ma mi sento come se qualcun altro DEVE aver già fatto lo stesso.

Conosci delle buone strategie per classificare le eccezioni e raggrupparle?

    
posta Lukas Rieger 19.06.2015 - 20:29
fonte

2 risposte

3

Raccolta di eccezioni

Quando raccogli le eccezioni, fai attenzione con due cose:

  • Che cosa succederà se si verifica un'eccezione e, durante la segnalazione, il meccanismo di segnalazione genera un'altra eccezione?

    Il caso peggiore è iniziare a segnalare la nuova eccezione, che potrebbe innescarne una nuova, con conseguente migliaia di nuove eccezioni generate in un ciclo. Devi assolutamente evitarlo.

  • Che cosa succede se non riesci a segnalare un'eccezione?

    L'invio di un'eccezione a un server potrebbe non riuscire perché il server non risponde. L'archiviazione di un'eccezione in Eventi di Windows potrebbe non riuscire a causa della mancanza di autorizzazioni. Il salvataggio dell'eccezione in un database locale potrebbe non riuscire perché il database è, per qualche motivo, inattivo. Anche accodare l'eccezione a un file di testo può essere problematico: potresti semplicemente avere esaurito lo spazio o mancare le autorizzazioni.

    Di solito, devi avere due o tre modi per registrare le eccezioni, facendo un fallback da quello che non è riuscito a quello che dovrebbe essere più affidabile (ad esempio, segnala a un server, database, file di testo semplice).

    È essenziale, una volta risolto il problema originale che impediva la corretta registrazione delle eccezioni, di essere in grado di recuperare le eccezioni da tutte quelle fonti e di analizzarle attentamente. Ad esempio, come raccogli le eccezioni che sono state memorizzate in un file di testo quando sia la rete che il database erano inattivi?

Quando si tratta di dati sensibili, assicurati di crittografare le eccezioni quando li invii a un server di terze parti (o anche ai tuoi server), al fine di impedire l'accesso allo stack trace a persone non autorizzate. Assicurati che gli sviluppatori non includano mai informazioni riservate nei messaggi delle eccezioni . Ad esempio, AccessDeniedException non dovrebbe avere come messaggio:

Failed to authenticate the user John: the password "sihjdfogdhf" is invalid.

Tra le informazioni che raccogli, assicurati di avere:

  • La versione esatta dell'applicazione. Se non hai la versione, il debug di un'eccezione può diventare rapidamente un incubo.

  • Le informazioni sull'ambiente. Un'applicazione che genera un'eccezione su Windows XP non necessariamente la proietterà su Windows 8.1. Un'applicazione che genera un'eccezione con il sistema FAT32 può funzionare correttamente con NTFS. Un'applicazione può comportarsi in modo strano perché è rimasto meno di 1 MB di spazio su disco, o perché la RAM è piena e il sistema operativo deve scambiare tutto, con conseguente rallentamento dei tassi di risposta e molte eccezioni di timeout.

  • Qualcosa che identifica il cliente (se appropriato). Ciò rende possibile contattare il cliente per chiedere ulteriori informazioni.

Analisi delle eccezioni

Il passo più importante è deduplicare le informazioni sulle eccezioni raccolte. Molte eccezioni saranno simili, ma non identiche: è fondamentale identificare quanto sono vicine e raggrupparle. L'obiettivo è quello di essere in grado di concentrarsi sulle eccezioni più frequenti: se si dispone di un'eccezione che ha interessato due volte un utente nell'ultimo anno e un'eccezione che ha interessato migliaia di utenti migliaia di volte per lo stesso periodo di tempo, la la prima eccezione potrebbe non essere la tua priorità assoluta.

Probabilmente non otterrai il raggruppamento da zero; invece, studia le eccezioni che hai già raccolto, prova un approccio di raggruppamento e vedi come funziona, quindi modificalo finché non ottieni ciò di cui hai bisogno. Il raggruppamento è complicato, perché non ci sono praticamente duplicati assoluti e perché il divario tra ciò che lo rende duplicato e ciò che non lo è è sfocato.

Ad esempio:

  • Se ricevi due AccessDeniedException s segnalati al pulsante della finestra di login OnClick evento, uno relativo a John, un altro a Mary, quelli possono essere raggruppati, nonostante le diverse stringhe di messaggi.

  • D'altra parte, potrebbe esserci un'altra AccessDeniedException riguardante Mary, che accade da qualche altra parte nell'applicazione, e che non dovrebbe essere raggruppata con i primi due.

  • Ora c'è una AccessDeniedException generata da una diversa revisione della tua app: la traccia dello stack è diversa, ma l'eccezione è sempre la stessa delle prime due.

  • ecc.

Durante il raggruppamento, assicurati di conservare anche le singole informazioni. Ad esempio, il report potrebbe indicare che c'erano 94% diAccessDeniedException s lanciati per il giorno passato per gli utenti John, Mary e altri 14 nelle versioni 4.0.17 e 4.0.18 con le tracce dello stack fornite dai clienti 1, 2, 3 e 4.

    
risposta data 21.06.2015 - 20:04
fonte
0

Non ho una soluzione dettagliata per questo, ma il mio approccio sarebbe quello di creare sottoclassi di le eccezioni catturate e memorizzate + analizzano e implementano alcune informazioni sul tipo di eccezione.

public enum ExceptionDanger
{
    Low,
    Middle,
    SecurityCritical
    // And so on
}

Ora aggiungiamo questo alla classe di eccezione derivata:

public class MonitoredException : Exception
{
    public readonly ExceptionDanger danger;

    public MonitoredException(string message, ExceptionDanger danger)
        : base(message)
    {
        danger = danger;
    }
}

E nel sottoscrittore dell'evento AppDomain.FirstChanceException utilizziamo le informazioni per creare una nuova informazione di registro (uguale per AppDomain.UnhandledException ):

static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
{
    var monitoredException = e.Exception as MonitoredException;
    if(monitoredException != null)
    {
        var exDanger = monitoredException.danger;
        var exType = monitoredException.GetType().Name;
        var exTimestamp = DateTime.Now;

        // Build a package like a struct or so and exDanger, exType and exTimestamp to it
    }
}

Ora quando il server riceve il pacchetto (che consiste in exDanger ed exType) i dati possono essere utilizzati per memorizzare quanti errori di questo tipo sono stati lanciati e se si aggiunge un ID utente al pacchetto è possibile specificare quali utenti hanno lanciato le eccezioni. L'enum ExceptionDanger consiste nell'ordinare l'importanza dell'eccezione lato server.

Spero che questo ti abbia dato consigli o almeno un'idea su come ordinare e analizzare le eccezioni.

    
risposta data 21.06.2015 - 14:45
fonte

Leggi altre domande sui tag