Bug 1636251: report |./mach| errors with Sentry r=rstewart

These errors are reported to the "mach" project here:
https://sentry.prod.mozaws.net/operations/mach/

Should only report exceptions caused by a failure in `mach` or its subcommands. Build/test/etc failures
should not be sent to Sentry.

Depends on D74737

Differential Revision: https://phabricator.services.mozilla.com/D74738
This commit is contained in:
Mitchell Hentges 2020-06-11 20:38:04 +00:00
parent ad29c7cb77
commit 5b5e1ea7b9
3 changed files with 65 additions and 0 deletions

View File

@ -14,3 +14,5 @@ path:mach
path:python/
path:testing/mozbase/
path:third_party/python/
# certifi is needed for Sentry
path:testing/web-platform/tests/tools/third_party/certifi

View File

@ -18,6 +18,7 @@ import traceback
import uuid
from collections import Iterable
from mach.sentry import register_sentry, report_exception
from six import string_types
from .base import (
@ -319,6 +320,7 @@ To see more help for a specific command, run:
Returns the integer exit code that should be used. 0 means success. All
other values indicate failure.
"""
register_sentry()
# If no encoding is defined, we default to UTF-8 because without this
# Python 2.7 will assume the default encoding of ASCII. This will blow
@ -375,6 +377,7 @@ To see more help for a specific command, run:
stack = traceback.extract_tb(exc_tb)
self._print_exception(sys.stdout, exc_type, exc_value, stack)
report_exception(exc_value)
return 1
@ -480,6 +483,7 @@ To see more help for a specific command, run:
return e.exit_code
except Exception:
exc_type, exc_value, exc_tb = sys.exc_info()
report_exception(exc_value)
# The first two frames are us and are never used.
stack = traceback.extract_tb(exc_tb)[2:]

View File

@ -0,0 +1,59 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import
import os
import re
import sentry_sdk
from six.moves.configparser import SafeConfigParser, NoOptionError
from mozboot.util import get_state_dir
# https://sentry.prod.mozaws.net/operations/mach/
_SENTRY_DSN = "https://8228c9aff64949c2ba4a2154dc515f55@sentry.prod.mozaws.net/525"
def register_sentry():
cfg_file = os.path.join(get_state_dir(), 'machrc')
config = SafeConfigParser()
if not config.read(cfg_file):
return
try:
telemetry_enabled = config.getboolean("build", "telemetry")
except NoOptionError:
return
if not telemetry_enabled:
return
sentry_sdk.init(_SENTRY_DSN, before_send=_settle_mach_module_id)
def _settle_mach_module_id(sentry_event, exception):
# Sentry groups issues according to the stack frames and their associated
# "module" properties. However, one of the modules is being reported
# like "mach.commands.26a828ef5164403eaff4305ab4cb0fab" (with a generated id).
# This function replaces that generated id with the static string "<generated>"
# so that grouping behaves as expected
stacktrace_frames = sentry_event["exception"]["values"][0]["stacktrace"]["frames"]
for frame in stacktrace_frames:
module = frame.get("module")
if not module:
continue
module = re.sub("mach\\.commands\\.[a-f0-9]{32}", "mach.commands.<generated>",
module)
frame["module"] = module
return sentry_event
def report_exception(exception):
# sentry_sdk won't report the exception if `sentry-sdk.init(...)` hasn't been called
sentry_sdk.capture_exception(exception)