def message_v1(message_interface: Message, context: GroupingContext, **meta: Any) -> ReturnedVariants: if context["trim_message"]: message_in = message_interface.message or message_interface.formatted or "" message_trimmed = trim_message_for_grouping(message_in) hint = "stripped common values" if message_in != message_trimmed else None return { context["variant"]: GroupingComponent( id="message", values=[message_trimmed], hint=hint, similarity_encoder=text_shingle_encoder(5), ) } else: return { context["variant"]: GroupingComponent( id="message", values=[ message_interface.message or message_interface.formatted or "" ], similarity_encoder=text_shingle_encoder(5), ) }
def single_exception_legacy(exception, context, **meta): type_component = GroupingComponent( id="type", values=[exception.type] if exception.type else [], similarity_encoder=ident_encoder, contributes=False, ) value_component = GroupingComponent( id="value", values=[exception.value] if exception.value else [], similarity_encoder=text_shingle_encoder(5), contributes=False, ) stacktrace_component = GroupingComponent(id="stacktrace") if exception.stacktrace is not None: stacktrace_component = context.get_grouping_component(exception.stacktrace, **meta) if stacktrace_component.contributes: if exception.type: type_component.update(contributes=True) if exception.value: value_component.update(hint="stacktrace and type take precedence") elif exception.value: value_component.update(hint="stacktrace takes precedence") if not stacktrace_component.contributes: if exception.type: type_component.update(contributes=True) if exception.value: value_component.update(contributes=True) return GroupingComponent( id="exception", values=[stacktrace_component, type_component, value_component] )
def message_v1(message_interface, **meta): return GroupingComponent( id="message", values=[ message_interface.message or message_interface.formatted or "" ], similarity_encoder=text_shingle_encoder(5), )
def message_v2(message_interface, **meta): message_in = message_interface.message or message_interface.formatted or "" message_trimmed = trim_message_for_grouping(message_in) hint = "stripped common values" if message_in != message_trimmed else None return GroupingComponent( id="message", values=[message_trimmed], hint=hint, similarity_encoder=text_shingle_encoder(5), )
def single_exception_legacy(interface: SingleException, event: Event, context: GroupingContext, **meta: Any) -> ReturnedVariants: type_component = GroupingComponent( id="type", values=[interface.type] if interface.type else [], similarity_encoder=ident_encoder, contributes=False, ) value_component = GroupingComponent( id="value", values=[interface.value] if interface.value else [], similarity_encoder=text_shingle_encoder(5), contributes=False, ) stacktrace_component = GroupingComponent(id="stacktrace") if interface.stacktrace is not None: stacktrace_component = context.get_grouping_component( interface.stacktrace, event=event, **meta) if stacktrace_component.contributes: if interface.type: type_component.update(contributes=True) if interface.value: value_component.update( hint="stacktrace and type take precedence") elif interface.value: value_component.update(hint="stacktrace takes precedence") if not stacktrace_component.contributes: if interface.type: type_component.update(contributes=True) if interface.value: value_component.update(contributes=True) return { context["variant"]: GroupingComponent( id="exception", values=[stacktrace_component, type_component, value_component]) }
def single_exception_common(exception, config, meta, with_value): if exception.stacktrace is not None: stacktrace_component = config.get_grouping_component( exception.stacktrace, **meta) else: stacktrace_component = GroupingComponent(id="stacktrace") type_component = GroupingComponent( id="type", values=[exception.type] if exception.type else [], similarity_encoder=ident_encoder, ) if exception.mechanism and exception.mechanism.synthetic: type_component.update(contributes=False, hint="ignored because exception is synthetic") values = [stacktrace_component, type_component] if with_value: value_component = GroupingComponent( id="value", similarity_encoder=text_shingle_encoder(5)) value_in = exception.value if value_in is not None: value_trimmed = trim_message_for_grouping(value_in) hint = "stripped common values" if value_in != value_trimmed else None if value_trimmed: value_component.update(values=[value_trimmed], hint=hint) if stacktrace_component.contributes and value_component.contributes: value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because stacktrace takes precedence", ) values.append(value_component) return GroupingComponent(id="exception", values=values)
def single_exception(exception, context, **meta): type_component = GroupingComponent( id="type", values=[exception.type] if exception.type else [], similarity_encoder=ident_encoder, ) ns_error_component = None if exception.mechanism: if exception.mechanism.synthetic: type_component.update( contributes=False, hint="ignored because exception is synthetic") if exception.mechanism.meta and "ns_error" in exception.mechanism.meta: ns_error_component = GroupingComponent( id="ns-error", values=[ exception.mechanism.meta["ns_error"].get("domain"), exception.mechanism.meta["ns_error"].get("code"), ], ) if exception.stacktrace is not None: stacktrace_variants = context.get_grouping_component( exception.stacktrace, **meta) else: stacktrace_variants = { "app": GroupingComponent(id="stacktrace"), } rv = {} for variant, stacktrace_component in stacktrace_variants.items(): values = [stacktrace_component, type_component] if ns_error_component is not None: values.append(ns_error_component) if context["with_exception_value_fallback"]: value_component = GroupingComponent( id="value", similarity_encoder=text_shingle_encoder(5)) value_in = exception.value if value_in is not None: value_trimmed = trim_message_for_grouping(value_in) hint = "stripped common values" if value_in != value_trimmed else None if value_trimmed: value_component.update(values=[value_trimmed], hint=hint) if stacktrace_component.contributes and value_component.contributes: value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because stacktrace takes precedence", ) if (ns_error_component is not None and ns_error_component.contributes and value_component.contributes): value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because ns-error info takes precedence", ) values.append(value_component) rv[variant] = GroupingComponent(id="exception", values=values) return rv
def single_exception(exception, context, **meta): type_component = GroupingComponent( id="type", values=[exception.type] if exception.type else [], similarity_encoder=ident_encoder, ) system_type_component = type_component.shallow_copy() ns_error_component = None if exception.mechanism: if exception.mechanism.synthetic: type_component.update(contributes=False, hint="ignored because exception is synthetic") system_type_component.update( contributes=False, hint="ignored because exception is synthetic" ) if exception.mechanism.meta and "ns_error" in exception.mechanism.meta: ns_error_component = GroupingComponent( id="ns-error", values=[ exception.mechanism.meta["ns_error"].get("domain"), exception.mechanism.meta["ns_error"].get("code"), ], ) if context["detect_synthetic_exception_types"] and _synthetic_exception_type_re.match( exception.type ): # Do not update type component of system variant, such that regex # can be continuously modified without unnecessarily creating new # groups. type_component.update( contributes=False, hint="ignored because exception is synthetic (detected via exception type)", ) if exception.stacktrace is not None: with context: context["exception_data"] = exception.to_json() stacktrace_variants = context.get_grouping_component(exception.stacktrace, **meta) else: stacktrace_variants = { "app": GroupingComponent(id="stacktrace"), } rv = {} for variant, stacktrace_component in stacktrace_variants.items(): values = [ stacktrace_component, system_type_component if variant == "system" else type_component, ] if ns_error_component is not None: values.append(ns_error_component) if context["with_exception_value_fallback"]: value_component = GroupingComponent( id="value", similarity_encoder=text_shingle_encoder(5) ) value_in = exception.value if value_in is not None: value_trimmed = trim_message_for_grouping(value_in) hint = "stripped common values" if value_in != value_trimmed else None if value_trimmed: value_component.update(values=[value_trimmed], hint=hint) if stacktrace_component.contributes and value_component.contributes: value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because stacktrace takes precedence", ) if ( ns_error_component is not None and ns_error_component.contributes and value_component.contributes ): value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because ns-error info takes precedence", ) values.append(value_component) rv[variant] = GroupingComponent(id="exception", values=values) return rv
def single_exception(interface: SingleException, event: Event, context: GroupingContext, **meta: Any) -> ReturnedVariants: type_component = GroupingComponent( id="type", values=[interface.type] if interface.type else [], similarity_encoder=ident_encoder, ) system_type_component = type_component.shallow_copy() ns_error_component = None if interface.mechanism: if interface.mechanism.synthetic: # Ignore synthetic exceptions as they are produced from platform # specific error codes. # # For example there can be crashes with EXC_ACCESS_VIOLATION_* on Windows with # the same exact stacktrace as a crash with EXC_BAD_ACCESS on macOS. # # Do not update type component of system variant, such that regex # can be continuously modified without unnecessarily creating new # groups. type_component.update( contributes=False, hint="ignored because exception is synthetic") if interface.mechanism.meta and "ns_error" in interface.mechanism.meta: ns_error_component = GroupingComponent( id="ns-error", values=[ interface.mechanism.meta["ns_error"].get("domain"), interface.mechanism.meta["ns_error"].get("code"), ], ) if interface.stacktrace is not None: with context: context["exception_data"] = interface.to_json() stacktrace_variants = context.get_grouping_component( interface.stacktrace, event=event, **meta) else: stacktrace_variants = { "app": GroupingComponent(id="stacktrace"), } rv = {} for variant, stacktrace_component in stacktrace_variants.items(): values = [ stacktrace_component, system_type_component if variant == "system" else type_component, ] if ns_error_component is not None: values.append(ns_error_component) if context["with_exception_value_fallback"]: value_component = GroupingComponent( id="value", similarity_encoder=text_shingle_encoder(5)) value_in = interface.value if value_in is not None: value_trimmed = trim_message_for_grouping(value_in) hint = "stripped common values" if value_in != value_trimmed else None if value_trimmed: value_component.update(values=[value_trimmed], hint=hint) if stacktrace_component.contributes and value_component.contributes: value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because stacktrace takes precedence", ) if (ns_error_component is not None and ns_error_component.contributes and value_component.contributes): value_component.update( contributes=False, contributes_to_similarity=True, hint="ignored because ns-error info takes precedence", ) values.append(value_component) rv[variant] = GroupingComponent(id="exception", values=values) return rv