2012-11-11 11 views
23

Sto usando Sentry (in un progetto django) e mi piacerebbe sapere come posso ottenere correttamente gli errori da aggregare. Sto registrando alcune azioni dell'utente come errori, quindi non esiste un'eccezione di sistema sottostante e sto utilizzando l'attributo culprit per impostare un nome di errore descrittivo. Il messaggio è basato su un modello e contiene un messaggio comune ("Utente 'x' non è stato in grado di eseguire azioni perché 'y'"), ma non è mai esattamente lo stesso (utenti diversi, condizioni diverse).In che modo Sentry aggrega gli errori?

Sentry utilizza chiaramente alcuni set di attributi sotto il cofano per determinare se aggregare gli errori come la stessa eccezione, ma nonostante abbia esaminato il codice, non riesco a capire come.

Qualcuno può cortocircuitare il mio dover scavare ulteriormente nel codice e dirmi quali proprietà devo impostare per gestire l'aggregazione come vorrei?

[UPDATE 1: raggruppamento evento]

Questa linea appare in sentry.models.Group:

class Group(MessageBase): 
    """ 
    Aggregated message which summarizes a set of Events. 
    """ 
    ... 

    class Meta: 
     unique_together = (('project', 'logger', 'culprit', 'checksum'),) 
    ... 

che ha un senso - del progetto, logger e colpevole io pongo in questo momento - il problema è checksum. Analizzerò ulteriormente, tuttavia il "checksum" suggerisce che l'equivalenza binaria, che non funzionerà mai, deve essere possibile raggruppare le istanze della stessa eccezione, con attributi diversi?

[UPDATE 2: checksum evento]

Il checksum evento nasce dal metodo sentry.manager.get_checksum_from_event:

def get_checksum_from_event(event): 
    for interface in event.interfaces.itervalues(): 
     result = interface.get_hash() 
     if result: 
      hash = hashlib.md5() 
      for r in result: 
       hash.update(to_string(r)) 
      return hash.hexdigest() 
    return hashlib.md5(to_string(event.message)).hexdigest() 

tappa successiva - in cui fanno l'evento interfaces viene?

[UPDATE 3: interfacce evento]

ho lavorato che interfaces riferiscono al meccanismo standard per la descrizione dei dati passati in eventi sentinella, e che sto utilizzando lo standard sentry.interfaces.Message e sentry.interfaces.User interfacce.

Entrambe conterranno dati diversi a seconda dell'istanza di eccezione, pertanto un checksum non corrisponderà mai. Esiste un modo per escluderli dal calcolo del checksum? (O almeno il valore User di interfaccia, come quella deve essere diverso - il valore Message interfaccia di I potuto standardizzare.)

[AGGIORNAMENTO 4: soluzione]

Ecco i due get_hash funzioni per la Message e User interfacce rispettivamente:

# sentry.interfaces.Message 
def get_hash(self): 
    return [self.message] 

# sentry.interfaces.User 
def get_hash(self): 
    return [] 

Guardando questi due, solo l'interfaccia Message.get_hash restituirà un valore che viene prelevato dal metodo get_checksum_for_event, e quindi questo è quello che verrà restituito (hash ecc) Th L'effetto netto di questo è che il checksum viene valutato solo sul messaggio, il che in teoria significa che posso standardizzare il messaggio e mantenere la definizione dell'utente unica.

Ho risposto alla mia domanda qui, ma spero che la mia indagine sia utile agli altri che hanno lo stesso problema.(Per inciso, ho anche inviato una richiesta di pull contro la documentazione di Sentry come parte di questo ;-))

(Nota per chiunque usi/estendi Sentry con interfacce personalizzate - se si desidera evitare l'interfaccia utilizzare per raggruppare le eccezioni, restituire una lista vuota.)

+0

Attenzione! Sovrascrivere get_hash potrebbe essere eccessivo. 'Sentry raggrupperà i messaggi in modo intelligente se utilizzi la corretta formattazione delle stringhe. Potrebbe essere il tuo caso solo per formattare correttamente gli errori https://docs.getsentry.com/hosted/clients/python/integrations/logging/ – andi

risposta

17

Vedere il mio aggiornamento finale nella domanda stessa. Gli eventi sono aggregati su una combinazione di proprietà "progetto", "logger", "colpevole" e "checksum". I primi tre di questi sono relativamente facili da controllare: il quarto, 'checksum' è una funzione del tipo di dati inviati come parte dell'evento.

Sentry utilizza il concetto di "interfacce" per controllare la struttura dei dati inoltrati e ogni interfaccia viene fornita con un'implementazione di get_hash, che viene utilizzata per restituire un valore hash per i dati inoltrati. Sentry viene fornito con un numero di interfacce standard ("Messaggio", "Utente", "HTTP", "Stacktrace", "Query", "Eccezione"), ognuna delle quali ha una propria implementazione di get_hash. L'impostazione predefinita (ereditata dalla classe di base dell'interfaccia) è una lista vuota, che non influisce sul checksum.

In assenza di interfacce valide, il messaggio di evento stesso viene sottoposto a hash e restituito come checksum, il che significa che il messaggio deve essere univoco per l'evento da raggruppare.

+1

Su http: // raven.readthedocs.org/en/latest/config/logging.html#usage dice "Sentry raggruppa i messaggi in modo intelligente se si utilizza la corretta formattazione delle stringhe". con un esempio in cui il formato della stringa del messaggio di registro rimane lo stesso e gli argomenti variano. In che modo questo si riferisce al meccanismo del checksum? – akaihola

+0

@akaihola - Non ne ho idea. Osservando il codice stesso, il metodo 'Message.get_hash()' restituisce il messaggio stesso - che è la post-formattazione. –

+2

@ HugoRodger-Brown @akaihola Credo che l'interfaccia 'sentry.interfaces.Message' abbia le proprietà' message' e 'params' e che il messaggio sia pre-formattato. vedi [qui] (http://sentry.readthedocs.org/en/latest/developer/interfaces/index.html#sentry.interfaces.Message) per i dettagli – Nick

0

Ho avuto un problema comune con Eccezioni. Attualmente il nostro sistema sta catturando solo eccezioni e sono stato confuso perché alcune di queste sono state unite in un singolo errore, altre no. Con le tue informazioni sopra ho rimosso i metodi "get_hash" e ho cercato di trovare le differenze "aumentando" i miei errori. Quello che ho scoperto è che tutti gli errori raggruppati provenivano da un tipo di eccezione autodidatta che ha un valore di Exception.message vuoto.

uscita get_hash:

[<class 'StorageException'>, StorageException()] 

e le molteplici errori proveniva da una classe di eccezione che ha un valore di messaggio pieno (template engine Jinja)

[<class 'jinja2.exceptions.UndefinedError'>, UndefinedError('dict object has no attribute LISTza_*XYZ*',)] 

Diversi messaggi di eccezione innescano diversi rapporti, a mio caso l'unione è stata causata a causa della mancanza del valore Exception.message.

Implementazione:

class StorageException(Exception): 

def __init__(self, value): 
    Exception.__init__(self) 
    self.value = value 
Problemi correlati