-
[OPIK-6941] [BE] [FE] feat: workspace-level span metric aggregation in dashboards (#7365)
发布于
2026-07-13 15:02:45 +00:00 - [OPIK-6941] [BE] [FE] feat: workspace-level span metric aggregation in dashboards
Add a workspace metrics endpoint (POST /v1/private/workspaces/metrics/spans)
that aggregates span metrics (count, token usage, cost) across a set of
projects — empty set means all projects in the workspace — with optional
provider/model breakdown and configurable interval. The DAO builds the whole
series in SQL (groupArray) like the existing workspace cost query; the service
stays thin and returns WorkspaceMetricResponse. A dedicated
WorkspaceSpanMetricRequest keeps the shared WorkspaceMetricRequest contract
untouched.Frontend: the dashboard metric widget's Project field becomes a multi-select
(reusing ProjectsSelectBox). One project keeps the existing per-project
behavior and full metric set; two or more narrows the metric list to the span
trio and routes to the workspace endpoint. The form is otherwise identical to
main.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- feat(dashboards): workspace totals for the single-metric widget
Add multi-project support to the single-metric (stat card) widget, mirroring the
time-series widget: the Project field is a multi-select, and selecting two or more
projects narrows the metric list to the span totals (count, token usage, cost)
served by the workspace endpoint with interval=TOTAL, rendered as a single value.Extract the shared workspace-metric logic into dedicated modules to avoid
duplicating flow-specific data across widgets:- lib/dashboard/workspaceMetrics.ts: supported metric names, editor/stat options,
isWorkspaceMetric, and project-selection resolution (single vs workspace). - api/projects/useMetricData.ts: picks the per-project vs workspace metrics source,
so MetricChartContainer no longer branches inline.
The stats-endpoint metric catalog (metrics.ts) and useWorkspaceMetric are kept free
of cross-flow constants.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- feat(dashboards): span filters and duration percentiles for workspace metrics
Extend workspace-level span aggregation to match the per-project endpoint more
closely:- Span filters: WorkspaceSpanMetricRequest carries a
filterslist, bound in
getSpanMetric via FilterQueryBuilder (span + span-feedback-score strategies),
reusing the filter slots already present in the copied SPAN_FILTERED_PREFIX. The
time-series and single-metric widgets forward span filters to the workspace
endpoint in multi-project mode. - Duration percentiles: SPAN_DURATION joins the supported workspace span metrics,
computing quantiles(0.5, 0.9, 0.99) DB-side and fanning them into p50/p90/p99
series (single percentile per group when a provider/model breakdown is set). It
is exposed in the time-series widget only, since a percentile distribution has no
single-value stat-card representation.
Tests: duration parity vs the per-project endpoint, a filtered parity case proving
the filter narrows results, and validation that a token-usage or duration breakdown
without sub_metric returns 400.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- refactor(dashboards): drop workspace duration group-by; keep percentiles
Duration across projects is percentile-only (p50/p90/p99); grouping a percentile
by provider/model isn't needed. Remove the duration breakdown query and quantile
sub_metric handling; the service now rejects a duration request with a breakdown
(400), and the widgets hide the group-by control for duration in multi-project mode
and never send a breakdown for it. Group by and span filters remain for the other
workspace span metrics.Also fixes the filtered-parity test to type the filter list explicitly so it
compiles under ECJ.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- refactor(dashboards): scope workspace aggregation to span token usage only
Narrow the workspace span feature to a single metric — span token usage — with
provider/model grouping and span filters. Drop span count, span cost, and span
duration from workspace aggregation (they remain single-project only):- Backend: SUPPORTED_SPAN_METRICS is just SPAN_TOKEN_USAGE; removed the count/cost/
duration queries and DAO methods, and the service now returns 400 for any other
metric type. Grouping and filter wiring are unchanged. - Frontend: the time-series and stat-card metric lists expose only token usage in
multi-project mode; removed the now-dead duration-in-workspace guards and the
unused SPAN_COST metric-name entry.
Tests: SpanMetricsTest now covers token-usage parity, provider breakdown, filtered
parity, all-vs-subset, workspace isolation, and rejects the unsupported metrics.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- fix(dashboards): bound workspace "all projects" aggregation to a resolved project set
Address PR review feedback on workspace-level span metrics:
- Blocker (all-projects unbounded scan): the workspace endpoint resolves an
empty project set to every project id in the workspace up front, so the DAO
always queries a boundedproject_id IN (...)list that prunes on the spans
primary key instead of an unconstrained workspace-wide scan. This also
removes the 30s-refetch amplification, since each refetch is now bounded. - Frontend "All projects" is now an explicit, dynamic selection (allProjects
flag) that sends the empty "all" signal, rather than select-all expanding to
a capped/frozen list of currently-loaded ids (no silent under-count, no stale
snapshot). Kept distinct from the empty/not-configured state. - DRY: extracted the shared SPAN_FILTERED_PREFIX into SpanMetricsQueries, used
by both ProjectMetricsDAO and WorkspaceMetricsDAO with a parameterized project
predicate; drove the span filter-strategy add/bind passes from one list. - Fixed the stat-card span-filter error that never cleared in multi-project +
trace-source mode; dropped the unreachable SPAN_COUNT fallback and a stale
count/cost comment; documented the metrics-editor single-project asymmetry.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- fix(dashboards): source filters, group by, and usage keys for "all projects" widgets
In "all projects" mode there is no selected project, so the editor's representative
projectId was empty — which hid the usage-metrics field (blocking group-by for span
token usage) and starved the filter field and metadata autocompletes. Fall back to the
first project in the workspace (from the cache the project dropdown already populated) as
the representative for those project-scoped option lists, so filters and grouping are
usable when aggregating across all projects. The stored selections still apply to the
workspace-wide aggregation; only the option lists borrow a representative project.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- docs(dashboards): soften "all projects" scan-cost wording in workspace span metrics
Address thiagohora's follow-up review: the Javadoc on WorkspaceSpanMetricRequest
and the comment on WorkspaceMetricsService claimed the resolved-to-explicit
project set is "never an unconstrained workspace-wide span scan". That's
misleading for large tenants —project_id IN (<all ids>)reads roughly the
same granules as a full workspace scan, since the id/time window can't prune at
the primary-key level across many disjoint project prefixes. Reword both to note
the query is bounded to the workspace's projects but remains full-scan-equivalent
for tenants with many projects.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com
下载附件