Repository navigation
Add the authored Blocking and Deadlocks alert-notebook templates (#4222) - #4395
Merged
Merged
Conversation
Adds authored/blocking and authored/deadlocks server-side templates to AlertNotebookEndpoint, checked before the mechanical conversion, for the three metric names the alert engine emits: Blocking Detected, Blocking Wait Time, and Deadlocks Detected. Every other metric keeps the byte-identical mechanical path. Ports the blocking-rca and deadlock-postmortem panel specs from notebook.js into server-side composed cells with an absolute range bound to the mechanical window (window_end - 24h family lookback), plus a database_name filter when the matched incident carries one. Read cells carry server/as_of/hours/limit per the existing mechanical convention; get_deadlock_trend is the one bucketed-trend read with no limit param, so it is exempted rather than forcing an undeclared param onto it. Extends DarlingWebEndpoints.ValidateNotebookDefinition to accept the header/status lead-in cell types (previously unvalidatable, since only the endpoint's own live-HTTP output exercised them) with their own strict-key sets.
Adds Darling.Tests.AlertNotebookAuthoredTemplateTests.cs (23 tests, in-process on macOS, 23/23 PASS): metric routing, ValidateNotebookDefinition against both templates, degrade, dispatch-entry census for authored read cells, a new compose-catalog check for composed cells' measures/breakdowns (with its own red-on-a-renamed-measure pin), budget, binding, explicit viz, and the by-database breakdown's no-filter rule. Widens AuthoredTemplate/AuthoredTemplateEntry from private to internal so the test project calls them directly via the existing InternalsVisibleTo, no reflection. RED confirmed against origin/dev: 11x CS0117 compile failure, AuthoredTemplate does not exist there.
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.
Refs #4222.
Why
The alert-notebook MVP (#4222) ships every metric through a mechanical read-cell conversion (#4366). This adds the two authored templates the spec calls for: Blocking (Blocking Detected / Blocking Wait Time) and Deadlocks (Deadlocks Detected) get a forensic, multi-cell layout instead of a flat read list, reusing the same panel shapes the
blocking-rcaanddeadlock-postmortemseed notebooks already use.What changes
AlertNotebookEndpoint.cs: addsAuthoredTemplate(metric), checked before the mechanical conversion. It returns anauthored/blockingorauthored/deadlocksentry for the three alert-engine metric names ("Blocking Detected", "Blocking Wait Time", "Deadlocks Detected"), each with its own version constant (BlockingTemplateVersion,DeadlocksTemplateVersion). Every other metric is unchanged — samemechanical/<metric>id, same cells.get_blocking(limit 20), ablocked_process_reportstimeline (composed cell,annotations: ["deadlocks"]), three ranked breakdowns ported fromblocking-rca(most-blocked objects, by database, lock modes — bar/bar/pie, topN 10/10/8), thenget_active_queriesblocking_only=true.get_deadlock_detail(limit 3), adeadlockstimeline (composed cell,annotations: ["blocked_process_reports"]), one ranked breakdown fromdeadlock-postmortem(deadlocks by database), thenget_deadlock_trendover 24h.rangeequal to the computed window (window_end - 24h..window_end, the existing mechanical anchor math); the matched incident'sDatabase, when present, is bound as aneqfilter on every composed cell EXCEPT the by-database breakdown (which must show every database, not just the incident's one).server/as_of=window_end/ an explicithours+limit, same convention as the mechanical path, exceptget_deadlock_trend, which declares nolimitparam at all (a bucketed trend, not a row-capped list) — exempted by name rather than forced into an undeclared-param 400.viz("table" for reads, "line"/"bar"/"pie" for the composed cells).DarlingWebEndpoints.cs:ValidateNotebookDefinitiongainscase "header":/case "status":arms (with their own strict-key sets,s_headerCellKeys/s_statusCellKeys) so the endpoint's own lead-in cells — which it already emitted for every template, mechanical included — can be validated at all. Before this, only the mechanical path's live-HTTP round trip ever exercised those two cell shapes; the validator itself rejected them as an "unknown type".Test plan
dotnet build Darling/Darling.Tests/Darling.Tests.csproj -p:EnableWindowsTargeting=true— 0 warnings / 0 errors.dotnet build Lite.Tests/Lite.Tests.csproj -p:EnableWindowsTargeting=true— 0 warnings / 0 errors.Darling.Tests.dllin-process recipe: build Release, strip theMicrosoft.WindowsDesktop.Appframework entry from the runtimeconfig, rundotnet Darling.Tests.dll -class <name>— no rig needed, these are pure tests):Darling.Tests.AlertNotebookAuthoredTemplateTests(new file, 23 tests): metric routing for all three alert-engine metric names plus a non-authored control metric; both templates passValidateNotebookDefinitionagainst a fixed incident; the degrade case (no matched incident) still validates with the same cell count; every authored read cell names aBuildReadDispatchentry (a gapEveryMechanicalReadCell_NamesAKnownDispatchEntrycouldn't see, since it only walksSectionsFor); every composed (panel) cell's measure/source/groupBy is checked throughComposeSpec.TryParsePanel— the SAME authority a saved dashboard/notebook panel is checked against — plus one dedicated pin (ComposeCatalogCheck_RedsOnARenamedMeasure) proving that check actually reds on a bogus measure name, not just trivially passing; budget (explicitlimiton every read cell exceptget_deadlock_trend, noaudit_config/analyze_*, every composed window ≤ 24h); binding (range== computed window, readas_of==window_end); explicitvizon every read/panel cell; the by-database breakdown never binds a database filter even with a matched incident. Result: 23/23 PASS, 0.12s.Darling.Tests.AlertNotebookEndpointTests(pre-existing, unmodified): still 24/24 PASS — confirms the widened visibility (AuthoredTemplate/AuthoredTemplateEntryprivate → internal) and the validator's newheader/statuscases didn't disturb anything already pinned.origin/dev(git worktree add --detach <tmp> origin/dev, copy in the new test file only, build): compile failure, 11×CS0117: 'AlertNotebookEndpoint' does not contain a definition for 'AuthoredTemplate'—AuthoredTemplatedoesn't exist on dev at all, so the new pins cannot even compile there, let alone pass. Confirms the pins are real (they exercise code that doesn't exist pre-fix), not a change blind to the fix.Validator fix, settled
wwwroot/js/pages/views.js:704'ssaveAsNotebookButtonposts the in-memorydefinitionto/api/viewsunmodified (api.createView({ name, description, definition })) — no strip ofheader/statuscells anywhere in the call path (renderNotebookDoc→saveAsNotebookButton,views.js:517-706). Every alert-mode notebook, mechanical or authored, carries aheadercell and astatuscell (AlertNotebookEndpoint.HeaderCell/StatusCell) as its first two cells. So "Save as notebook" was broken on dev for every single alert before this PR:ValidateNotebookDefinitionrejected any definition carrying those two cell types with "cell 0 has an unknown type 'header'", and/api/views' create path runs every definition through that same validator (DarlingWebEndpoints.cs:1632). The validator change in this PR (case "header":/case "status":,s_headerCellKeys/s_statusCellKeys) is therefore a real, necessary fix — kept, not reverted — and is a fix to #4366/#4368 (the mechanical template and its "Save as notebook" affordance), not just an enabler for this PR's own pins.AuthoredTemplate_BuiltAgainstAMatchedIncident_PassesValidateNotebookDefinitionandEveryMechanicalReadCell_NamesAKnownDispatchEntry's sibling render path both exercise the validated shape end to end; the render side (renderAlertCellinviews.js:611-660) already has explicitif (cell.type === "header")/"status"branches predating this PR, so no render-side change was needed — only the validator was the gap.CHANGELOG entry
SECTION: Added
ENTRY:
/api/alert-notebooknow returns a forensic, multi-cell layout for Blocking Detected, Blocking Wait Time, and Deadlocks Detected instead of the flat mechanical read list every other alert type gets: a blocked-process-reports or deadlocks timeline with a cross-annotation, ranked breakdowns by object/database/lock-mode, and the existing header/status/drill-down reads, all bound to the alert's own window and database.REF:
[#4395]: #4395