Repository navigation
The web dashboard serves 82 reads and shows 23: the server page is 7 panels where the viewer has 65 tabs #2475
Description
The desktop viewer's per-server surface is a TabControl with 65 TabItems across 38 ViewerServerTab.*.cs partials. The web dashboard's #/server/{name} is one scroll of seven panels: Overview, CPU, Wait Stats, Active Queries, Memory Trend, File I/O Latency, Collection Health.
That is not a backend gap. The service already dispatches 82 read handlers at GET /api/read/{name} (DarlingWebEndpoints.BuildReadDispatch), and wwwroot/js/panels.js is already a generic renderer over them — renderPanel({read, params, viz, span}) with a four-kind viz registry. Of those 82 reads, the built-in web pages reach 23. The other 59 are served, documented in /api/catalog, reachable by hand-typing a URL, and surfaced nowhere a UAT user will find them.
The specific shape of the problem:
- A user who wants to know why a server is amber has no memory clerk list, no resource semaphore, no plan-cache breakdown, no scheduler pressure, no latch or spinlock stats, no blocking or deadlock detail, no
system_healthparse, no default trace, no configuration snapshot, no configuration change history, and no configuration audit — all of which the store holds and the service already serves. - The single time window is baked into each panel's descriptor (
hours_back: 4for CPU,24for everything else). The desktop viewer has a toolbar range picker; the web page has nothing, so a reader investigating an incident from Tuesday cannot look at Tuesday. - Two reads are unreachable from a browser at all because they require a parameter no UI collects:
get_perfmon_trendneeds acounter_name,get_wait_trendneeds await_type. The desktop viewer has a picker for each.
What is genuinely not portable, and should be said rather than imitated
Some of the 65 are desktop things and a web imitation of them would be worse than an honest absence:
- Plan Viewer, Get Actual Plan (re-run), View Cached Plan — need a plan renderer and a Stage-2 command back to the monitored server. The web seat is read-only over collected rows and has neither.
- Current Active Queries — the entire tab is an on-demand
fetch_active_queriescommand; there is nothing collected to render. - Query Heatmap, Block Chain, the interactive deadlock graph — interactive plots/graph views.
- The cross-cutting desktop affordances: chart context menus, Copy Repro Script, CSV export, right-click drill-down to a ±30-minute window.
Also missing on the read side (this part IS backend work)
Seven desktop tabs have no /api/read handler at all, so no amount of front-end work reaches them:
| Desktop tab | Reader with no MCP read |
|---|---|
| Queries > Query Store Regressions | GetQueryStoreRegressionsAsync |
| Queries > Query Heatmap | GetQueryHeatmapAsync |
| Queries > Performance Trends (3 of its 4 charts) | GetProcedureDurationTrendAsync, GetQueryStoreDurationTrendAsync, GetExecutionCountTrendAsync |
| Blocking > Blocking Stats | GetBlockingDurationStatsAsync, GetDeadlockSeverityStatsAsync |
| Blocking > Trends (the lock-wait lane) | GetLockWaitTrendAsync |
| Blocking > Current Waits | GetWaitingTaskTrendAsync, GetBlockedSessionTrendAsync |
| Collection Health > Collection Log + Duration Trends | GetRecentCollectionLogAsync |
And one that has a read whose SHAPE the web renderer cannot use: get_database_scoped_config returns databases[].settings[], a nested array, which vizTable cannot render — it needs either a flattened projection or a nested-table viz.
And one the fleet payload blocks
DarlingFleetReader.FleetServerCard carries engine_edition — the SQL Server SERVERPROPERTY('EngineEdition') — and no CollectorTargetEngine discriminator. So the browser cannot tell a PostgreSQL target from a SQL Server one, and the eight get_pg_* reads have no honest home on a per-server page: a PostgreSQL panel added today would render on every SQL Server in the fleet, permanently empty. Adding the discriminator to the fleet payload is the prerequisite for any PostgreSQL surface in the web dashboard.
Activity
Follow the descriptors: repoint two pins, and carry the band's reason (…
UAT onboarding 3.4: the absences that are no longer absent (#2475)
An empty trend is not a warming-up trend (#2475)
UAT 3.4: point the no-endpoint list at its issue (#2475)
One fetch per read per tab, and the count in the headline (#2475)
Web server page: eleven sub-tabs over the existing renderPanel seam (e…