Review 1.2: read only the default trace's current file between rollovers
With ALTER TRACE the error log collector read every default trace file (up to 5 x 20 MB) every 5 minutes. While the current file is the one read last time, everything since then is in it, so only that file is read; after a rollover (and the first time) all files are read once as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8e551bcaa6
commit
d9e3b4ee6d
2 changed files with 16 additions and 6 deletions
|
|
@ -69,13 +69,14 @@ public sealed class ErrorLogCollector(int loginFailureBurst = 20) : Collector<Er
|
|||
List<ErrorLogEntry> entries;
|
||||
ErrorLogSource source;
|
||||
string? coverage = null;
|
||||
string? traceFile = null;
|
||||
if (errorLog && await ReadErrorLogAsync(connection, since, now, offset, ct).ConfigureAwait(false) is { } fromLog)
|
||||
{
|
||||
(entries, source) = (fromLog, ErrorLogSource.ErrorLog);
|
||||
}
|
||||
else if (await ReadDefaultTraceAsync(connection, since, offset, ct).ConfigureAwait(false) is { } fromTrace)
|
||||
else if (await ReadDefaultTraceAsync(connection, since, offset, previous?.TraceFile, ct).ConfigureAwait(false) is { } fromTrace)
|
||||
{
|
||||
(entries, source, coverage) = (fromTrace, ErrorLogSource.DefaultTrace, DefaultTraceCoverage);
|
||||
(entries, source, coverage, traceFile) = (fromTrace.Entries, ErrorLogSource.DefaultTrace, DefaultTraceCoverage, fromTrace.File);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -103,6 +104,7 @@ public sealed class ErrorLogCollector(int loginFailureBurst = 20) : Collector<Er
|
|||
Groups = groups,
|
||||
Recent = ErrorLogAnalysis.Recent(previous?.Recent ?? [], groups, context.Now),
|
||||
Coverage = coverage,
|
||||
TraceFile = traceFile,
|
||||
LoginFailureBurst = loginFailureBurst,
|
||||
};
|
||||
}
|
||||
|
|
@ -126,8 +128,8 @@ public sealed class ErrorLogCollector(int loginFailureBurst = 20) : Collector<Er
|
|||
}
|
||||
|
||||
/// <summary>ErrorLog (22) and Audit Login Failed (20) events from the default trace, or null without ALTER TRACE.</summary>
|
||||
private static async Task<List<ErrorLogEntry>?> ReadDefaultTraceAsync(DbConnection connection, DateTimeOffset since, TimeSpan offset,
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task<(List<ErrorLogEntry> Entries, string File)?> ReadDefaultTraceAsync(DbConnection connection, DateTimeOffset since, TimeSpan offset,
|
||||
string? previousFile, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -138,9 +140,14 @@ public sealed class ErrorLogCollector(int loginFailureBurst = 20) : Collector<Er
|
|||
return null;
|
||||
}
|
||||
|
||||
// All rollover files (up to 100 MB) every 5 minutes is not cheap. While the current file is the one read last
|
||||
// time, everything since then is in it; after a rollover (and the first time) all files are read once.
|
||||
var files = string.Equals(path, previousFile, StringComparison.OrdinalIgnoreCase)
|
||||
? Db.Literal(path) + ", 1"
|
||||
: Db.Literal(PrivilegeAnalysis.TraceFileBase(path)) + ", DEFAULT";
|
||||
var sql = $"""
|
||||
SELECT StartTime, EventClass, Error, Severity, CAST(TextData AS nvarchar(2000))
|
||||
FROM sys.fn_trace_gettable({Db.Literal(PrivilegeAnalysis.TraceFileBase(path))}, DEFAULT)
|
||||
FROM sys.fn_trace_gettable({files})
|
||||
WHERE EventClass IN (20, 22) AND StartTime > '{Local(since, offset)}'
|
||||
""";
|
||||
var rows = await Db.QueryAsync(connection, sql, r => (At: Utc(r.DateTime(0)) - offset, Class: r.Int(1), Error: r.NullableInt(2), Severity: r.NullableInt(3),
|
||||
|
|
@ -164,7 +171,7 @@ public sealed class ErrorLogCollector(int loginFailureBurst = 20) : Collector<Er
|
|||
|
||||
// StartTime is compared to whole seconds above, so the entries of that second that were read last time
|
||||
// (the newest of them is ReadUntil) come back; leave them out, or they are counted again every collection.
|
||||
return [.. entries.Where(e => e.At > since)];
|
||||
return ([.. entries.Where(e => e.At > since)], path);
|
||||
}
|
||||
catch (DbException)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ public sealed record ErrorLogSnapshot
|
|||
/// <summary>The newest entry read; the next collection continues after it.</summary>
|
||||
public required DateTimeOffset ReadUntil { get; init; }
|
||||
|
||||
/// <summary>The default trace's current file when it was read; while it stays the same, only that file is read next time.</summary>
|
||||
public string? TraceFile { get; init; }
|
||||
|
||||
/// <summary>What was found since the previous collection, grouped.</summary>
|
||||
public IReadOnlyList<ErrorLogGroup> Groups { get; init; } = [];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue