-
Notifications
You must be signed in to change notification settings - Fork 36
Description
Problem
Both Dashboard and Lite support monitoring multiple SQL Server instances, but collector schedule intervals are not properly per-server.
- Dashboard: Technically already per-server (each server's PerformanceMonitor DB has its own
config.collection_scheduletable), but theCollectorScheduleWindowUI doesn't show which server you're editing. - Lite: Truly global — a single
collection_schedule.jsonapplied to all servers.ScheduleManagerhas zero server awareness.RemoteCollectorService.RunDueCollectorsAsync()callsGetDueCollectors()once and applies the same list to all enabled servers.
There's no way to say "collect wait stats every 1 minute on the prod server but every 10 minutes on the dev box."
Dashboard: Title Fix
Add server name to CollectorScheduleWindow title and header so it's clear which server's schedule you're editing.
Files:
Dashboard/CollectorScheduleWindow.xaml— update TitleDashboard/CollectorScheduleWindow.xaml.cs— accept server display name in constructorDashboard/ServerTab.xaml.cs(~line 1553) — pass server name to constructor
Window title becomes: "Collector Schedules - SQL2022-Prod"
Lite: Per-Server Schedules
Data Model
New JSON schema for collection_schedule.json (version 2):
{
"version": 2,
"default_schedule": [
{ "name": "wait_stats", "enabled": true, "frequency_minutes": 1, "retention_days": 30, "description": "..." }
],
"server_overrides": {
"<server-guid>": {
"collectors": [
{ "name": "wait_stats", "enabled": true, "frequency_minutes": 5, "retention_days": 30 }
]
}
}
}default_schedule: baseline all new servers inheritserver_overrides: keyed byServerConnection.Id(GUID), full collector list per server (not sparse diff — simpler when new collectors are added in upgrades)- Descriptions omitted from overrides (inherited from defaults)
New model class: Lite/Models/ServerScheduleOverride.cs
ScheduleManager Refactoring
File: Lite/Services/ScheduleManager.cs
Replace _schedules list with _defaultSchedule + _serverOverrides dictionary + _serverRunState for per-server runtime tracking.
New public API:
| Method | Purpose |
|---|---|
GetSchedulesForServer(serverId) |
Returns override if exists, else copy of default |
GetDueCollectorsForServer(serverId) |
Replaces global GetDueCollectors() |
MarkCollectorRunForServer(serverId, collectorName, runTime) |
Per-server run tracking |
GetDefaultSchedule() |
Returns the default schedule list |
SetScheduleForServer(serverId, schedules) |
Creates/updates a server override |
RemoveServerOverride(serverId) |
Reverts server to default |
HasServerOverride(serverId) |
Check if server has custom schedule |
ApplyPresetForServer(serverId, presetName) |
Apply preset to one server |
ApplyPresetToDefault(presetName) |
Apply preset to the default schedule |
GetActivePresetForServer(serverId) |
Detect active preset for a server |
CleanupRemovedServers(activeServerIds) |
Remove orphaned overrides |
MergeNewDefaults must now apply to both _defaultSchedule and every entry in _serverOverrides.
RemoteCollectorService Changes
File: Lite/Services/RemoteCollectorService.cs
RunDueCollectorsAsync()(~line 238): MoveGetDueCollectorscall inside each server's task →GetDueCollectorsForServer(server.Id)RunCollectorAsync()(~line 399):MarkCollectorRun→MarkCollectorRunForServer(server.Id, ...)RunAllCollectorsForServerAsync()(~line 302): UseGetSchedulesForServer(server.Id)instead of global list
SettingsWindow Changes
File: Lite/Windows/SettingsWindow.xaml (Row 6) and .xaml.cs
Replace the DataGrid+preset section with a Server Schedule Summary Panel:
Collector Schedules
+------------------------------------------------+
| Server | Preset | Status |
| SQL2022-Prod | Aggressive | Customized | [Edit]
| SQL2019-Dev | Balanced | Default | [Edit]
| SQL2016-Legacy | Low-Impact | Default | [Edit]
+------------------------------------------------+
Default Schedule: [Balanced v] [Edit Default...]
[Apply Default to All Servers]
- Read-only DataGrid: server name, detected preset, "Default" vs "Customized" status
- Edit button per row opens
CollectorScheduleEditorWindow - Default preset selector + "Edit Default..." + "Apply Default to All"
Constructor adds ServerManager parameter. MainWindow.xaml.cs line 851 passes _serverManager.
New Window: CollectorScheduleEditorWindow
New files: Lite/Windows/CollectorScheduleEditorWindow.xaml and .xaml.cs
Modal dialog (900x600) for editing one server's schedule or the default.
+--------------------------------------------------+
| Collector Schedules - SQL2022-Prod |
| Server: SQL2022-Prod (192.168.1.50) |
| |
| Preset: [Balanced v] [ ] Use default sched |
| |
| +-----------------------------------------------+|
| |[x] Collector | Freq (min) | Ret (days) ||
| | wait_stats | 1 | 30 ||
| | query_stats | 1 | 30 ||
| | query_store | 5 | 30 ||
| | ... | | ||
| +-----------------------------------------------+|
| |
| [Copy from Server... v] [Copy from Default] |
| |
| [Save] [Cancel] |
+--------------------------------------------------+
Key behaviors:
- "Use default schedule" checkbox: When checked, no override exists — DataGrid is read-only/muted. Unchecking creates an override by copying the default.
- Preset ComboBox: Only active when not using default. Same presets (Custom, Low-Impact, Balanced, Aggressive).
- DataGrid: Same columns as current (Enabled, Collector, Frequency, Retention, Schedule display, Last Run per-server).
- "Copy from Server...": Dropdown of other servers, copies that schedule here.
- "Copy from Default": Resets to default schedule.
- Save/Cancel: Explicit save (matches Lite pattern).
- When editing the default: Title says "Default Collector Schedule", no "Use default" checkbox, no "Copy from Default" button.
Migration Path
Automatic on first load after upgrade:
LoadSchedules()detects missingversionfield → treats as v1- Copies legacy
collectorslist todefault_schedule - Sets
server_overrides = {} - Saves as v2, backs up old file as
.v1.bak - All servers inherit the default (same behavior as before until user customizes)
Implementation Phases
- Data layer:
ServerScheduleOverridemodel,ScheduleManagerrefactoring with migration - Collector dispatch:
RemoteCollectorServiceper-server dispatch - UI:
CollectorScheduleEditorWindow, SettingsWindow summary panel - Dashboard:
CollectorScheduleWindowtitle fix - Cleanup: Server deletion cleanup, migration testing