Merge pull request #18570 from mvdbeek/sentry_group_cheetah_errors

Group tool templating exceptions in sentry
This commit is contained in:
Marius van den Beek
2024-07-24 16:33:29 +02:00
committed by GitHub
2 changed files with 59 additions and 13 deletions
+23
View File
@@ -147,6 +147,7 @@ from galaxy.tools.cache import ToolCache
from galaxy.tools.data import ToolDataTableManager
from galaxy.tools.data_manager.manager import DataManagers
from galaxy.tools.error_reports import ErrorReports
from galaxy.tools.evaluation import ToolTemplatingException
from galaxy.tools.search import ToolBoxSearch
from galaxy.tools.special_tools import load_lib_tools
from galaxy.tours import (
@@ -227,12 +228,34 @@ class SentryClientMixin:
level=logging.INFO, # Capture info and above as breadcrumbs
event_level=getattr(logging, event_level), # Send errors as events
)
def before_send(event, hint):
if "exc_info" in hint:
exc_type, exc_value, tb = hint["exc_info"]
if isinstance(exc_value, ToolTemplatingException):
# We set a custom fingerprint that may look like:
# ["Error occurred while {action_str.lower()} for tool '{tool.id}'",
# "1.0",
# "cannot find 'file_name' while searching for 'species_chromosomes.file_name'"]
# If we don't do this issues are never properly grouped since by default the calling stack is inspected,
# and that is always unique in cheetah as it is dynamically generated.
event["fingerprint"] = [str(exc_value), str(exc_value.tool_version), str(exc_value.__cause__)]
event.setdefault("tags", {}).update(
{
"tool_is_latest": exc_value.is_latest,
"tool_id": str(exc_value.tool_id),
"tool_version": exc_value.tool_version,
}
)
return event
self.sentry_client = sentry_sdk.init(
self.config.sentry_dsn,
release=f"{self.config.version_major}.{self.config.version_minor}",
integrations=[sentry_logging],
traces_sample_rate=self.config.sentry_traces_sample_rate,
ca_certs=self.config.sentry_ca_certs,
before_send=before_send,
)
+36 -13
View File
@@ -12,6 +12,7 @@ from typing import (
Dict,
List,
Optional,
TYPE_CHECKING,
Union,
)
@@ -70,6 +71,9 @@ from galaxy.util.template import (
from galaxy.util.tree_dict import TreeDict
from galaxy.work.context import WorkRequestContext
if TYPE_CHECKING:
from galaxy.tools import Tool
log = logging.getLogger(__name__)
@@ -89,13 +93,27 @@ class ToolErrorLog:
global_tool_errors = ToolErrorLog()
def global_tool_logs(func, config_file, action_str):
class ToolTemplatingException(Exception):
def __init__(self, *args: object, tool_id: Optional[str], tool_version: str, is_latest: bool) -> None:
super().__init__(*args)
self.tool_id = tool_id
self.tool_version = tool_version
self.is_latest = is_latest
def global_tool_logs(func, config_file: str, action_str: str, tool: "Tool"):
try:
return func()
except Exception as e:
# capture and log parsing errors
global_tool_errors.add_error(config_file, action_str, e)
raise e
raise ToolTemplatingException(
f"Error occurred while {action_str.lower()} for tool '{tool.id}'",
tool_id=tool.id,
tool_version=tool.version,
is_latest=tool.is_latest_version,
) from e
DeferrableObjectsT = Union[
@@ -581,13 +599,18 @@ class ToolEvaluator:
"""
config_file = self.tool.config_file
global_tool_logs(
self._create_interactivetools_entry_points, config_file, "Building Interactive Tool Entry Points"
self._create_interactivetools_entry_points, config_file, "Building Interactive Tool Entry Points", self.tool
)
global_tool_logs(self._build_config_files, config_file, "Building Config Files")
global_tool_logs(self._build_param_file, config_file, "Building Param File")
global_tool_logs(self._build_command_line, config_file, "Building Command Line")
global_tool_logs(self._build_version_command, config_file, "Building Version Command Line")
global_tool_logs(self._build_environment_variables, config_file, "Building Environment Variables")
global_tool_logs(
self._build_config_files,
config_file,
"Building Config Files",
self.tool,
)
global_tool_logs(self._build_param_file, config_file, "Building Param File", self.tool)
global_tool_logs(self._build_command_line, config_file, "Building Command Line", self.tool)
global_tool_logs(self._build_version_command, config_file, "Building Version Command Line", self.tool)
global_tool_logs(self._build_environment_variables, config_file, "Building Environment Variables", self.tool)
return (
self.command_line,
self.version_command_line,
@@ -836,7 +859,7 @@ class PartialToolEvaluator(ToolEvaluator):
def build(self):
config_file = self.tool.config_file
global_tool_logs(self._build_environment_variables, config_file, "Building Environment Variables")
global_tool_logs(self._build_environment_variables, config_file, "Building Environment Variables", self.tool)
return (
self.command_line,
self.version_command_line,
@@ -857,10 +880,10 @@ class RemoteToolEvaluator(ToolEvaluator):
def build(self):
config_file = self.tool.config_file
global_tool_logs(self._build_config_files, config_file, "Building Config Files")
global_tool_logs(self._build_param_file, config_file, "Building Param File")
global_tool_logs(self._build_command_line, config_file, "Building Command Line")
global_tool_logs(self._build_version_command, config_file, "Building Version Command Line")
global_tool_logs(self._build_config_files, config_file, "Building Config Files", self.tool)
global_tool_logs(self._build_param_file, config_file, "Building Param File", self.tool)
global_tool_logs(self._build_command_line, config_file, "Building Command Line", self.tool)
global_tool_logs(self._build_version_command, config_file, "Building Version Command Line", self.tool)
return (
self.command_line,
self.version_command_line,