Skip to content

Add scheduler observability metrics - #68068

Merged
hussein-awala merged 9 commits into
apache:mainfrom
safaehar:feat/scheduler-observability-metrics
Jul 7, 2026
Merged

hussein-awala merged 9 commits into
apache:mainfrom
safaehar:feat/scheduler-observability-metrics

Conversation

@safaehar

@safaehar safaehar commented Jun 5, 2026 •

Copy link
Copy Markdown
Contributor

Emit three new metrics from `SchedulerJobRunner` to improve visibility into scheduler health. These metrics have been running in production at Datadog via local monkey-patches and are contributed upstream so the patches can eventually be removed.

New metrics

  • `scheduler.loop_exceptions{exception_class}` — counter incremented when the scheduler loop exits with an unhandled exception, tagged with the exception class. Emitted from the existing `except Exception` block in `_execute`.

  • `scheduler.executor_events.batch_size` (gauge) and `scheduler.executor_events.processed` (counter) — emitted on every successful call to `process_executor_events` with the size of the event batch. `scheduler.executor_events.failed{exception_class}` is incremented when the call raises, tagged with the exception class.

  • `scheduler.zombies.detected{reason}` — counter incremented when zombie task instances are detected, tagged by detection path:

    • `heartbeat_timeout`: task exceeded the heartbeat threshold

Tests

New test class `TestSchedulerObservabilityMetrics` in `airflow-core/tests/unit/jobs/test_scheduler_job.py` covers all three metrics (success and failure paths):

pytest airflow-core/tests/unit/jobs/test_scheduler_job.py::TestSchedulerObservabilityMetrics -v

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below) : Claude

Important

🛠️ Maintainer triage note for @safaehar · by @potiuk · 2026-07-02 17:46 UTC

Some review feedback from @hussein-awala is waiting on you:

  • 1 unresolved review thread(s) from @hussein-awala need a reply or a fix.

The ball is in your court — you've been assigned to this PR. Reply or push a fix in each thread, then mark them resolved.

Automated triage — may be imperfect; a maintainer takes the next look.

@safaehar
safaehar requested review from XD-DENG and ashb as code owners June 5, 2026 09:10
@safaehar
safaehar force-pushed the feat/scheduler-observability-metrics branch 4 times, most recently from d018424 to 27131ce Compare June 5, 2026 10:19
@hussein-awala
hussein-awala requested a review from Copilot June 8, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds scheduler observability metrics in SchedulerJobRunner to improve visibility into scheduler loop failures, executor event processing volume/failures, and zombie task detection, along with unit tests to validate emission.

Changes:

  • Emit scheduler.loop_exceptions{exception_class} when _execute() exits due to an unhandled exception.
  • Emit executor event batch metrics (scheduler.executor_events.batch_size, scheduler.executor_events.processed, scheduler.executor_events.failed{reason}) around process_executor_events().
  • Emit scheduler.zombies.detected{reason} for heartbeat-timeout zombies and orphan adopt/reset failures, with new/updated unit tests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
airflow-core/src/airflow/jobs/scheduler_job_runner.py Adds new scheduler metrics for loop exceptions, executor event processing success/failure, and zombie detection.
airflow-core/tests/unit/jobs/test_scheduler_job.py Updates existing executor-event assertions and adds a new test class covering the new metrics.

@potiuk

potiuk commented Jun 9, 2026

Copy link
Copy Markdown
Member

@safaehar A few things need addressing before review — see our Pull Request quality criteria.

  • ❌ Pre-commit / static checks. See docs.

No rush.

Note: This comment was drafted by an AI-assisted triage tool and may contain mistakes. Once you have addressed the points above, an Apache Airflow maintainer — a real person — will take the next look at your PR. We use this two-stage triage process so that our maintainers' limited time is spent where it matters most: the conversation with you.

@safaehar

