Skip to content

feat(workflow_engine): Document metric monitor aggregates in the API schema - #129451

Draft
sentry-junior[bot] wants to merge 5 commits into
masterfrom
feat/metric-monitor-aggregate-schema
Draft

sentry-junior[bot] wants to merge 5 commits into
masterfrom
feat/metric-monitor-aggregate-schema

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

BaseDetectorTypeValidator.data_sources is a plain ListField, so the public schema types it as Array<unknown>. Clients such as @sentry/api and the Sentry CLI copy the accepted aggregate values from backend source, and their copies drift.

This gives the field an explicit schema without changing how it is validated: each item is a oneOf of the metric data sources (Errors, Spans, Logs, Application Metrics, Crash Rate). Each branch is keyed by dataset and event_types, and its aggregate gets an enum or pattern built from the constants the validator already checks against:

Branch aggregate Source
Errors (events) enum: count(), count_unique(user|dist|release) and their tags[sentry:*] forms TRANSLATABLE_COLUMNS
Spans (trace_item_span) pattern of EAP_FUNCTIONS calls EAP_FUNCTIONS ∩ SPAN_DEFINITIONS
Logs (trace_item_log) same, without p100 and the formulas EAP_FUNCTIONS ∩ OURLOG_DEFINITIONS
Application Metrics (trace_item_metric) pattern of trace metric functions, or equation|… TRACE_METRICS_DEFINITIONS
Crash Rate (metrics) the backend regex CRASH_RATE_ALERT_AGGREGATE_RE

CRASH_RATE_ALERT_AGGREGATE_RE loses a redundant \, escape. Python treats \, and , the same, but ECMAScript u-mode regexes (which ajv and other JSON Schema validators use) reject \,. The help text also drops the percentile(...) examples, because EAP spans don't define percentile. A test checks that every JSON example in the help text matches exactly one branch, so the prose and the schema can't drift apart again.

EAP_FUNCTIONS gains performance_score and opportunity_score. The span monitor UI has offered both since #112146, but they were never added to the allowlist: opportunity_score fell through to legacy Discover validation and was rejected as an invalid function, and performance_score passed only through an older Insights shortcut.

To stop this drift recurring, a test parses the monitor form's TypeScript aggregate lists (ALLOWED_EXPLORE_VISUALIZE_AGGREGATES, ADDITIONAL_EAP_AGGREGATES, LOGS_EXCLUDED_AGGREGATES) and checks that each offered function matches the schema branch for its dataset, the same way test_frontend_datadog_sites_match_backend checks the Datadog site list. It found one more gap: the logs form offers epm, eps, p100, performance_score, and opportunity_score, which the logs definitions don't define, so building the subscription request fails with "Unknown function". The test lists those as known gaps until the frontend stops offering them.

Scope decisions (also documented in the metric_data_source_schema module docstring):

  • Metric data sources only. The detector endpoints share one request schema across detector types, but the public API only documents metric_issue monitors. Cron and uptime data sources are still accepted at runtime and aren't described. A catch-all branch would make the oneOf match anything, so clients couldn't use it to check aggregates.
  • Transactions dataset left out. It's deprecated, and creating transaction alerts is already blocked behind discover-saved-queries-deprecation.
  • Aggregates are what monitors support, not everything the validator tolerates. Errors lists count() and count_unique() over the allowlisted columns. The backend also accepts other Discover functions when the test query runs. Spans leaves out http_response_rate, cache_miss_rate, and count_scores. They pass through a 2024 shortcut for span metrics alerts, but since 2025 Insights creates monitors with equivalent count() queries instead, because Explore and alerts don't support these functions.
  • snake_case keys (event_types, time_window), the same as every other field drf-spectacular generates in this schema. The API accepts both cases.

Fixes #129450
Fixes ENG-8945

via @BYK.

--

View Session in Sentry

…schema

The detector data_sources field was a plain ListField, so the generated OpenAPI schema typed it as an array of unknown items. Clients copied the accepted aggregate values from the backend source and drifted from it.

Document each metric data source (errors, spans, logs, application metrics, crash rate) as a oneOf branch keyed by dataset and event types. Build each aggregate enum or pattern from the constants the validator checks against: EAP_FUNCTIONS intersected with the dataset definitions, TRANSLATABLE_COLUMNS, and CRASH_RATE_ALERT_AGGREGATE_RE. Drop the stale percentile() examples from the help text, since EAP spans don't define percentile.

Refs #129450

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
@linear-code

linear-code Bot commented Nov 1, 2026

Copy link
Copy Markdown

ENG-8945

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 1, 2026

@BYK BYK 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.

Transactions dataset left out. It's deprecated, and creating transaction alerts is already blocked behind discover-saved-queries-deprecation. A client that validates requests strictly against this schema could no longer send it. Should it get a loose branch?

Nope, this is good.

Only metric data sources are documented. The same request schema serves every detector type, but the public docs only advertise metric_issue, so cron and uptime payloads aren't described. Is that acceptable, or should there be a permissive fallback? A fallback would mean anyOf, which makes the union useless for validation.

Can you provide more context on this as I don't fully understand the implications.

Errors enum is the practical set, not an exhaustive allowlist. The backend accepts any Discover function whose column is empty or allowlisted, as long as the test query runs. Spans similarly accept a few Insights functions outside EAP_FUNCTIONS, such as http_response_rate(5). The schema documents the explicit alerting allowlist.

Is there a decision needs to be made here? If yes, I don't understand and need more context.

Nested properties are snake_case (event_types, time_window), which matches how drf-spectacular names every other field in this schema. The API accepts both cases.

What's the other case?

sentry-junior Bot and others added 4 commits November 1, 2026 18:48
…rrides

Detector validator subclasses override data_sources with their own ListField, which mypy rejected once the base field became DataSourcesField.
…n monitors

The monitor UI offers both functions for span monitors since #112146, but they were missing from EAP_FUNCTIONS. opportunity_score fell through to legacy Discover validation and was rejected as an invalid function. performance_score passed only through the older Insights shortcut.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
…hema

Document why only metric data sources are described, and which aggregates the validator accepts that the schema leaves out on purpose.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
…ource schema

The monitor form lists its span and log aggregates in TypeScript, separately from EAP_FUNCTIONS, and the two drifted: the UI offered opportunity_score while the backend rejected it. Parse the frontend lists and check that each offered function matches the schema branch for its dataset. The schema is built from EAP_FUNCTIONS and the dataset definitions, so this covers both.

The logs form also offers epm, eps, p100, performance_score, and opportunity_score, which the logs definitions don't define. They are listed as known gaps until the UI stops offering them.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>

This branch has not been deployed

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose metric monitor aggregates in the OpenAPI schema

1 participant