Commit graph

10 commits

Author SHA1 Message Date
1c18bcfab8 Web: Windows-servere and Syntetiske tjek pages, and the same in API v1 (scope config:write)
- Menu group "Servere" with Windows-servere (/servere) and Syntetiske tjek
  (/syntetiske-tjek).
- /servere: every server with status (overvåges, delvist målbar, kan ikke læses),
  CPU, free memory, the fullest disk and the nearest "fuld om ca. N dage", findings;
  add application/AOS/file servers. /servere/{id}: findings and what is not
  measurable and why, CPU/memory for the last day, disks with forecasts, watched
  and stopped services, grouped event log errors, scheduled tasks, rights per area
  with the latest test, the least-privilege PowerShell script (copy or download,
  UTF-8 with BOM), role and service lists, pause and remove. /servere/fund/{id}.
- /syntetiske-tjek: checks with status and response time; one form for every kind
  (TCP, HTTP(S), SQL login + query, DNS, AX logon) with an optional server and
  service; a SQL login password is sealed for the agent at once and never shown.
  /syntetiske-tjek/{id}: latest result (incl. "kun porten er testet"), findings,
  response times, history, edit, run now, pause, remove.
- API v1: /windows-servers (+ test, grant-script, performance, disks, services,
  events, tasks, rule-states), /server-findings, /synthetic-checks (+ run, results,
  rule-states); all in OpenAPI. Passwords are write-only; event samples, failure
  messages and sensitive evidence are "[udeladt]" unless
  SQLInsight:Web:ApiIncludesSensitiveEvidence is on. /api/v1/rules lists the new rules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 14:58:52 +02:00
f4d2603181 Review 1.4: AX texts in API v1 and the hub without logins or host names; API has what the pages show
- "Ikke målbar" texts, notes and detection problems carry the GRANT text with
  the agent's login and database user. API v1 (batch-jobs, number-sequences,
  recids, databases, rule-states) returned them as they were, although logins
  are redacted everywhere else. AxReadAccess.WithoutPrincipals replaces them
  with the placeholder unless sensitive values are allowed; the grant script
  also hides a database user that differs from the login.
- SQLI-AX-010 put the host and program name (in 2-tier AX 3.0 the user's own
  PC) in the finding's explanation, which reaches the hub unredacted for an
  opted-in database. They are only in the sensitive evidence now, with the raw
  CONTEXT_INFO; the CONTEXT_INFO parsing says it is not verified against
  customer data.
- A database named e.g. "AX · test" was read from a subject as "AX", whose
  hub opt-in then applied. Middle dots in the database are doubled in AX
  subjects, and the AX community rules' subjects are built the same way.
- API v1 now also has the detection problems (/detection-problems), what each
  raw batch STATUS means, and the thresholds behind the number sequence and
  RecId pages; the blocking explanation is no longer redacted (it holds
  nothing sensitive now).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 14:29:34 +02:00
a01ec374a4 Review 1.2: keep SQL Server's error message out of the replication reason
When the distribution database could not be read, SQL Server's message
(which names the agent's login) was appended to Unavailable. That text is
the rules' "not measurable" reason and is returned unredacted by
/rule-states and /replication. It is now UnavailableDetail: shown on the
local instance page and [udeladt] in the API unless
ApiIncludesSensitiveEvidence. The agent list is also capped (TOP 500).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 11:33:25 +02:00
6cc65e3c75 Index usage over time and never-updated statistics (8g, F)
The index collector now sums index reads and writes between collections
across restarts of SQL Server (and of the agent, by seeding from the
stored snapshot) and keeps them per day in insight.IndexUsageDaily
(migration 0015, HourlyDays). SQLI-IDX-002 judges an index once it has
been followed for 7 days instead of needing 7 days of uptime.
GET /api/v1/instances/{name}/index-usage lists usage per index.

SQLI-STAT-001 also reports statistics that were never updated on tables
with rows; statistic rows now come from the table's heap or clustered
index, as a never-updated statistic has no row count of its own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 10:55:22 +02:00
473a7d0be3 Replication from the distributor (8f)
On a distributor, a 15-minute collector reads each distribution agent's
latest run (status, latency, message) and replication errors the last
day from the distribution database. That needs SELECT on
MSdistribution_agents, MSdistribution_history and MSrepl_errors, which
the agent does not have by default (never the replicated commands);
without it SQLI-REPL-001 (agent failed/retrying, High) and SQLI-REPL-002
(latency > 5 min, Medium) are "not measurable" with the exact grant, and
"not relevant" elsewhere. Shown on the instance page and in
GET /api/v1/instances/{name}/replication. Tested against a real
distributor set up in the SQL 2022 container.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 10:48:46 +02:00
4d18d20ab0 tempdb and version store (8c)
A five-minute collector reads tempdb space (free, version store, user and
internal objects, whether files can grow), the 'Version Store Size (KB)'
counter, the sessions using most tempdb, the oldest snapshot transaction
and, only when the version store is large, the databases generating
versions. Trend and heavy sessions survive restarts; used space and the
version store become metrics with explanation and assessment.

Rules SQLI-TEMP-001 (version store > 1 GB or steadily growing),
SQLI-TEMP-002 (nearly full and cannot grow) and SQLI-TEMP-003 (session
above 1 GB for 15 minutes), configurable under SQLInsight:Tempdb.
"tempdb lige nu" on the instance page; GET /api/v1/instances/{name}/tempdb.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 10:42:38 +02:00
6f7839d011 Long and large transactions and long-running statements (8b, 8d)
A one-minute collector reads open user transactions (age, log bytes used
and reserved, database, session, login, program, statement) and user
requests running longer than the threshold, leaving out the agent's own
and system sessions, BACKUP/RESTORE/DBCC (long operations) and requests
waiting on purpose. Transactions open a minute or holding 100 MB are kept
in insight.LongTransactions (migration 0014, RawDays).

Rules SQLI-TRAN-001 (open > 10 min, High at 6x), SQLI-TRAN-002 (> 1 GB
log) and SQLI-REQ-001 (statement > 15 min), configurable under
SQLInsight:Activity. Shown "right now" on the instance page and in the
time window analysis and PDF; GET /api/v1/instances/{name}/activity and
the analysis JSON leave logins and statements out.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 10:36:41 +02:00
e6840e40d7 SQL Server error log without elevated rights (8a)
A five-minute collector reads important error log entries from the best
source the agent's rights allow: the error log itself (xp_readerrorlog,
only with securityadmin), the default trace's ErrorLog and Audit Login
Failed events (optional ALTER TRACE), or the exception and connectivity
ring buffers (VIEW SERVER STATE: numbers and severity, failed logins).
Repetitions are summed per error; the watermark is the newest entry
read, because the default trace is buffered. Stored in
insight.ErrorLogEvents (migration 0013, EventDays), resumed after restart.

Rules SQLI-LOG-001..006: corruption 823/824/825, I/O over 15 s (833),
severe errors (17+), login failure bursts (configurable), stack dumps and
AG errors; rules needing the log text are "not measurable" with the
right to grant. Page /instanser/{navn}/fejllog (menu Overvågning) and
GET /api/v1/instances/{name}/error-log with messages redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 10:30:41 +02:00
0dc7866808 Separate "check by hand" from "not relevant" for version-gated rules
A rule whose topic applies but whose way of measuring needs a newer
version or patch now gives the new outcome ManualCheck with concrete
Danish guidance, instead of NotApplicable. It is marked explicitly per
rule (IRule.ManualCheck) and only used when every missing capability is
a measurement capability (InstanceCapabilities.IsMeasurement): CHECKDB
status (SQLI-DB-009), VLFs (SQLI-DB-011), spills and memory grants
(SQLI-PLAN-004/005) and deadlocks on 2005 (SQLI-DLK-001). Query Store,
AG and Azure-managed topics stay "not relevant".

Shown in a visible "Skal tjekkes manuelt" section on the instance page,
a KPI on the overview, a "Tjek manuelt" column in the management
report's controls, manualChecks in /api/v1/instances and manualCheck in
rule-states; not counted as not measurable.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 09:59:50 +02:00
30d89acbd7 API v1: findings, rules, reports and page data as JSON, with OpenAPI
- /api/v1/findings gains status (active/resolved/all), from/to, database,
  ruleId, category, sort and paging (limit + X-Continuation header; the
  response stays an array). /findings/{id} with fix script and history.
- /rules (built-in, community, local) and /instances/{name}/rule-states.
- /reports and /reports/{driftsrapport|analyse|rettigheder} as JSON or PDF,
  built from the same models as the pages and PDFs.
- Page data: analysis, top-sql, disks, configuration, privileges (one or
  all instances) and wait types. Statement texts, logins, names and
  service accounts are "[udeladt]" unless ApiIncludesSensitiveEvidence.
- OpenAPI at /api/v1/openapi.json; a test fails when an endpoint is
  missing from it.
- API tokens get scopes ("read", "support:write"); the old form is read
  only, and new-api-token takes --scope. Token names show as token:<name>.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 09:27:10 +02:00