Overview
Performance Inspector
Route runtime metrics (fetch/render) and Data Quality of the loaded dataset,
with hybrid server persistence: raw events with short retention (7 days) +
historical aggregates for fast analysis (avg / p95 / max / count per window).
Screenshot reference (user manual)
manual__performance-inspector__01.png: Performance Inspector dialog on a list with local sample and server trend. (status: unavailable — capture planned)
Prerequisite: application gate (mandatory)
All of the feature's additional logging is active only if the flag is true
in appsettings.json:
{ "AppSettings": { "enablePerformanceInspector": "true" } }- Editable from the appsettings-editor (App Runtime section) with
hot-reload effect: no restart.
- With the flag off: no DB writes, ingest/job/trend respond
enabled:false, the client sends nothing. The panel still shows the
local sample.
Per-route activation (metadata)
In the route's md_props_bag (metadata editor → props bag):
{
"qualityInspector": {
"persistence": {
"enabled": true,
"mode": "hybrid",
"retentionDays": 7,
"scope": "global+user"
persistence.enabled: enables metric collection + sending for the route and
the Performance button in the list caption-bar.
thresholds.slowFetchMs: threshold of theslow_metadatawarning (default 1500 ms).mode/retentionDays/scopedocument v1 (hybrid, 7 days,
global+user); retention is fixed in v1.
What is collected
| Metric | Content |
|---|---|
fetch | ms duration of the DataSource data cycle (getData) |
render | ms from data publication to the rendered frame |
dq | Data Quality summary of the loaded dataset: completeness %, duplicates, anomalies (z-score>3), severity |
Only technical metrics and summaries: never row data. Sending is batched
(2s debounce), asynchronous and best-effort: a failed ingest does not impact the UI.
Server persistence
sys_route_metrics_events: raw events, 7-day retention.sys_route_metrics_agg: aggregates perhour/daybucket and
global/user scope (avg, p95 nearest-rank, max, count, warning_count).
- Job
route_metrics_job(scheduler, every 5 minutes,action_type 3):
idempotent recomputation of the recent buckets + raw cleanup. Registration:
pwsh -File scripts/scaffold-route-metrics-scheduler.ps1UI panel
Performance button in the list caption-bar (visible only with
qualityInspector.persistence.enabled): opens the dialog with
- latest local sample: fetch ms, render ms, completeness, duplicates,
anomalies + slow metadata warning;
- server historical trend (latest hourly windows) with scope toggle
Global / My user and metric fetch / render / dq.
API
GET api/route-metrics/status—{ enabled }(gate).POST api/route-metrics/ingest— event batch{ events: [...] }. Without a valid session the events are discarded (200 response withingested: 0).GET api/route-metrics/trend?route=&scope=global|user&metric=&bucket=hour|day&userId=— latest 50 windows.POST api/route-metrics/admin/run-job— runs aggregation+retention immediately (administrators only since 1.7.13).GET api/route-metrics/routes— list of scaffolded routes with config and metrics status (dashboard).POST api/route-metrics/route-config— enables/disables collection for a route (admin).GET api/route-metrics/series?routes=&metric=&bucket=&from=&to=— multi-route aggregated series for the chart.
Administrative dashboard
Menu entry Administration → Route metrics (route /route-metrics-dashboard,
registered with scripts/scaffold-route-metrics-dashboard-menu.ps1, idempotent on
all DBMS): centralized analysis and configuration page.
- List of all scaffolded routes (non-system): the checkbox
enables/disables metric collection for the route (writes
qualityInspector.persistence.enabled into the md_props_bag and invalidates
the metadata cache — admin only) and at the same time includes/excludes the
series from the chart. The green dot marks routes that already have recorded
metrics.
- Filters: date range,
hour/daygranularity,fetch/render/dqmetric,
avg/p95/max value, Global / My user scope.
- Multi-series line chart (one series per enabled route) on the aggregated buckets.
Dedicated APIs: GET api/route-metrics/routes, POST api/route-metrics/route-config
(admin), GET api/route-metrics/series?routes=&metric=&bucket=&from=&to=.
Limits (v1)
- Fixed 7-day retention; UI trend buckets: hourly.
- DQ computed on the loaded dataset (current page), not on the whole table.
- The events'
userIdis declared by the client (telemetry, not a security
surface).