feat(logging): build-config debug logging + task traceability #8
44
src/ClaudeDo.Logging/LoggingSetup.cs
Normal file
44
src/ClaudeDo.Logging/LoggingSetup.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using Serilog;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace ClaudeDo.Logging;
|
||||||
|
|
||||||
|
public static class LoggingSetup
|
||||||
|
{
|
||||||
|
private const string OutputTemplate =
|
||||||
|
"[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Process}/{SourceContext} [{TaskId}] {Message:lj}{NewLine}{Exception}";
|
||||||
|
|
||||||
|
public static LoggerConfiguration Configure(LoggerConfiguration cfg, string processTag, string logRoot)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logRoot);
|
||||||
|
var logFile = Path.Combine(logRoot, "claudedo-.log");
|
||||||
|
|
||||||
|
cfg.Enrich.FromLogContext()
|
||||||
|
.Enrich.WithProperty("Process", processTag)
|
||||||
|
.Enrich.With(new DefaultTaskIdEnricher());
|
||||||
|
|
||||||
|
if (BuildConfig.IsDebug)
|
||||||
|
{
|
||||||
|
cfg.MinimumLevel.Debug()
|
||||||
|
.WriteTo.Console(outputTemplate: OutputTemplate)
|
||||||
|
.WriteTo.File(
|
||||||
|
logFile,
|
||||||
|
rollingInterval: RollingInterval.Day,
|
||||||
|
retainedFileCountLimit: 2,
|
||||||
|
shared: true,
|
||||||
|
outputTemplate: OutputTemplate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cfg.MinimumLevel.Warning()
|
||||||
|
.WriteTo.File(
|
||||||
|
logFile,
|
||||||
|
rollingInterval: RollingInterval.Day,
|
||||||
|
retainedFileCountLimit: 2,
|
||||||
|
shared: true,
|
||||||
|
outputTemplate: OutputTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
tests/ClaudeDo.Worker.Tests/Logging/LoggingSetupTests.cs
Normal file
30
tests/ClaudeDo.Worker.Tests/Logging/LoggingSetupTests.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using ClaudeDo.Logging;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace ClaudeDo.Worker.Tests.Logging;
|
||||||
|
|
||||||
|
public sealed class LoggingSetupTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Configure_WritesSharedLogFile()
|
||||||
|
{
|
||||||
|
var logRoot = Path.Combine(Path.GetTempPath(), "claudedo-logtest-" + Guid.NewGuid().ToString("N"));
|
||||||
|
Directory.CreateDirectory(logRoot);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var logger = LoggingSetup.Configure(new LoggerConfiguration(), "test", logRoot).CreateLogger();
|
||||||
|
logger.Warning("marker-{Marker}", "xyz");
|
||||||
|
logger.Dispose(); // flush + release the file handle
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(logRoot, "claudedo-*.log");
|
||||||
|
var file = Assert.Single(files);
|
||||||
|
var contents = File.ReadAllText(file);
|
||||||
|
Assert.Contains("marker-", contents);
|
||||||
|
Assert.Contains("test/", contents); // {Process} tag in the template
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { Directory.Delete(logRoot, recursive: true); } catch { /* best effort */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user