Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ console_scripts =
dev =
pre-commit
tox
sentry =
psutil
sentry_sdk

[options.package_data]
fuzzfetch =
Expand Down
50 changes: 46 additions & 4 deletions src/fuzzfetch/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@
from logging import DEBUG, INFO, WARNING, basicConfig, getLogger
from pathlib import Path
from platform import system
from shutil import copy
from shutil import copy, disk_usage
from tempfile import mkstemp
from typing import TYPE_CHECKING, Any

from pytz import timezone

try:
from psutil import virtual_memory
from sentry_sdk import Event, Hint
from sentry_sdk import init as sentry_init

HAVE_SENTRY = True
except ImportError:
HAVE_SENTRY = False

from .args import FetcherArgs
from .download import download_url, get_url, resolve_url
from .errors import FetcherException
Expand All @@ -42,6 +51,25 @@
BUG_URL = "https://github.com/MozillaSecurity/fuzzfetch/issues/"


def _add_system_context(event: Event, hint: Hint) -> Event:
event.setdefault("contexts", {})
event["contexts"]["system_stats"] = {
"free_memory_mb": virtual_memory().available // 1024 // 1024,
"free_disk_mb": disk_usage("/").free // 1024 // 1024,
}

# add crashing module as a tag
exc_info = hint.get("exc_info")
if exc_info:
_, _, tb = exc_info
if tb:
mod_name = tb.tb_frame.f_globals.get("__name__")
if mod_name:
event.setdefault("tags", {})["origin_module"] = mod_name

return event


class Fetcher:
"""Fetcher fetches build artifacts from TaskCluster and unpacks them"""

Expand Down Expand Up @@ -288,9 +316,13 @@ def moz_info(self) -> dict[str, str | bool | int]:
"""Return the build's mozinfo"""
if "moz_info" not in self._memo:
try:
self._memo["moz_info"] = get_url(
self.artifact_url("mozinfo.json")
).json()
resp = get_url(self.artifact_url("mozinfo.json"))
self._memo["moz_info"] = resp.json()
if (
not isinstance(self._memo["moz_info"], dict)
or "crashreporter" not in self._memo["moz_info"]
):
LOG.error("malformed response fetching mozinfo.json: %r", resp)
except FetcherException:
# If mozinfo doesn't exist, set the default topsrcdir
self._memo["moz_info"] = {"topsrcdir": "/builds/worker/checkouts/gecko"}
Expand Down Expand Up @@ -731,6 +763,16 @@ def main(cls) -> int:

Run with --help for usage
"""
if (
HAVE_SENTRY
and "SENTRY_DSN" in os.environ
and "PYTEST_CURRENT_TEST" not in os.environ
):
sentry_init(
dsn=os.environ["SENTRY_DSN"],
before_send=_add_system_context,
)

log_level = INFO
log_fmt = "%(message)s"
if bool(os.getenv("DEBUG")):
Expand Down