safaehar commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks @potiuk, addressed the failing static checks in ab239f6:

  • check-metrics-synced-with-registry: registered the five new metrics (scheduler.loop_exceptions, scheduler.executor_events.{processed,failed,batch_size}, scheduler.zombies.detected) in shared/observability/src/airflow_shared/observability/metrics/metrics_template.yaml.
  • ruff format: applied (ruff 0.15.15, matching the pinned pre-commit version).

All three hooks (ruff, ruff-format, check-metrics-synced-with-registry) now pass locally.

@safaehar
safaehar force-pushed the feat/scheduler-observability-metrics branch from 79f3197 to 18648f9 Compare June 11, 2026 09:30

@hussein-awala hussein-awala left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once the doc is updated.

Needs a second review before merging.

@safaehar
safaehar requested a review from hussein-awala June 15, 2026 12:12
@potiuk
potiuk marked this pull request as draft June 22, 2026 06:35
@safaehar
safaehar marked this pull request as ready for review June 23, 2026 11:58

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on the metrics — correct, cheap (once per scheduler loop, no added DB round-trips), registered in the metrics template, and tested.

One ask before merge: please update the description — it still advertises scheduler.zombies.detected{reason:adopt_failure}, which was removed during review (only heartbeat_timeout emits now), so the advertised metric surface no longer matches the code.

Minor (non-blocking): the executor_events emit block is duplicated at all three return points; a small helper would keep batch_size/processed from drifting.

safaehar added 7 commits July 6, 2026 19:42
Emit three new metrics from SchedulerJobRunner to improve visibility
into scheduler health:

- scheduler.loop_exceptions{exception_class}: counter incremented when
  the scheduler loop exits with an unhandled exception, tagged with the
  exception class to aid triaging crash loops.

- scheduler.executor_events.batch_size (gauge) and
  scheduler.executor_events.processed (counter): emitted on each
  successful call to process_executor_events with the event count.
  scheduler.executor_events.failed{reason} is incremented instead when
  the call raises, tagged with the exception class.
  The original body is extracted into _process_executor_events_core so
  process_executor_events can act as a thin metrics wrapper.

- scheduler.zombies.detected{reason}: counter incremented when zombie
  task instances are detected, tagged with the detection path:
    - heartbeat_timeout: task exceeded the heartbeat threshold
    - adopt_failure: orphaned task could not be re-adopted and was reset

These metrics are already running in production via local monkey-patches
at Datadog; this commit contributes them natively upstream so the
patches can eventually be removed.
… metric

Three existing tests used mock_stats.incr.assert_not_called() to verify that
no error/mismatch metrics were emitted in requeued-TI and stale-success
scenarios. The new executor_events.processed counter now fires unconditionally
for every _process_executor_events call, so those blanket assertions became
too broad. Replace each with an assertion that permits the expected counter
while still verifying that no scheduler.tasks.killed_externally metric fired.
safaehar added 2 commits July 6, 2026 19:42
Extract _emit_executor_events_batch_metrics helper to avoid the
batch_size/processed emit drifting across the three return points
in process_executor_events.
Rebasing onto main pulled in apache#68741's queued-after-defer regression test,
which asserted stats.incr was never called. That predates this PR's
executor_events.processed counter, which now fires unconditionally on
every successful process_executor_events call. Align the assertion with
the sibling scheduled-after-defer test fixed earlier in this PR.
@safaehar
safaehar force-pushed the feat/scheduler-observability-metrics branch from ef14d22 to ddc7ecb Compare July 6, 2026 17:49
@safaehar safaehar changed the title feat: add scheduler observability metrics Add scheduler observability metrics Jul 7, 2026
@safaehar
safaehar marked this pull request as draft July 7, 2026 08:43
@safaehar
safaehar marked this pull request as ready for review July 7, 2026 08:43
@hussein-awala

Copy link
Copy Markdown
Member

All comments and suggestions have been addressed. I'll merge this now.

@hussein-awala
hussein-awala merged commit c96f5c8 into apache:main Jul 7, 2026
215 of 218 checks passed
@boring-cyborg

boring-cyborg Bot commented Jul 7, 2026

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

@hussein-awala

Copy link
Copy Markdown
Member

Congrats @safaehar on your first commit!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants