Warning
This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.tools.error_reports.plugins.sentry
"""The module describes the ``sentry`` error plugin plugin."""
import logging
try:
import sentry_sdk
except ImportError:
sentry_sdk = None
from galaxy import web
from galaxy.util import string_as_bool
from . import ErrorPlugin
log = logging.getLogger(__name__)
SENTRY_SDK_IMPORT_MESSAGE = "The Python sentry-sdk package is required to use this feature, please install it"
ERROR_TEMPLATE = """Galaxy Job Error: {tool_id} v{tool_version}
Command Line:
{command_line}
Stderr:
{stderr}
Stdout:
{stdout}
The user provided the following information:
{message}"""
[docs]class SentryPlugin(ErrorPlugin):
"""Send error report to Sentry."""
plugin_type = "sentry"
[docs] def __init__(self, **kwargs):
self.app = kwargs["app"]
self.redact_user_details_in_bugreport = self.app.config.redact_user_details_in_bugreport
self.verbose = string_as_bool(kwargs.get("verbose", False))
self.user_submission = string_as_bool(kwargs.get("user_submission", False))
assert sentry_sdk, SENTRY_SDK_IMPORT_MESSAGE
[docs] def submit_report(self, dataset, job, tool, **kwargs):
"""Submit the error report to sentry"""
extra = {
"info": job.info,
"id": job.id,
"command_line": job.command_line,
"destination_id": job.destination_id,
"stderr": job.stderr,
"traceback": job.traceback,
"exit_code": job.exit_code,
"stdout": job.stdout,
"handler": job.handler,
"tool_id": job.tool_id,
"tool_version": job.tool_version,
"tool_xml": tool.config_file if tool else None,
}
if self.redact_user_details_in_bugreport:
extra["email"] = "redacted"
else:
if "email" in kwargs:
extra["email"] = kwargs["email"]
# User submitted message
extra["message"] = kwargs.get("message", "")
# Construct the error message to send to sentry. The first line
# will be the issue title, everything after that becomes the
# "message"
error_message = ERROR_TEMPLATE.format(**extra)
# Update context with user information in a sentry-specific manner
context = {}
# Getting the url allows us to link to the dataset info page in case
# anything is missing from this report.
try:
url = web.url_for(
controller="dataset",
action="show_params",
dataset_id=self.app.security.encode_id(dataset.id),
qualified=True,
)
except AttributeError:
# The above does not work when handlers are separate from the web handlers
url = None
user = job.get_user()
if self.redact_user_details_in_bugreport:
if user:
# Opaque identifier
context["user"] = {"id": user.id}
else:
if user:
# User information here also places email links + allows seeing
# a list of affected users in the tags/filtering.
context["user"] = {
"name": user.username,
"email": user.email,
}
context["request"] = {"url": url}
for key, value in context.items():
sentry_sdk.set_context(key, value)
sentry_sdk.set_context("job", extra)
sentry_sdk.set_tag("tool_id", job.tool_id)
sentry_sdk.set_tag("tool_version", job.tool_version)
# Send the message, using message because
response = sentry_sdk.capture_message(error_message)
return (f"Submitted bug report to Sentry. Your guru meditation number is {response}", "success")
__all__ = ("SentryPlugin",)