Repository navigation
Long-running query completion trace (opt-in XE) in Lite + Darling (#1496) - #1572
Merged
Merged
Conversation
) New long_query_completions collector: an app-managed Extended Events ring-buffer session capturing rpc_completed + sql_batch_completed (duration >= 2s, the Full Dashboard's SQL Trace default) plus attention unfiltered (cancelled/timed-out long queries - attention.duration is handling time, not query runtime). Modeled end-to-end on the blocked-process collector family. Dedicated switch, default OFF: seeded disabled via a new CollectorScheduleDefaults.DefaultEnabled flag both SKUs honor; enabling creates the session on monitored servers, disabling DROPS it there (the lifecycle reconciles to the flag both ways, driven from shared session-DDL builders on the collector so Lite and Darling can't drift). Both apps: shared collector + catalog registration + Lite's catalog-driven storage registrations + Darling store migration V29; a Long Queries viewer tab (grid default-sorted DESC by duration, aborted/attention row tints) with an empty-state banner naming the exact switch when disabled; a get_long_query_completions MCP read tool. Azure SQL DB gets the per-database session variant (#1535 pattern; nt_username omitted there - Azure uses Entra/SQL auth). Closes #1496 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The per-sweep reconcile is act-on-change, so a Darling-monitored Azure SQL DB database-scoped session that stops on reconnect would not be restarted (the applied flag stays true and the reconcile skips). Reset the flag to null on every successful connect so the first post-connect sweep re-ensures — matching blocked-process's per-connect ensure. The reconcile still no-ops unless the desired state differs (ensure is IF-NOT-running START; drop is IF EXISTS), so the disabled default stays near-zero cost. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
erikdarlingdata
added a commit
that referenced
this pull request
Jul 18, 2026
Rebase onto dev brought #1572's new read tool get_long_query_completions; the endpoint<->catalog parity test caught it as unwired (exactly its purpose). It is a stored data-read, so add its /api/read dispatch entry (server, hours_back=24, limit=30). Also carries the web migration renumber V29->V30 (dev took V29 = long_query_completions): PgMigrations V30Sql + Migration(30), StorageVersion 30, the 14-column store schema probe (long_query->29, web->30), and the migration/probe test pins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Closes #1496.
What
A new opt-in
long_query_completionscollector — the Extended Events equivalent of the classic long-query trace (SSMS's QuickSessionStandard completion trio), modeled end-to-end on theblocked_process_reportcollector family, shipped in both Lite and the Darling viewer.rpc_completed+sql_batch_completedfiltered byduration >= threshold, plusattentionunfiltered — a cancelled/timed-out long query'sattention.durationis the cancellation-handling time (tens of ms), not the query runtime, so a duration predicate would discard exactly that evidence (MS Learn-verified). Completed events also carryresult(Abort= the long query was killed).SET collect_statement/collect_object_name/collect_batch_text = 1— these are off by default or arrive NULL).Erik's dedicated switch (default OFF)
Seeded disabled via a new
CollectorScheduleDefaults.Entry.DefaultEnabledflag both SKUs honor (Lite'sScheduleManager; Darling'sStoreConfigProvider.ResolveSchedulefalls back to it, so "reset to defaults" returns it to OFF rather than silently ON). The XE session lifecycle follows the flag: enabling creates the session on the monitored servers; disabling DROPS it there (the session itself is the busy-server cost). The reconcile is state-tracked (zero steady-state cost for the default-off fleet) and driven from shared session-DDL builders on the collector (BuildCreateSessionSql/BuildStartSessionSql/BuildDropSessionSql) so Lite and Darling can't drift on the 3-event/9-action DDL. Drop-on-disable had no precedent in the codebase (both apps only ever created XE sessions) — it is net-new and test-covered.Both apps
CollectorCatalogregistration → Lite's catalog-driven storage registrations (table/index/archive view/retention) and Darling'sPgSchemaGeneratorschema come for free; Darling store migration V29 for upgraded stores +StorageVersionbump 28→29 (viewer schema-probe extended with a 13th sentinel).SortDescription, never flips the SQLORDER BY), aborted/attention rows tinted.WarningTextBrushbanner (the msdb-permissions idiom) names the exact switch — Lite: "Settings → Collector Schedules → Edit → tick the Enabled box"; Darling: "Settings → Collection Schedule → Edit Collector Schedules…".get_long_query_completionsMCP read tool in both apps (Lite reads DuckDB, Darling reads Postgres) — added to both to keep the cross-app MCP inventory pin green with no allow-list debt (parity).Key decisions
install/30_collect_trace_management.sql:37, which captured the same RPC/batch/attention trio), NOT the 30 s fallback. Hardcoded const with doc comment: the schedule model carries only frequency/retention (no per-collector numeric-knob surface), so this follows the blocked-process-threshold hardcoded precedent + defaults-over-speculative-config.rpc_completed/sql_batch_completed/attentionare all available in an Azure database-scoped session (used directly — nodatabase_-prefixed variant, unlike deadlocks).nt_usernameis omitted from the Azure DDL — Azure uses Entra/SQL auth so it's meaningless and may be absent database-scoped; the column simply lands NULL there.result(flags timed-out/aborted long queries — verifier-recommended),physical_reads, andobject_name(the proc that ran) — all free in the completed-event payload.Tests / gates
LongQueryCompletionsCollectorDefinitionTestspins identity, the ring-buffer read/event filter, the 20-column payload ordinals (this caught a real ReadAsync off-by-one before it shipped), attention duration→NULL, and the DDL builders (predicate on completed-only, attention unfiltered,SET collect_*, Azurent_usernameomission, guarded idempotent DROP).DuckDbSchemaGeneratorTests,DuckDbSchemaEquivalenceTests,DuckDbSchemaTests42→43,PgSchemaGeneratorTestsincl. 33→34 indexes,DarlingObservabilityTestsmigration count/version); golden schema oracle gains the table+index; shared-defaults pin strengthened to enforceEnabled↔DefaultEnabledparity; viewer schema-probe test extended to 13 sentinels.Capability pins / baselines
The ServerTab / ViewerServerTab capability pins are subset ratchets, so the additive tab + grid + filter-manager + event-wire capabilities kept them green with no baseline file changes (baselines only ever shrink on intentional removals). No baseline lines added or deleted.
Noticed / not changed
CPU >= 1000 mspredicate; the issue design specifiesduration >= thresholdonly, so this follows the design (CPU is still captured as a column).🤖 Generated with Claude Code