2012-11-11 35 views
23

Używam Sentry (w projekcie django) i chciałbym wiedzieć, w jaki sposób mogę uzyskać poprawne zagregowanie błędów. Rejestruję określone działania użytkowników jako błędy, więc nie ma żadnego wyjątku systemowego i używam atrybutu culprit do ustawienia przyjaznej nazwy błędu. Wiadomość jest szablonem i zawiera wspólny komunikat ("Użytkownik x" nie mógł wykonać akcji z powodu "y"), ale nigdy nie jest dokładnie taki sam (różni użytkownicy, różne warunki).W jaki sposób Sentry agreguje błędy?

Sentry wyraźnie używa jakiś zestaw atrybutów pod maską, aby określić, czy łączyć błędy jak samego wyjątku, ale mimo przejrzałem kodu, nie mogę dowiedzieć się, jak.

Może ktoś krótko obciąć konieczności kopać dalej do kodu i powiedz mi, jakie właściwości muszę ustawić w celu zarządzania agregację jak pragnę?

[UPDATE 1: grupowanie zdarzeń]

Linia ta pojawia się w sentry.models.Group:

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

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

Jaki sens - projekt, rejestrator i sprawcę ja ustawiania w tej chwili - problem to checksum. Zbadam dalej, jednak "suma kontrolna" sugeruje równoważność binarną, która nigdy nie zadziała - musi być możliwe grupowanie wystąpień tego samego wyjątku, z atrybutami różnicowania?

[Aktualizacja 2: kontrolne event]

kontrolna zdarzenie pochodzi od sposobu 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() 

Następny przystanek - gdzie zrobić imprezę interfaces pochodzi?

[3 UPDATE: interfejsy event]

Pracowałem że interfaces odnoszą się do standardowego mechanizmu opisujące dane przekazane do posterunku wydarzeń, a że używam standardowe sentry.interfaces.Message i sentry.interfaces.User interfejsów.

Oba te elementy zawierają różne dane w zależności od wystąpienia wyjątku - i dlatego suma kontrolna nigdy nie będzie zgodna. Czy jest jakiś sposób, że mogę je wykluczyć z obliczania sumy kontrolnej? (Lub przynajmniej wartość User interfejs, a który musi być różny - wartość Message interfejs mogę standaryzacji).

[Aktualizacja 4: Roztwór]

Oto dwa get_hash funkcji do Message i User interfejsy odpowiednio:

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

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

patrząc na te dwa, tylko interfejs Message.get_hash powróci do wartości, które są odbierane przez sposobu get_checksum_for_event, a więc jest to taki, który jest zwrócony (słupek itd.), H Skutkiem tego jest to, że suma kontrolna jest oceniana tylko na samym komunikacie - co teoretycznie oznacza, że ​​mogę standaryzować wiadomość i zachować unikalną definicję użytkownika.

Odpowiedziałem na własne pytanie tutaj, ale mam nadzieję, że moje dochodzenie jest przydatne dla innych mających ten sam problem.(Na marginesie, wysłałem również żądanie ściągnięcia przeciwko dokumentacji Sentry jako część tego ;-))

(Uwaga dla każdego, kto używa/rozszerza Sentry z niestandardowymi interfejsami - jeśli chcesz uniknąć interfejsu użyj do zgrupowania wyjątków, zwróć pustą listę.)

+0

Ostrzeżenie! Zastąpienie get_hash może być przesadą. 'Sentry inteligentnie pogrupuje wiadomości, jeśli użyjesz odpowiedniego formatowania napisów. Więc może to być twój przypadek tylko po to, aby poprawnie formatować błędy https://docs.getsentry.com/hosted/clients/python/integrations/logging/ – andi

Odpowiedz

17

Zobacz moją ostateczną aktualizację samego pytania. Zdarzenia są agregowane na podstawie kombinacji właściwości "projektu", "rejestratora", "sprawcy" i "sumy kontrolnej". Pierwsze trzy z nich są stosunkowo łatwe do kontrolowania - czwarta "suma kontrolna" jest funkcją rodzaju danych wysyłanych jako część zdarzenia.

Sentry wykorzystuje koncepcję "interfejsów" do kontrolowania struktury przekazywanych danych, a każdy interfejs jest dostarczany z implementacją get_hash, która jest używana do zwracania wartości mieszania dla przekazywanych danych. Sentry pochodzi z liczbą standardowych interfejsów ("Message", "User", "HTTP", "Stacktrace", "Query", "Exception"), a każda z nich ma własną implementację get_hash. Wartością domyślną (odziedziczoną z klasy bazowej interfejsu) jest pusta lista, która nie ma wpływu na sumę kontrolną.

W przypadku braku jakichkolwiek ważnych interfejsów wiadomość o zdarzeniu jest mieszana i zwracana jako suma kontrolna, co oznacza, że ​​wiadomość musi być unikatowa, aby zdarzenie mogło zostać zgrupowane.

+1

Na http: // raven.readthedocs.org/en/latest/config/logging.html#usage mówi: "Sentry inteligentnie pogrupuje wiadomości, jeśli użyjesz odpowiedniego formatowania napisów." z przykładem, w którym format ciągu wiadomości dziennika pozostaje taki sam, a argumenty są różne. Jak to się ma do mechanizmu sum kontrolnych? – akaihola

+0

@akaihola - Nie mam pojęcia. Patrząc na sam kod, metoda 'Message.get_hash()' zwraca samą wiadomość - czyli postformatowanie. –

+2

@ HugoRodger-Brown @akaihola Uważam, że interfejs 'sentry.interfaces.Message' ma właściwości' message' i 'params' oraz że wiadomość jest wstępnie sformatowana. zobacz [tutaj] (http://sentry.readthedocs.org/en/latest/developer/interfaces/index.html#sentry.interfaces.Message), aby poznać szczegóły. – Nick

0

Mam wspólny problem z wyjątkami. Obecnie nasz system przechwytuje tylko wyjątki i byłem zdezorientowany, dlaczego niektóre z nich zostały scalone w jeden błąd, a inne nie. W powyższej informacji poznałem metody "get_hash" i próbowałem znaleźć różnice "podnosząc" moje błędy. Odkryłem, że zgrupowane błędy pochodzą wyłącznie z napisanego przez siebie typu wyjątku, który ma pustą wartość Exception.message.

wyjście get_hash:

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

i wielokrotne błędy pochodził z klasy wyjątków, które ma wypełniony wartość tekstową (jinja szablon silnika)

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

różne komunikaty wyjątków wywołać różne raporty, w moim przypadku, gdy scalenie zostało spowodowane z powodu braku wartości Exception.message.

Realizacja:

class StorageException(Exception): 

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