Repository navigation
Settable blocking bands, so the colours agree with the alerts (#6927) - #6938
Merged
Merged
Conversation
A threshold override can now be set for a server tag. Precedence is database, then server, then the deepest tag the server is under (the notification routes' own rule), then global. Adds V227, the MCP tag argument, the get_alert_settings tag source, the Viewer and web Admin tag rows, and tests.
…ade and the settings round trip (#6927) The fleet total was banded as one rate against the per-server tiers, so ten servers at 3 events an hour (none even Warning) made the tile Critical. The roll-up now takes the worst card band per signal, in the same fields. Adds live tests for the V228 upgrade on a store with a settings row and for update_alert_settings and get_alert_settings with the critical-below-warn refusal, and moves the settings column pins from 86 to 90.
… use Assert.Single in the tag scope test
… rule in the server view (#6926) LoadAsync now throws when the tag tables could not be read, so the worker keeps the whole snapshot in force instead of installing one with no tag winners until the next config change. get_alert_settings filtered tag rows through its own known-key and integer checks. It now calls the loader's Accept, so a deeper tag whose value is outside the key's bounds is skipped there as it is in the engine, and the view names the tag the engine applies.
#6927) Nothing read it: the service, the viewer and the MCP tools all read the tiers through BlockingBandStore. The config fields it wrapped are still bound by the seed insert and the store load, so they stay.
…e read from the store source (#6926) V227 adds a nullable column, two CHECKs and a partial unique index to the operator-written config.config_threshold_overrides table, a handful of rows, so it is declared SetsTheFloor false and the lock-wait multiple stays 5. The tag-name read in the override tool now uses postgres.CreateCommand like its sibling reads, which is the store receiver the read-deadline census recognises.
erikdarlingdata
marked this pull request as ready for review
October 30, 2026 01:09
1 of 3 tasks
Closed
Merged
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claude posting for Erik Darling.
Closes #6927.
Draft on purpose: it must not merge before the current release is published.
Why
The blocking colour on the Fleet Overview, the Overview tab and the Daily Health Calendar came from compile-time constants (warn at 5 reports per hour or a 10 s block, critical at 20 per hour or a 60 s block). An operator who tunes the blocking alert to their workload still saw red. The fleet totals row also coloured the Deadlocks tile critical and the Blocking tile warning on any non-zero count.
What changes
PerformanceMonitor.Common: newBlockingBandThresholds(four tiers, clamped on read, defaults equal today's constants) and floors and ceilings beside the deadlock ones.ServerHealthClassifier.BlockingSeveritytakes an optional tiers argument,ServerHealthMetrics.BlockingBandThresholdsandDailyHealthThresholds.BlockingBandscarry them. Lite passes nothing and keeps the constants.blocking_warn_per_hour(5),blocking_critical_per_hour(20),blocking_warn_wait_seconds(10) andblocking_critical_wait_seconds(60) toconfig_alert_settings, idempotent (ADD COLUMN IF NOT EXISTS).StorageVersionis 228, the viewer schema probe andMapProbedSchemaVersionhave a V228 arm, and the rung rewind list has the V228 entry. Noprovision-roles.sqlchange: V120 added none either, the existing table-level grants cover new columns.DarlingConfig,DarlingAlertSettings.BlockingBandThresholds, the store seed and read inStoreConfigProvider,get_alert_settings(health_bands.blocking_*),update_alert_settings(bounds 1 to 10000 per hour and 1 to 86400 seconds, critical below warn refused in the same body or against the stored other value, nothing written on refusal).BlockingBandStore): fleet cards andget_fleet_overview(including the worst-first re-band), the fleet sweep and its evidence thresholds,get_daily_healthand the calendar, the Viewer Overview card, calendar and Settings window (four boxes, validated, restore defaults).total_blocking_severityandtotal_deadlock_severity, and each is the worst band among the cards for that signal, the classification the cards already show, computed where the roll-up is built.fleet.jscolours the two tiles from them. A fleet sum is never banded as one server's rate: ten servers at 3 events an hour (no card even Warning at the default 5) no longer turn the tile Critical.Test plan
Runs on a throwaway PostgreSQL cluster (port 55927, stopped afterwards),
DARLING_CONFIGpointing at a scratch file.BlockingBandTiersTests,ServerHealthClassifierTests,DailyHealthBandTests,DarlingMcpAlertToolsTests,ConfigSeedStatementArityTests, plus the newBlockingBandSettingsLiveTests,ClientTimeoutsSettingsSurfaceTestsandClientTimeoutsSettingsLiveTests: Total 165, Failed 0.Stage=Guardtrait: Total 4478, Failed 3. The three are the dense-ladder checks (CollectorStallProbeStoreTests,StoreLogSelfMonitoringStoreTests,PgCpuCapacityHeadroomTestsTheRungIsRegistered...). They fail only because this branch has V228 and dev tops at V226: V227 is Hold alert threshold overrides for a server tag (#6926) #6939's. That was before the merge with V227 below, and CI runs them again on the merged head.BlockingBandSettingsLiveTestscovers the V228 upgrade on a store whose settings row exists (defaults 5, 20, 10, 60, the operator's deadlock tier untouched) and theupdate_alert_settings/get_alert_settingsround trip, including critical-below-warn refused with nothing written (in one body, and lone against the stored value) and a value below 1 refused.ClientTimeoutsSettingsSurfaceTestsonly.playwright-cli, the service built from this branch against the scratch cluster, two screenshots, one wide and one at phone width): with ten servers at 3 events an hour the Blocking tile at 30 is not coloured (defaults), and Warning with the bands set to 2 and 6 (every card Warning), and Critical once one card passes 6. At 390 px wide the tiles wrap and nothing scrolls sideways. The Admin page shows the four fields at 5, 20, 10 and 60, then 2, 6, 30 and 120 after a save throughupdate_alert_settingsand a reload. The Admin page cannot set them (it is read only), so the save and the refusals went through the MCP tool: critical 1 with warn 2 and warn 200 with critical 100 both came backinvalidwith nothing written.StorageVersion.SchemaVersionis 228, V228 sits after V227, both rungs keep their rewind artifacts, probe sentinels and census entries. V228 adds only constant-default NOT NULL columns and is not a data-moving rung, so the census needed no new declaration. On a throwaway cluster:MigrationDataMovingRungCensusPins,McpReadCommandTimeoutTests,RungRewindArtifacts,ViewerSchemaVersionGateTests, every*Census*,*Ratchet*,*Migration*,*Rung*and*SchemaVersion*class,BlockingBand*,ClientTimeoutsSettingsSurfaceTests,DarlingMcpAlertToolsTests,ThresholdOverride*,ViewerSweepPressureLiveTests: Total 1385, Failed 0. The three dense-ladder failures above no longer apply.ThresholdOverrideTagScopeTests.V227_OnAStoreThatHoldsServerOverrides_KeepsThem_AndTakesTagRowsasserted the newest stamped version was 227 and now compares withStorageVersion.SchemaVersion.Considered, not added
Notes for whoever merges
CA1068inViewerDataService.CollectionHealth.cs, a file this change does not touch.Click-through attempt (Viewer Settings window, Overview card, calendar)
Not done. The viewer cannot run as a second copy: it is single-instance, and a launch with
--configpointing at a throwaway store handed off to the viewer already running on this machine and exited (its log line:Handoff ... -> Surface). That running viewer was not touched beyond that surface request, and no connection or setting in the real profile was changed. So these remain to be clicked, on a machine with no other viewer running:What was checked instead: the service from this branch on a throwaway PostgreSQL cluster (own config file, first log line named it). A fresh store came up with the V228 columns at 5, 20, 10 and 60.
update_alert_settingswithhealth_bands.blocking_warn_per_hour8 andblocking_critical_per_hour4 was refused with "must not be lower than", nothing written. A valid pair (8/30 per hour, 15/90 seconds) was accepted and read back from the store.Changes after a code check
DarlingAlertSettings.BlockingBandThresholds. It had no reader: the service, the viewer and the MCP tools all read the tiers throughBlockingBandStore. The config fields it wrapped stay, because the seed insert and the store load still bind them.BlockingBandTiersTestsandServerHealthClassifierTests: Total 75, Failed 0. Nothing else in the tests or the source names the removed property. Not re-run after the final rebase onto the branch.