When not dogfooding, just print a regular stacktrace in the logs

This will hopefully help when getting issue-reports for those that
have not set up dogfooding.

See [Dogfooding Bugsink](https://www.bugsink.com/docs/dogfooding/)
This commit is contained in:
Klaas van Schelven
2025-04-11 13:22:37 +02:00
parent 0c11bf0787
commit 1084796763
3 changed files with 30 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
from collections import namedtuple
import json
import sentry_sdk
import logging
from django.db.models import Q
from django.utils import timezone
@@ -16,6 +17,7 @@ from django.db.utils import OperationalError
from django.conf import settings
from sentry.utils.safe import get_path
from sentry_sdk_extensions import capture_or_log_exception
from bugsink.decorators import project_membership_required, issue_membership_required, atomic_for_request_method
from bugsink.transaction import durable_atomic
@@ -34,6 +36,8 @@ from .forms import CommentForm
from .utils import get_values, get_main_exception
from events.utils import annotate_with_meta, apply_sourcemaps
logger = logging.getLogger("bugsink.issues")
MuteOption = namedtuple("MuteOption", ["for_or_until", "period_name", "nr_of_periods", "gte_threshold"])
@@ -410,7 +414,7 @@ def issue_event_stacktrace(request, issue, event_pk=None, digest_order=None, nav
raise
# sourcemaps are still experimental; we don't want to fail on them, so we just log the error and move on.
sentry_sdk.capture_exception(e)
capture_or_log_exception(e, logger)
# NOTE: I considered making this a clickable button of some sort, but decided against it in the end. Getting the UI
# right is quite hard (https://ux.stackexchange.com/questions/1318) but more generally I would assume that having

View File

@@ -1,3 +1,4 @@
import traceback
import types
from sentry_sdk.utils import current_stacktrace
@@ -111,3 +112,19 @@ def capture_stacktrace(message):
}
}
sentry_sdk.capture_event(event)
def capture_or_log_exception(e, logger):
try:
if sentry_sdk.is_initialized():
sentry_sdk.capture_exception(e)
else:
# this gnarly approach makes it so that each line of the traceback gets the same prefixes (dates etc)
for bunch_of_lines in traceback.format_exception(e):
for line in bunch_of_lines.splitlines():
# Note: when .is_initialized() is True, .error is spammy (it gets captured) but we don't have that
# problem in this branch.
logger.error(line)
except Exception as e2:
# We just never want our error-handling code to be the cause of an error.
print("Error in capture_or_log_exception", str(e2), "during handling of", str(e))

View File

@@ -10,11 +10,12 @@ import time
import signal
import threading
from inotify_simple import INotify, flags
from sentry_sdk import capture_exception
import sentry_sdk
from django.conf import settings
from django.db import connections
from sentry_sdk_extensions import capture_or_log_exception
from performance.context_managers import time_to_logger
from bugsink.transaction import durable_atomic
@@ -180,9 +181,11 @@ class Foreman:
function(*inner_args, **inner_kwargs)
except Exception as e:
# Potential TODO: make this configurable / depend on our existing config in bugsink/settings.py
logger.warning("Snappea caught Exception: %s", str(e))
capture_exception(e)
if sentry_sdk.is_initialized():
# Only for the case where full error is captured to Dogfooded Bugsink, do we want to draw some
# attention to this; in the other case the big error in the logs (full traceback) is clear enough.
logger.warning("Snappea caught Exception: %s", str(e))
capture_or_log_exception(e, logger)
finally:
# equivalent to the below, but slightly more general (and thus more future-proof). In both cases nothing
# happens with already-closed/never opened connections):
@@ -324,7 +327,7 @@ class Foreman:
logger.error('Create workers: can\'t execute "%s": %s', task.task_name, e)
with time_to_logger(performance_logger, "Snappea delete Task"):
task.delete() # we delete the task because we can't do anything with it, and we don't want to hang
capture_exception(e)
capture_or_log_exception(e, logger)
self.worker_semaphore.release()
continue