refactor: notification metrics come from spans, and NotificationMetrics is gone

Merged
HA
20h ago
+257-193

Summary

Part of #389, the notifications area. The ten instruments in NotificationMetrics now come from spans, so NotificationService has no meter left.

Changes

Each delivery runs in a notification.deliver span with category, channel, severity, result, error type and delivery seconds. The throttle, each retry and each subscription update leave a one-line notification.throttled, notification.retry or notification.subscription_change span where the metric call was. The collector's signaltometrics connector makes the same ten series from them. Labels take the span attribute names (notification_channel, notification_error, ...), so the notifications dashboard's queries and legends move with them. NotificationService takes trace.Tracer.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling changes

Test Plan

  • Backend unit tests pass (cd backend && uv run pytest tests/unit)
  • Frontend unit tests pass (cd frontend && npm run test)
  • Backend E2E tests pass (docker compose exec -T backend sh -c 'uv sync --group test --no-dev --frozen --no-install-project --no-build && pytest tests/e2e')
  • Frontend E2E tests pass (cd frontend && npm run test:e2e)
  • API spec and client regenerated if routes or schemas changed (./deploy.sh openapi, then ./deploy.sh types), never edited by hand
  • Manual testing performed

Validation: unit 570 passed (6 span tests), contract 3 passed, e2e 488 passed and 1 skipped. Driving NotificationService from the API container against a local stack (3 in-app deliveries, 1 webhook to a closed port, 2 subscription updates) gave exactly those counts in VictoriaMetrics, with 2 retries and ConnectError on the failure. The throttle path is covered by a unit test only.

Checklist

  • My code follows the project's style guidelines
  • I have run pre-commit run --all-files and all checks pass
  • I have added tests that prove my fix/feature works
  • I have updated documentation if needed
  • My changes don't introduce new warnings

Summary by cubic

Moves notification metrics from NotificationMetrics instruments to spans, with no change to the ten series emitted (part of #389).

Changes

  • Each delivery is a notification.deliver span; the throttle, each retry, and each subscription update emit notification.throttled, notification.retry, and notification.subscription_change spans.
  • The collector's signaltometrics connector derives the ten series from those spans, and label names become the span attribute names; the notifications dashboard moves with them.
  • NotificationService now takes a trace.Tracer instead of a meter, and NotificationMetrics is removed.