feat(explore): add --metric flag for auto-resolving tracemetrics format#927
feat(explore): add --metric flag for auto-resolving tracemetrics format#927MathurAditya724 wants to merge 10 commits intomainfrom
Conversation
sentry explore --dataset metrics sends metricsEnhanced to the Events API, which requires the tracemetrics format: aggregation(value,metric_name,metric_type,unit). Without validation, standard aggregates like count() or avg(measurements.fcp) silently fail with opaque 400 errors from the API. - Add validateMetricsFields() that detects non-tracemetrics aggregates and throws a ValidationError with format guidance and working examples - Fix the wrong metrics example in explore.ts fullDescription (was using span-style avg(measurements.fcp) which doesn't work with metricsEnhanced) - Fix the wrong metrics example in docs fragment with correct tracemetrics examples including LLM token usage and tag breakdown patterns
|
Codecov Results 📊✅ 6704 passed | Total: 6704 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
All tests are passing successfully. ❌ Patch coverage is 62.90%. Project has 13618 uncovered lines. Files with missing lines (3)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 76.67% 76.61% -0.06%
==========================================
Files 303 304 +1
Lines 57997 58213 +216
Branches 0 0 —
==========================================
+ Hits 44463 44595 +132
- Misses 13534 13618 +84
- Partials 0 0 —Generated by Codecov Action |
- Detect when user runs --dataset metrics without -F and throw a helpful ValidationError instead of sending incompatible defaults to the API - Add 4 tests: rejects standard aggregates, accepts tracemetrics format, requires explicit fields, allows non-aggregate tag fields
80e524b to
401fb61
Compare
|
Ready for review. All required CI checks pass (Unit Tests, E2E, Lint & Typecheck, Build, CodeQL). The Self-review found one bug that's now fixed: the original commit would throw a confusing |
00a12eb to
489a5b9
Compare
Add --metric (-m) flag that auto-discovers a metric's type and unit via
the Events API, then constructs the tracemetrics aggregate format
automatically. This eliminates the need to know the arcane
aggregation(value,name,type,unit) syntax.
Example:
sentry explore my-org/seer -F gen_ai.request.model -m llm.token_usage \
--dataset metrics --period 7d
Instead of:
sentry explore my-org/seer -F gen_ai.request.model \
-F "sum(value,llm.token_usage,distribution,none)" \
--dataset metrics --period 7d
- Add queryMetricsMeta() to discover.ts — queries Events API with
metric.name/type/unit fields (same technique as Sentry Explore UI)
- Add src/lib/metrics-transform.ts with resolveMetricField() and
makeTracemetricsAggregate() helpers
- Add --agg flag (default: sum) to control aggregation function
- Wire auto mode into explore func() — grouping fields from -F are
preserved alongside the auto-constructed aggregate
- Update error message for bare --dataset metrics to mention --metric
- Add 10 unit tests for metrics-transform, 3 integration tests for
--metric flag in explore
7ceca6b to
9832013
Compare
| return fieldList.find((f) => f.includes("(") && f.includes(")")); | ||
| } | ||
|
|
||
| /** True when the field looks like an aggregate call: `fn(...)`. */ |
There was a problem hiding this comment.
Pagination hints omit new --metric and --agg flags
Medium Severity
appendFlagHints picks only "dataset" | "environment" | "sort" | "query" | "period" | "field" | "limit" from ExploreFlags, omitting the new metric and agg properties. When a --metric query has more than one page of results, the pagination hint (e.g., sentry explore my-org/ -c next --dataset metrics) won't include -m or --agg, so copy-pasting it will hit the "requires --metric or explicit --field flags" validation error instead of fetching the next page.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 54ad40b. Configure here.
There was a problem hiding this comment.
fixed in 6ea7639 — appendFlagHints now includes metric and agg in its Pick type and emits -m / --agg flags when set.
There was a problem hiding this comment.
fixed in 6ea7639 — appendFlagHints now picks metric and agg from ExploreFlags and emits -m / --agg in pagination hints.
Two bugs caught during review: 1. --metric without --dataset metrics warned but didn't actually set dataset to metricsEnhanced, sending the tracemetrics aggregate to the wrong dataset 2. Metadata discovery hardcoded 7d statsPeriod, ignoring the user's --period flag — older metrics wouldn't appear in discovery results
54ad40b to
1477279
Compare
|
Review pass found and fixed two bugs:
Added a test for the dataset auto-switch behavior. All CI checks pass (Lint & Typecheck, Unit Tests, CodeQL, warden). |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f645f2a. Configure here.
| statsPeriod: metaParams.statsPeriod, | ||
| project, | ||
| }) | ||
| ); |
There was a problem hiding this comment.
Absolute time ranges silently ignored for metric discovery
Medium Severity
When the user specifies an absolute time range (e.g., --period "2026-04-01..2026-05-01"), timeRangeToApiParams() returns { start, end } with no statsPeriod. The code only passes metaParams.statsPeriod to queryMetricsMeta, which is undefined for absolute ranges, causing it to silently fall back to "7d". The start/end params are completely dropped because queryMetricsMeta doesn't accept them. This means metric discovery searches the wrong time window, potentially failing to find the metric and throwing a misleading "not found" error.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f645f2a. Configure here.
There was a problem hiding this comment.
good catch — fixed in 320e10a. queryMetricsMeta now accepts start/end and the call site spreads the full timeRangeToApiParams result instead of cherry-picking statsPeriod.
When --period specifies an absolute range (e.g. 2026-04-01..2026-05-01),
timeRangeToApiParams returns {start, end} with no statsPeriod. Previously
only statsPeriod was forwarded to queryMetricsMeta, causing it to silently
fall back to 7d and potentially miss the target metric.
Previously queryMetricsMeta fetched a single page (100 results) and discarded the cursor, silently truncating the metric list for large orgs. Now uses the same pagination loop as queryEvents, bounded by MAX_PAGINATION_PAGES.
…tive appendFlagHints was reading the original flags.field, which included aggregate fields that get silently dropped from the query when --metric is set. The hint now mirrors the same filtering, so it accurately reflects the executed query.
When --metric auto-switches dataset to metricsEnhanced, the pagination hints now reflect the actual dataset so subsequent paginated requests include --dataset metrics.


sentry explore --dataset metricsmaps tometricsEnhancedon the Events API, which requires the tracemetrics comma-separated format:aggregation(value,metric_name,metric_type,unit). Without validation, standard aggregates likecount()oravg(measurements.fcp)silently fail with opaque 400 errors — making the CLI unusable for metrics queries (both for humans and AI agents).This adds
validateMetricsFields()to catch invalid aggregate formats early with a clear error message showing the correct syntax, and fixes the wrong metrics examples in help text and docs that were showing span-style aggregates.Changes
validateMetricsFields()insrc/commands/explore.ts— detects non-tracemetrics aggregates when--dataset metricsand throwsValidationErrorwith format guidanceexplore.tsfullDescription(wasavg(measurements.fcp), now shows correct tracemetrics format)docs/src/fragments/commands/explore.mdwith working examples (LLM token usage, tag breakdowns)Testing
bun test test/commands/explore.test.ts— 29 pass, 1 pre-existing fail (missing generatedapi-schema.json)biome check src/commands/explore.ts— cleantsc --noEmit— no new errors from changes