feat: add per-subsystem log control via --log_level_override CLI flag

Adds LogOverrides property to NatsOptions and a --log_level_override=namespace=level CLI flag that wires Serilog MinimumLevel.Override entries so operators can tune verbosity per .NET namespace without changing the global log level.
This commit is contained in:
Joseph Doherty
2026-02-23 04:34:01 -05:00
parent d0af741eb8
commit d69308600a
3 changed files with 42 additions and 0 deletions

View File

@@ -85,6 +85,14 @@ for (int i = 0; i < args.Length; i++)
case "--service":
windowsService = true;
break;
case "--log_level_override" when i + 1 < args.Length:
var parts = args[++i].Split('=', 2);
if (parts.Length == 2)
{
options.LogOverrides ??= new();
options.LogOverrides[parts[0]] = parts[1];
}
break;
}
}
@@ -135,6 +143,16 @@ else if (options.Syslog)
logConfig.WriteTo.LocalSyslog("nats-server");
}
// Apply per-subsystem log level overrides
if (options.LogOverrides is not null)
{
foreach (var (ns, level) in options.LogOverrides)
{
if (Enum.TryParse<Serilog.Events.LogEventLevel>(level, true, out var serilogLevel))
logConfig.MinimumLevel.Override(ns, serilogLevel);
}
}
Log.Logger = logConfig.CreateLogger();
if (windowsService)

View File

@@ -90,5 +90,8 @@ public sealed class NatsOptions
public OcspConfig? OcspConfig { get; set; }
public bool OcspPeerVerify { get; set; }
// Per-subsystem log level overrides (namespace -> level)
public Dictionary<string, string>? LogOverrides { get; set; }
public bool HasTls => TlsCert != null && TlsKey != null;
}

View File

@@ -15,3 +15,24 @@ public class NatsOptionsTests
opts.Tags.ShouldBeNull();
}
}
public class LogOverrideTests
{
[Fact]
public void LogOverrides_defaults_to_null()
{
var options = new NatsOptions();
options.LogOverrides.ShouldBeNull();
}
[Fact]
public void LogOverrides_can_be_set()
{
var options = new NatsOptions
{
LogOverrides = new() { ["NATS.Server.Protocol"] = "Trace" }
};
options.LogOverrides.ShouldNotBeNull();
options.LogOverrides["NATS.Server.Protocol"].ShouldBe("Trace");
}
}