logs framework errores bugs django sentry

django - framework - ¿Cómo se agregan los errores de Sentry?



sentry server logs (2)

Estoy usando Sentry (en un proyecto django), y me gustaría saber cómo puedo obtener los errores para agregarlos correctamente. Estoy registrando ciertas acciones del usuario como errores, por lo que no hay una excepción del sistema subyacente, y estoy usando el atributo culprit para establecer un nombre de error amigable. El mensaje tiene una plantilla y contiene un mensaje común ("El usuario ''x'' no pudo realizar la acción porque ''y''"), pero nunca es exactamente el mismo (diferentes usuarios, diferentes condiciones).

Sentry claramente usa un conjunto de atributos bajo el capó para determinar si agregar errores como la misma excepción, pero a pesar de haber revisado el código, no puedo entender cómo.

¿Puede alguien reducir mi necesidad de profundizar en el código y decirme qué propiedades debo configurar para administrar la agregación como me gustaría?

[ACTUALIZACIÓN 1: agrupación de eventos]

Esta línea aparece en sentry.models.Group:

class Group(MessageBase): """ Aggregated message which summarizes a set of Events. """ ... class Meta: unique_together = ((''project'', ''logger'', ''culprit'', ''checksum''),) ...

Lo que tiene sentido: el proyecto, el registrador y el culpable que estoy configurando en este momento, el problema es la checksum . Seguiré investigando, sin embargo, ''checksum'' sugiere que la equivalencia binaria, que nunca va a funcionar, ¿debe ser posible agrupar instancias de la misma excepción, con diferentes atributos?

[ACTUALIZACIÓN 2: sumas de comprobación de eventos]

La suma de comprobación del evento proviene del método 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()

Próxima parada: ¿de dónde provienen las interfaces eventos?

[ACTUALIZACIÓN 3: interfaces de eventos]

He descubierto que las interfaces refieren al mecanismo estándar para describir los datos transmitidos a eventos de centinela, y que estoy usando las interfaces sentry.interfaces.Message y sentry.interfaces.User estándar.

Ambos contendrán datos diferentes según la instancia de excepción, por lo que una suma de comprobación nunca coincidirá. ¿Hay alguna forma en que pueda excluirlos del cálculo de suma de comprobación? (O al menos el valor de la interfaz de User , ya que tiene que ser diferente: el valor de la interfaz de Message que podría estandarizar).

[ACTUALIZACIÓN 4: solución]

Aquí están las dos funciones get_hash para las interfaces de Message y User respectivamente:

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

En cuanto a estos dos, solo la interfaz Message.get_hash devolverá un valor que es recogido por el método get_checksum_for_event , por lo que este es el que se devolverá (con hash, etc.) El efecto neto de esto es que la suma de comprobación es evaluado solo en el mensaje, lo que en teoría significa que puedo estandarizar el mensaje y mantener la definición del usuario única.

He respondido mi propia pregunta aquí, pero espero que mi investigación sea de utilidad para otras personas que tengan el mismo problema. (Como parte aparte, también he enviado una solicitud de extracción contra la documentación de Sentry como parte de esto ;-))

(Nota para cualquier persona que use / extienda Sentry con interfaces personalizadas: si desea evitar que su interfaz se use para agrupar excepciones, devuelva una lista vacía).


He tenido un problema común con las excepciones. Actualmente nuestro sistema está capturando solo excepciones y estaba confundido por qué algunos de estos se fusionaron en un solo error, otros no. Con su información anterior, extraje los métodos "get_hash" e intenté encontrar las diferencias "elevando" mis errores. Lo que descubrí es que todos los errores agrupados provienen de un tipo de excepción autoescrito que tiene un valor de mensaje de excepción vacío.

Salida get_hash:

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

y los múltiples errores provienen de una clase de excepción que tiene un valor de mensaje completado (motor de plantillas jinja)

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

Diferentes mensajes de excepción activan diferentes informes, en mi caso, la fusión se debió a la falta del valor Exception.message.

Implementación:

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


Ver mi actualización final en la pregunta en sí. Los eventos se agregan en una combinación de propiedades de ''proyecto'', ''registrador'', ''culpable'' y ''suma de comprobación''. Los tres primeros son relativamente fáciles de controlar; el cuarto, ''checksum'' es una función del tipo de datos enviados como parte del evento.

Sentry usa el concepto de ''interfaces'' para controlar la estructura de los datos pasados, y cada interfaz viene con una implementación de get_hash , que se usa para devolver un valor hash para los datos pasados. Sentry viene con una serie de interfaces estándar ( ''Message'', ''User'', ''HTTP'', ''Stacktrace'', ''Query'', ''Exception''), y cada uno tiene su propia implementación de get_hash . El valor predeterminado (heredado de la clase base de la interfaz) es una lista vacía, que no afectaría la suma de comprobación.

En ausencia de interfaces válidas, el mensaje del evento se revisa y se devuelve como suma de comprobación, lo que significa que el mensaje debe ser único para que el evento se agrupe.