Skip to content
Snippets Groups Projects
Commit 236f7986 authored by Antoine Lambert's avatar Antoine Lambert
Browse files

celery_backend/config: Fix enabling of celery integration for sentry

About a year ago, we updated the way sentry is configured for celery
tasks by not relying anymore on the worker_init signal and the
SWH_SENTRY_DSN environment variable but rather by using a task_prerun
signal callback that sets sentry DSN through a dict mapping a task name
to its sentry DSN.

But as a result it broke our celery integration for sentry (that notably
adds task name and parameters in sentry events) as integrations must be
initialized in the worker_init signal callback to work properly. So ensure
they are by first setting a fake DSN in the worker_init signal callback and
update tests to check celery integration is enabled.

Related to swh/meta#4949.
parent fb746617
No related branches found
Tags v2.2.2
1 merge request!375celery_backend/config: Fix enabling of celery integration for sentry
Pipeline #7780 passed
......@@ -6,6 +6,7 @@
import functools
import logging
import os
import sys
from time import monotonic as _monotonic
import traceback
from typing import Any, Dict, Optional
......@@ -176,9 +177,23 @@ def _init_sentry(sentry_dsn: str, main_package: Optional[str] = None):
@worker_init.connect
@_print_errors
def on_worker_init(*args, **kwargs):
sentry_dsn = None # will be set in `init_sentry` function
# use a fake sentry DSN to ensure celery integration for sentry is
# properly configured as it must happen in the worker_init signal
# callback, real sentry DSN is then setup in task_prerun signal
# callback (see celery_task_prerun function below)
sentry_dsn = "https://public@sentry.example.org/1"
_init_sentry(sentry_dsn)
if "pytest" in sys.argv[0] or "PYTEST_XDIST_WORKER" in os.environ:
# when pytest collects tests, it breaks the proper configuration
# of the celery integration as a side effect, so we ensure that
# the celery.worker.consumer.build_tracer function gets overridden
# as it should have be
from celery.app import trace
from celery.worker.consumer import consumer
consumer.build_tracer = trace.build_tracer
@Panel.register
def monotonic(state):
......
......@@ -33,7 +33,7 @@ def multiping(self, n=10):
@shared_task(name=TASK_ERROR)
def not_implemented():
def not_implemented(*args, **kwargs):
raise NotImplementedError("Nope")
......
......@@ -200,13 +200,25 @@ def test_run_ready_task_with_priority(
def test_task_exception(
swh_scheduler_celery_app, swh_scheduler_celery_worker, swh_scheduler
swh_scheduler_celery_app,
swh_scheduler_celery_worker,
swh_scheduler,
mocker,
):
from sentry_sdk.integrations import celery
# using the sentry_events fixture does not work for celery tasks so
# we spy the capture_event method from the client of the sentry Hub
# used in celery integration instead
capture_event = mocker.spy(celery.Hub.current.client, "capture_event")
task_type = swh_scheduler.get_task_type("swh-test-error")
assert task_type
assert task_type["backend_name"] == TASK_ERROR
swh_scheduler.create_tasks([create_task_dict("swh-test-error", "oneshot")])
swh_scheduler.create_tasks(
[create_task_dict("swh-test-error", "oneshot", "arg", kwarg="kwarg")]
)
backend_tasks = run_ready_tasks(swh_scheduler, swh_scheduler_celery_app)
assert len(backend_tasks) == 1
......@@ -216,6 +228,16 @@ def test_task_exception(
with pytest.raises(NotImplementedError):
result.get()
# check celery integration for sentry is enabled
assert capture_event.mock_calls
sentry_event_extra = capture_event.mock_calls[0].kwargs["event"]["extra"]
assert "celery-job" in sentry_event_extra
assert sentry_event_extra["celery-job"] == {
"task_name": TASK_ERROR,
"args": ["arg"],
"kwargs": {"kwarg": "kwarg"},
}
def test_statsd(swh_scheduler_celery_app, swh_scheduler_celery_worker, mocker):
m = mocker.patch("swh.scheduler.task.Statsd._send_to_server")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment