Skip to content

Ten viewer surfaces read data that has no /api/read endpoint, so neither the web dashboard nor the MCP can reach it #2484

Description

@erikdarlingdata

Split out of #2475, which named it but is not the place to fix it.

The web dashboard's per-server page now carries twelve sub-tabs reaching 61 of the service's 82 /api/read/* handlers (#2477). Three groups of viewer data remain unreachable from a browser, and only one of them is web work:

  • (a) served but unshown — the eight get_pg_* reads (blocked by the fleet payload carrying no target-engine discriminator), get_database_scoped_config (a nested databases[].settings[] the table renderer cannot draw), get_store_metrics (store-wide, no per-server home). Front-end and payload work, tracked on The web dashboard serves 82 reads and shows 23: the server page is 7 panels where the viewer has 65 tabs #2475.
  • (c) desktop-only by design — the plan viewer, query heatmap rendering, block-chain reconstruction, the interactive deadlock graph, and the grids' filter/export/repro/drill-down affordances. A standing product boundary, now stated in docs/uat-onboarding.md §3.4.
  • (b) — this issue. Data the WPF viewer reads that has no /api/read endpoint at all. No amount of front-end work reaches it, and it is invisible to the MCP surface too, so an agent asking about it gets nothing.

The list

Every one of these is a projection over data the store already holds — the viewer opens no connection to a monitored server and reads the same Postgres store the MCP tools do, so these are endpoints, not collectors. None needs new collection.

Viewer tab Reader Note
Queries › Query Store Regressions GetQueryStoreRegressionsAsync (ViewerDataService.QueryStoreRegressions.cs) Regression detection over query_store_stats. The only #2477 tab that is entirely unreachable rather than reduced.
Queries › Query Heatmap GetQueryHeatmapAsync (ViewerDataService.QueryHeatmap.cs) The read is portable even though the interactive plot is not — a bucketed table is a real answer. Needs a bucket-size decision.
Queries › Performance Trends (3 of 4 charts) GetProcedureDurationTrendAsync, GetQueryStoreDurationTrendAsync, GetExecutionCountTrendAsync (ViewerDataService.QueryTrends.cs) get_query_duration_trend exists and ships; these three are its missing siblings, same shape.
Blocking › Blocking Stats GetBlockingDurationStatsAsync, GetDeadlockSeverityStatsAsync (ViewerDataService.BlockingStats.cs) The whole tab. Duration distribution and deadlock severity over data get_blocking / get_deadlocks already return row-by-row.
Blocking › Trends (lock-wait lane) GetLockWaitTrendAsync (ViewerDataService.BlockingTrends.cs) LCK% per-second rates. get_wait_trend can chart one LCK type; this is the aggregate lane.
Blocking › Current Waits GetWaitingTaskTrendAsync, GetBlockedSessionTrendAsync (ViewerDataService.BlockingTrends.cs) The whole tab. get_waiting_tasks gives the snapshot rows, never the trend.
System Events › Significant Waits GetSignificantWaitsAsync (ViewerDataService.SystemEvents.cs) The one member of the system_health parse-on-read family with no get_health_parser_* twin — the other eight all have one, so this reads as an omission rather than a decision.
Collection Health › Collection Log GetRecentCollectionLogAsync (ViewerDataService.CollectionHealth.cs) get_collection_health serves the 7-day per-collector rollup; the raw per-run log has no read. This is also what Duration Trends charts, so one endpoint covers two tabs.
Collection Health › Duration Trends same reader
Daily Summary GetDailySummaryRangeAsync (ViewerDataService.DailySummary.cs) get_daily_summary serves ONE date. The range read behind the month calendar has no endpoint, so the web page can only ever show today.

Adjacent, same category, lower priority

Several viewer charts are the trend form of a read that ships only as a snapshot. Same "endpoint over collected data" shape, and each would upgrade a tab #2477 currently ships as partial:

GetCpuSchedulerTrendAsync, GetPlanCacheTrendAsync, GetFileIoThroughputTrendAsync, GetTempDbFileIoTrendAsync, GetLatchStatsTrendAsync / GetSpinlockStatsTrendAsync, GetMemoryClerkTrendsByTypesAsync, and the session-count trend behind Session Stats.

And two are multi-series forms of reads that exist as single-series: GetWaitStatsTrendsByTypesAsync (vs get_wait_trend, one wait type) and GetPerfmonTrendsByCountersAsync (vs get_perfmon_trend, one counter). #2477 ships single-select pickers for both, which is a real reduction: you cannot compare two waits on one chart.

Why it is worth doing

These are not only web gaps. /api/read/* is machine-derived from the MCP read catalog, so an absent endpoint is absent from both surfaces — an agent asked "was this server blocking more last Tuesday than today" has get_blocking and get_blocking_trend but no duration distribution, and cannot see the collection log at all. The viewer is currently the only way to that data, on a Windows desktop.

Suggested order, by what a UAT user asks for first: the collection log (two tabs, and it is the diagnostic people reach for when collection looks wrong), then Blocking Stats and Current Waits, then Significant Waits (a one-line omission in an otherwise complete family), then the Performance Trends siblings, then Query Store Regressions and the heatmap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions