- AddServerRequestAsync returns a ServerTest/SyntheticCheckRun already waiting for the agent (Pending, same kind and target) instead of queueing another one, like AddAgentRequestAsync; AgentRequestRow carries TargetId. - Active server findings and the overview counts leave out removed servers and checks, and paused ones across all (a paused one's own list keeps its latest findings, as for instances); findings say ScopeRemoved/ScopePaused. GetServerFindingsAsync pages with OFFSET/FETCH. - Removing a server (in the web UI or a SQL Server host by the agent's sync) detaches its synthetic checks in the same transaction (ServerId NULL, serviceName out of the settings); check queries only join servers in use. - Removing a check clears its sealed password, key id, secret error and last message; a late agent result does not write to a removed check. (0018: UPDATE on LastMessage for the web login.) - 0018: settings and service lists as nvarchar(max) (no 500 on long æøå queries); indexes on SampledAt/LastAt/RunAt for the retention deletes. Run details that do not fit are trimmed from the end instead of all dropped. - One query for the overview's latest CPU/memory and disk collection per server. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
202 lines
11 KiB
Transact-SQL
202 lines
11 KiB
Transact-SQL
/* 1.5: Windows servers and synthetic checks.
|
|
|
|
WindowsServers the Windows servers the agent looks at: the computers behind the monitored SQL Server
|
|
instances (Source 'SqlHost', kept in step by the agent) and servers added in SQLInsight Web
|
|
(AOS and other application servers, file servers). The agent reads them remotely, as its own
|
|
identity, with least privilege (db/permissions/grant-windows-server.ps1); it never changes them.
|
|
ServerPerformance CPU, available memory, paging and commit per minute. Kept SQLInsight:Servers:SampleDays.
|
|
ServerDiskSamples free space per volume every 15 minutes: the history the "fuld om ca. N dage" forecast is
|
|
computed from. Kept SQLInsight:Servers:DiskHistoryDays.
|
|
ServerEvents errors and critical events from the System and Application logs, summed per collection,
|
|
source and event id like insight.ErrorLogEvents. Sample is a message: local only. Kept EventDays.
|
|
ServerSnapshots the latest collection per area (services, tasks, disks with forecasts …) for display, and so a
|
|
restarted agent continues where it stopped.
|
|
SyntheticChecks checks the agent runs on a schedule: TCP port, HTTP(S), SQL login + query, DNS, Dynamics AX
|
|
logon. A SQL login password is sealed with the agent's public key (insight.AgentKeys), as in 1.3.
|
|
SyntheticCheckResults every run, kept SQLInsight:SyntheticChecks:ResultDays.
|
|
ServerFindings, findings and rule outcomes of the Windows server rules (Scope 'Server') and synthetic check rules
|
|
ServerRuleStates (Scope 'Check'), like insight.Findings and insight.RuleStates for instances. */
|
|
CREATE TABLE insight.WindowsServers
|
|
(
|
|
ServerId int IDENTITY(1, 1) NOT NULL CONSTRAINT PK_WindowsServers PRIMARY KEY,
|
|
Name nvarchar(128) NOT NULL,
|
|
Host nvarchar(255) NOT NULL,
|
|
Role varchar(16) NOT NULL CONSTRAINT DF_WindowsServers_Role DEFAULT ('Other')
|
|
CONSTRAINT CK_WindowsServers_Role CHECK (Role IN ('Sql', 'Application', 'File', 'Other')),
|
|
Source varchar(16) NOT NULL CONSTRAINT DF_WindowsServers_Source DEFAULT ('Web')
|
|
CONSTRAINT CK_WindowsServers_Source CHECK (Source IN ('Web', 'SqlHost')),
|
|
Paused bit NOT NULL CONSTRAINT DF_WindowsServers_Paused DEFAULT (0),
|
|
WatchedServices nvarchar(max) NULL,
|
|
IgnoredServices nvarchar(max) NULL,
|
|
CreatedAt datetime2(0) NOT NULL CONSTRAINT DF_WindowsServers_CreatedAt DEFAULT (SYSUTCDATETIME()),
|
|
CreatedBy nvarchar(256) NULL,
|
|
UpdatedAt datetime2(0) NOT NULL CONSTRAINT DF_WindowsServers_UpdatedAt DEFAULT (SYSUTCDATETIME()),
|
|
UpdatedBy nvarchar(256) NULL,
|
|
RemovedAt datetime2(0) NULL,
|
|
RemovedBy nvarchar(256) NULL,
|
|
/* What the agent saw. */
|
|
LastContactAt datetime2(0) NULL,
|
|
LastErrorAt datetime2(0) NULL,
|
|
LastError nvarchar(1000) NULL,
|
|
Protocol varchar(16) NULL,
|
|
OperatingSystem nvarchar(256) NULL,
|
|
OsVersion nvarchar(64) NULL,
|
|
LastBootUpTime datetime2(0) NULL,
|
|
TotalMemoryMb float NULL,
|
|
LogicalProcessors int NULL,
|
|
AreasJson nvarchar(max) NULL
|
|
);
|
|
CREATE UNIQUE INDEX UQ_WindowsServers_Host ON insight.WindowsServers (Host) WHERE RemovedAt IS NULL;
|
|
CREATE UNIQUE INDEX UQ_WindowsServers_Name ON insight.WindowsServers (Name) WHERE RemovedAt IS NULL;
|
|
|
|
CREATE TABLE insight.ServerPerformance
|
|
(
|
|
ServerId int NOT NULL,
|
|
SampledAt datetime2(0) NOT NULL,
|
|
CpuPercent real NULL,
|
|
AvailableMb real NULL,
|
|
AvailablePct real NULL,
|
|
PagesPerSec real NULL,
|
|
CommitPct real NULL,
|
|
CONSTRAINT PK_ServerPerformance PRIMARY KEY (ServerId, SampledAt)
|
|
);
|
|
/* Retention deletes by time across all servers. */
|
|
CREATE INDEX IX_ServerPerformance_SampledAt ON insight.ServerPerformance (SampledAt);
|
|
|
|
CREATE TABLE insight.ServerDiskSamples
|
|
(
|
|
ServerId int NOT NULL,
|
|
Volume nvarchar(260) NOT NULL,
|
|
SampledAt datetime2(0) NOT NULL,
|
|
SizeGb float NOT NULL,
|
|
FreeGb float NOT NULL,
|
|
CONSTRAINT PK_ServerDiskSamples PRIMARY KEY (ServerId, Volume, SampledAt)
|
|
);
|
|
CREATE INDEX IX_ServerDiskSamples_SampledAt ON insight.ServerDiskSamples (SampledAt);
|
|
|
|
CREATE TABLE insight.ServerEvents
|
|
(
|
|
EventRowId bigint IDENTITY(1, 1) NOT NULL CONSTRAINT PK_ServerEvents PRIMARY KEY NONCLUSTERED,
|
|
ServerId int NOT NULL,
|
|
CollectedAt datetime2(0) NOT NULL,
|
|
LogName nvarchar(64) NOT NULL,
|
|
Source nvarchar(256) NOT NULL,
|
|
EventId bigint NOT NULL,
|
|
[Level] tinyint NOT NULL,
|
|
Category varchar(32) NOT NULL,
|
|
[Count] int NOT NULL,
|
|
FirstAt datetime2(0) NOT NULL,
|
|
LastAt datetime2(0) NOT NULL,
|
|
Sample nvarchar(500) NULL
|
|
);
|
|
CREATE CLUSTERED INDEX CX_ServerEvents ON insight.ServerEvents (ServerId, LastAt);
|
|
CREATE INDEX IX_ServerEvents_LastAt ON insight.ServerEvents (LastAt);
|
|
|
|
CREATE TABLE insight.ServerSnapshots
|
|
(
|
|
ServerId int NOT NULL,
|
|
Area varchar(32) NOT NULL,
|
|
CapturedAt datetime2(0) NOT NULL,
|
|
Json nvarchar(max) NOT NULL,
|
|
CONSTRAINT PK_ServerSnapshots PRIMARY KEY (ServerId, Area)
|
|
);
|
|
|
|
CREATE TABLE insight.SyntheticChecks
|
|
(
|
|
CheckId int IDENTITY(1, 1) NOT NULL CONSTRAINT PK_SyntheticChecks PRIMARY KEY,
|
|
Name nvarchar(128) NOT NULL,
|
|
Kind varchar(16) NOT NULL CONSTRAINT CK_SyntheticChecks_Kind CHECK (Kind IN ('Tcp', 'Http', 'Sql', 'Dns', 'AxLogon')),
|
|
ServerId int NULL CONSTRAINT FK_SyntheticChecks_Server REFERENCES insight.WindowsServers (ServerId),
|
|
SettingsJson nvarchar(max) NOT NULL,
|
|
SecretCipher varbinary(2048) NULL,
|
|
SecretKeyId varchar(64) NULL,
|
|
IntervalSeconds int NOT NULL CONSTRAINT DF_SyntheticChecks_Interval DEFAULT (300)
|
|
CONSTRAINT CK_SyntheticChecks_Interval CHECK (IntervalSeconds BETWEEN 60 AND 86400),
|
|
TimeoutSeconds int NOT NULL CONSTRAINT DF_SyntheticChecks_Timeout DEFAULT (15)
|
|
CONSTRAINT CK_SyntheticChecks_Timeout CHECK (TimeoutSeconds BETWEEN 1 AND 120),
|
|
Paused bit NOT NULL CONSTRAINT DF_SyntheticChecks_Paused DEFAULT (0),
|
|
CreatedAt datetime2(0) NOT NULL CONSTRAINT DF_SyntheticChecks_CreatedAt DEFAULT (SYSUTCDATETIME()),
|
|
CreatedBy nvarchar(256) NULL,
|
|
UpdatedAt datetime2(0) NOT NULL CONSTRAINT DF_SyntheticChecks_UpdatedAt DEFAULT (SYSUTCDATETIME()),
|
|
UpdatedBy nvarchar(256) NULL,
|
|
RemovedAt datetime2(0) NULL,
|
|
RemovedBy nvarchar(256) NULL,
|
|
SecretError nvarchar(1000) NULL,
|
|
/* What the agent saw. */
|
|
LastRunAt datetime2(0) NULL,
|
|
LastSuccess bit NULL,
|
|
LastDurationMs int NULL,
|
|
LastMessage nvarchar(1000) NULL,
|
|
ConsecutiveFailures int NOT NULL CONSTRAINT DF_SyntheticChecks_Failures DEFAULT (0)
|
|
);
|
|
CREATE UNIQUE INDEX UQ_SyntheticChecks_Name ON insight.SyntheticChecks (Name) WHERE RemovedAt IS NULL;
|
|
|
|
CREATE TABLE insight.SyntheticCheckResults
|
|
(
|
|
ResultId bigint IDENTITY(1, 1) NOT NULL CONSTRAINT PK_SyntheticCheckResults PRIMARY KEY NONCLUSTERED,
|
|
CheckId int NOT NULL,
|
|
RunAt datetime2(0) NOT NULL,
|
|
Success bit NOT NULL,
|
|
DurationMs int NOT NULL,
|
|
Message nvarchar(1000) NOT NULL,
|
|
DetailsJson nvarchar(4000) NULL,
|
|
CertificateExpiresAt datetime2(0) NULL,
|
|
CertificateSubject nvarchar(400) NULL,
|
|
ServiceState varchar(32) NULL,
|
|
[Partial] bit NOT NULL CONSTRAINT DF_SyntheticCheckResults_Partial DEFAULT (0)
|
|
);
|
|
CREATE CLUSTERED INDEX CX_SyntheticCheckResults ON insight.SyntheticCheckResults (CheckId, RunAt);
|
|
CREATE INDEX IX_SyntheticCheckResults_RunAt ON insight.SyntheticCheckResults (RunAt);
|
|
|
|
CREATE TABLE insight.ServerFindings
|
|
(
|
|
FindingId bigint IDENTITY(1, 1) NOT NULL CONSTRAINT PK_ServerFindings PRIMARY KEY,
|
|
Scope varchar(8) NOT NULL CONSTRAINT CK_ServerFindings_Scope CHECK (Scope IN ('Server', 'Check')),
|
|
ScopeId int NOT NULL,
|
|
RuleId varchar(40) NOT NULL,
|
|
Subject nvarchar(400) NOT NULL,
|
|
Severity tinyint NOT NULL,
|
|
Title nvarchar(1000) NOT NULL,
|
|
Explanation nvarchar(max) NOT NULL,
|
|
Recommendation nvarchar(max) NOT NULL,
|
|
EvidenceJson nvarchar(max) NOT NULL,
|
|
ReferencesJson nvarchar(max) NOT NULL,
|
|
FirstSeenAt datetime2(0) NOT NULL,
|
|
LastSeenAt datetime2(0) NOT NULL,
|
|
ResolvedAt datetime2(0) NULL
|
|
);
|
|
CREATE UNIQUE INDEX UX_ServerFindings_Active ON insight.ServerFindings (Scope, ScopeId, RuleId, Subject) WHERE ResolvedAt IS NULL;
|
|
CREATE INDEX IX_ServerFindings_Resolved ON insight.ServerFindings (ResolvedAt) WHERE ResolvedAt IS NOT NULL;
|
|
|
|
CREATE TABLE insight.ServerRuleStates
|
|
(
|
|
Scope varchar(8) NOT NULL,
|
|
ScopeId int NOT NULL,
|
|
RuleId varchar(40) NOT NULL,
|
|
RuleTitle nvarchar(400) NOT NULL,
|
|
Outcome tinyint NOT NULL,
|
|
Reason nvarchar(max) NULL,
|
|
EvaluatedAt datetime2(0) NOT NULL,
|
|
CONSTRAINT PK_ServerRuleStates PRIMARY KEY (Scope, ScopeId, RuleId)
|
|
);
|
|
|
|
/* Requests about a Windows server or a synthetic check name it in TargetId. */
|
|
ALTER TABLE insight.AgentRequests ADD TargetId int NULL;
|
|
ALTER TABLE insight.AgentRequests DROP CONSTRAINT CK_AgentRequests_Kind;
|
|
ALTER TABLE insight.AgentRequests ADD CONSTRAINT CK_AgentRequests_Kind
|
|
CHECK (Kind IN ('ConnectionTest', 'DatabaseDiscovery', 'InstanceDiscovery', 'ServerTest', 'SyntheticCheckRun'));
|
|
GO
|
|
|
|
CREATE INDEX IX_AgentRequests_Target ON insight.AgentRequests (Kind, TargetId, RequestId) WHERE TargetId IS NOT NULL;
|
|
GO
|
|
|
|
/* SQLInsight Web only has db_datareader. As in 0016 it gets exactly what it needs to change the configuration: add
|
|
servers and checks, change what may be changed, and remove (RemovedAt, no DELETE; a removed check's sealed password
|
|
and last message are cleared, and checks of a removed server lose the server). Nothing else the agent records. Host,
|
|
Name of a server and Kind of a check are fixed once created. Who may change it in the web UI is decided by
|
|
SQLInsight:Web:AdminGroups. */
|
|
GRANT INSERT ON insight.WindowsServers TO public;
|
|
GRANT UPDATE ON insight.WindowsServers (Role, Paused, WatchedServices, IgnoredServices, UpdatedAt, UpdatedBy, RemovedAt, RemovedBy) TO public;
|
|
GRANT INSERT ON insight.SyntheticChecks TO public;
|
|
GRANT UPDATE ON insight.SyntheticChecks (Name, ServerId, SettingsJson, SecretCipher, SecretKeyId, IntervalSeconds, TimeoutSeconds, Paused,
|
|
UpdatedAt, UpdatedBy, RemovedAt, RemovedBy, SecretError, LastMessage) TO public;
|