using SQLInsight.Core.Collection; using SQLInsight.Core.Servers; namespace SQLInsight.Rules.Servers; /// /// Thresholds of the Windows server rules (SQLInsight:Servers in the agent's appsettings.json). Not sealed: the agent's /// options add how and how often to collect. /// public class ServerRuleSettings { public CpuThresholds Cpu { get; set; } = new(); public MemoryThresholds Memory { get; set; } = new(); public DiskThresholds Disks { get; set; } = new(); public ServiceThresholds Services { get; set; } = new(); public EventLogThresholds EventLog { get; set; } = new(); public TaskThresholds Tasks { get; set; } = new(); /// A server not restarted for more than this many days is a (low) finding: it most likely lacks Windows updates. 0: off. public int UptimeDays { get; set; } } public sealed class CpuThresholds { /// Average CPU at or above this (percent) … public double HighPercent { get; set; } = 90; /// … for this many minutes is a finding (SQLI-WIN-001). public int SustainedMinutes { get; set; } = 15; } public sealed class MemoryThresholds { /// Available memory below this share (percent) … public double AvailablePercent { get; set; } = 5; /// … and below this many MB is a finding (SQLI-WIN-002). Both, so big SQL Server hosts with little left by design are not flagged. public double AvailableMegabytes { get; set; } = 1024; /// Hard page faults per second above this, while memory is low, is paging (SQLI-WIN-003). public double PagesPerSecond { get; set; } = 1000; /// Committed memory at or above this share of the commit limit (percent) is a finding (SQLI-WIN-004). public double CommitPercent { get; set; } = 90; } public sealed class DiskThresholds { /// Free space below this (percent) is a finding (SQLI-WIN-005) … public double FreePercent { get; set; } = 10; /// … High below this … public double CriticalFreePercent { get; set; } = 5; /// … unless there is at least this much free (GB): a big volume with a small share free can be fine. public double EnoughFreeGigabytes { get; set; } = 50; /// A volume forecast to be full within this many days is a finding (SQLI-WIN-006); within 7 days High, 2 days Critical. public int ForecastDays { get; set; } = 30; /// How many days of SQLInsight's own samples the forecast is computed from. public int ForecastHistoryDays { get; set; } = 14; } public sealed class ServiceThresholds { /// /// Services that may be stopped although they start automatically (they stop by design), in addition to the /// built-in list. Name, or a prefix ending in *. /// public IList Ignore { get; } = []; /// Right after a restart services are still starting: no finding for this many minutes. public int StartupGraceMinutes { get; set; } = 15; } public sealed class EventLogThresholds { /// An ordinary error must repeat this many times in 24 hours before it is a finding; the important kinds count at once. public int RepeatThreshold { get; set; } = 5; /// Events left out as noise, in addition to the built-in list: "Kilde:id", "Kilde" or "Kilde*". public IList Ignore { get; } = []; /// At most this many event findings per server, most important first. public int MaxFindings { get; set; } = 15; } public sealed class TaskThresholds { /// Also watch Microsoft's own tasks (\Microsoft\…). Off: there are hundreds, and their failures are rarely yours. public bool IncludeMicrosoftTasks { get; set; } /// A task whose next run time is more than this many minutes in the past has not run as planned (SQLI-WIN-013). public int LateMinutes { get; set; } = 60; /// Tasks never watched (path\name, or a prefix ending in *). public IList Ignore { get; } = []; } /// What the Windows server rules see: the server, the latest data per area, and the thresholds. public sealed record ServerRuleContext(ServerIdentity Server, DateTimeOffset Now, CollectedData Data, ServerRuleSettings Settings) { /// The interval performance samples are taken at, for "sustained" averages. public TimeSpan PerformanceInterval { get; init; } = ServerArea.DefaultInterval(ServerArea.Performance); }