From d0c6ef22a077235dc78d2a658d268517259a2880 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 6 Jun 2025 15:01:14 -0400 Subject: [PATCH 1/2] fix(taskworker) Improve metrics for scheduler Add a taskname dimension to scheduled tasks so that we can filter and breakdown scheduler operations. --- src/sentry/taskworker/scheduler/runner.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sentry/taskworker/scheduler/runner.py b/src/sentry/taskworker/scheduler/runner.py index 96ecc1f494764b..90e7a09b82307f 100644 --- a/src/sentry/taskworker/scheduler/runner.py +++ b/src/sentry/taskworker/scheduler/runner.py @@ -105,6 +105,10 @@ def __repr__(self) -> str: def fullname(self) -> str: return self._task.fullname + @property + def taskname(self) -> str: + return self._task.name + def set_last_run(self, last_run: datetime | None) -> None: self._last_run = last_run @@ -118,7 +122,6 @@ def runtime_after(self, start: datetime) -> datetime: return self._schedule.runtime_after(start) def delay_task(self) -> None: - logger.info("taskworker.scheduler.delay_task", extra={"task": self._task.fullname}) monitor_config = self.monitor_config() headers: dict[str, Any] | None = None if monitor_config: @@ -223,13 +226,15 @@ def _try_spawn(self, entry: ScheduleEntry) -> None: entry.delay_task() entry.set_last_run(now) - logger.info("taskworker.scheduler.delay_task", extra={"task": entry.fullname}) - metrics.incr("taskworker.scheduler.delay_task") + logger.info("taskworker.scheduler.delay_task", extra={"fullname": entry.fullname}) + metrics.incr("taskworker.scheduler.delay_task", tags={"taskname": entry.taskname}) else: # sync with last_run state in storage entry.set_last_run(self._run_storage.read(entry.fullname)) - logger.info("taskworker.scheduler.sync_with_storage", extra={"task": entry.fullname}) + logger.info( + "taskworker.scheduler.sync_with_storage", extra={"fullname": entry.fullname} + ) metrics.incr("taskworker.scheduler.sync_with_storage") def _update_heap(self) -> None: From b491658af3d51bac1684618937e046eb18de2360 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 9 Jun 2025 14:27:52 -0400 Subject: [PATCH 2/2] add namespace tag to scheduler metrics. --- src/sentry/taskworker/scheduler/runner.py | 12 +++++++++++- src/sentry/taskworker/task.py | 4 ++++ tests/sentry/taskworker/test_task.py | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sentry/taskworker/scheduler/runner.py b/src/sentry/taskworker/scheduler/runner.py index 90e7a09b82307f..05ddec68334c23 100644 --- a/src/sentry/taskworker/scheduler/runner.py +++ b/src/sentry/taskworker/scheduler/runner.py @@ -105,6 +105,10 @@ def __repr__(self) -> str: def fullname(self) -> str: return self._task.fullname + @property + def namespace(self) -> str: + return self._task.namespace.name + @property def taskname(self) -> str: return self._task.name @@ -227,7 +231,13 @@ def _try_spawn(self, entry: ScheduleEntry) -> None: entry.set_last_run(now) logger.info("taskworker.scheduler.delay_task", extra={"fullname": entry.fullname}) - metrics.incr("taskworker.scheduler.delay_task", tags={"taskname": entry.taskname}) + metrics.incr( + "taskworker.scheduler.delay_task", + tags={ + "taskname": entry.taskname, + "namespace": entry.namespace, + }, + ) else: # sync with last_run state in storage entry.set_last_run(self._run_storage.read(entry.fullname)) diff --git a/src/sentry/taskworker/task.py b/src/sentry/taskworker/task.py index 072f754f2f076b..2795cd75c14923 100644 --- a/src/sentry/taskworker/task.py +++ b/src/sentry/taskworker/task.py @@ -64,6 +64,10 @@ def __init__( def fullname(self) -> str: return f"{self._namespace.name}:{self.name}" + @property + def namespace(self) -> TaskNamespace: + return self._namespace + @property def retry(self) -> Retry | None: return self._retry diff --git a/tests/sentry/taskworker/test_task.py b/tests/sentry/taskworker/test_task.py index e435771be0e213..89b336985c1b11 100644 --- a/tests/sentry/taskworker/test_task.py +++ b/tests/sentry/taskworker/test_task.py @@ -30,6 +30,7 @@ def test_define_task_defaults(task_namespace: TaskNamespace) -> None: task = Task(name="test.do_things", func=do_things, namespace=task_namespace) assert task.retry is None assert task.name == "test.do_things" + assert task.namespace == task_namespace def test_define_task_retry(task_namespace: TaskNamespace) -> None: