Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **Memory Pressure Events in Lite** — the collector, chart, and `get_memory_pressure_events` MCP tool previously only in the Full Edition are now available in Lite ([#865])
- **Grid auto-scrolling** in Lite and Dashboard ([#843]) — thanks [@ClaudioESSilva](https://github.com/ClaudioESSilva)
- **`Off` collection preset** — `config.apply_collection_preset @preset_name = N'Off'` disables every collector in one call. Pair it with a second Agent job that applies a non-`Off` preset at the start of your active window to get overnight / quiet-hours scoping without writing scheduler code. Non-`Off` presets now also set `enabled = 1` across the board so the switch reliably resumes collection ([#888])

### Changed

Expand Down Expand Up @@ -47,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#865]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/865
[#867]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/867
[#872]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/872
[#888]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/888

## [2.7.0] - 2026-04-13

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ All release binaries are digitally signed via [SignPath](https://signpath.io)

## What You Get

🔍 **32 specialized T-SQL collectors** running on configurable schedules with named presets (Aggressive, Balanced, Low-Impact) — wait stats, query performance, blocking chains, deadlock graphs, memory grants, file I/O, tempdb, perfmon counters, FinOps/capacity, and more. Query text and execution plan collection can be disabled per-collector for sensitive environments.
🔍 **32 specialized T-SQL collectors** running on configurable schedules with named presets (Off, Aggressive, Balanced, Low-Impact) — wait stats, query performance, blocking chains, deadlock graphs, memory grants, file I/O, tempdb, perfmon counters, FinOps/capacity, and more. Query text and execution plan collection can be disabled per-collector for sensitive environments. Switch presets with a pair of SQL Agent jobs to get quiet-hours / overnight windows without writing any code.

🚨 **Real-time alerts** for blocking, deadlocks, and high CPU — system tray notifications, styled HTML emails with full XML attachments, and webhook notifications for external integrations

Expand Down
70 changes: 55 additions & 15 deletions install/41_schedule_management.sql
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,18 @@ GO

/*
Apply a named collection preset
Changes all scheduled collector frequencies in one operation.
Does not modify enabled/disabled state or daily/on-load collectors.

Valid preset names: Aggressive, Balanced, Low-Impact
Valid preset names: Off, Aggressive, Balanced, Low-Impact

Off sets enabled = 0 on every row in config.collection_schedule and changes
nothing else — no frequency edits. The other three set enabled = 1 on every
row (so switching back from Off reliably reactivates collection) and update
frequency_minutes for the collectors they list. Daily/on-load collectors
that aren't in the preset keep their existing frequency.

Heads up: applying a non-Off preset overrides any manual
UPDATE config.collection_schedule SET enabled = 0 on a specific collector.
If that matters in your environment, re-disable it after switching presets.
*/
IF OBJECT_ID(N'config.apply_collection_preset', N'P') IS NULL
BEGIN
Expand All @@ -169,9 +177,33 @@ BEGIN
@rows_updated bigint = 0;

BEGIN TRY
IF @preset_name NOT IN (N'Aggressive', N'Balanced', N'Low-Impact')
IF @preset_name NOT IN (N'Off', N'Aggressive', N'Balanced', N'Low-Impact')
BEGIN
RAISERROR(N'Invalid preset name "%s". Valid presets: Aggressive, Balanced, Low-Impact', 16, 1, @preset_name);
RAISERROR(N'Invalid preset name "%s". Valid presets: Off, Aggressive, Balanced, Low-Impact', 16, 1, @preset_name);
RETURN;
END;

/*
Off disables every collector and exits. No frequency table needed.
Pair with a second Agent job that applies a non-Off preset at the
start of your active window to resume collection.
*/
IF @preset_name = N'Off'
BEGIN
UPDATE
config.collection_schedule
SET
enabled = 0,
modified_date = SYSDATETIME();

SET @rows_updated = ROWCOUNT_BIG();

IF @debug = 1
BEGIN
RAISERROR(N'Applied "Off" preset — %I64d collectors disabled', 0, 1, @rows_updated) WITH NOWAIT;
END;

PRINT 'Applied "Off" collection preset (' + CONVERT(varchar(10), @rows_updated) + ' collectors disabled)';
RETURN;
END;

Expand Down Expand Up @@ -303,20 +335,27 @@ BEGIN
END;

/*
Apply the preset to all matching collectors.
Only updates frequency - does not change enabled/disabled state.
Skips daily/on-load collectors not in the preset.
Re-enable every collector first so a switch from Off → named preset
reliably resumes collection, including daily/on-load collectors that
aren't in the preset frequency table.
*/
UPDATE
config.collection_schedule
SET
enabled = 1,
modified_date = SYSDATETIME()
WHERE
enabled = 0;

/*
Apply the preset frequencies to the collectors it lists.
Daily/on-load collectors not in the preset keep their existing frequency.
*/
UPDATE
cs
SET
cs.frequency_minutes = p.frequency_minutes,
cs.next_run_time =
CASE
WHEN cs.enabled = 1
THEN SYSDATETIME()
ELSE cs.next_run_time
END,
cs.next_run_time = SYSDATETIME(),
cs.modified_date = SYSDATETIME()
FROM config.collection_schedule AS cs
JOIN @preset AS p
Expand Down Expand Up @@ -416,11 +455,12 @@ PRINT '';
PRINT 'Available procedures:';
PRINT '- config.update_collector_frequency - Change frequency for specific collector';
PRINT '- config.set_collector_enabled - Enable/disable specific collector';
PRINT '- config.apply_collection_preset - Apply a named preset (Aggressive, Balanced, Low-Impact)';
PRINT '- config.apply_collection_preset - Apply a named preset (Off, Aggressive, Balanced, Low-Impact)';
PRINT '- config.show_collection_schedule - Display current schedule';
PRINT '';
PRINT 'Examples:';
PRINT ' EXECUTE config.apply_collection_preset @preset_name = N''Aggressive'', @debug = 1;';
PRINT ' EXECUTE config.apply_collection_preset @preset_name = N''Balanced'';';
PRINT ' EXECUTE config.apply_collection_preset @preset_name = N''Low-Impact'';';
PRINT ' EXECUTE config.apply_collection_preset @preset_name = N''Off''; -- disables all collectors';
GO
Loading