feat: structured logging infrastructure with Serilog-style timestamps #15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/structured-logging"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a structured
ILogger<T>logging infrastructure with a Serilog-style console timestamp, plus request logging middleware and domain operation logging across Infrastructure and RestAdapter.Console output format
Every log line now starts with a full timestamp including timezone offset:
What changed
1. Console formatter (
Program.cs+appsettings.json)SimpleConsoleFormatterwithTimestampFormat = "yyyy-MM-dd HH:mm:ss.fffzzz "appsettings.json: addedMicrosoft.EntityFrameworkCore: WarningandDoujinManager: Informationto keep the signal-to-noise ratio high2. Request logging middleware (new)
RequestLoggingMiddleware— logs every HTTP request with method, path, status code, and elapsed milliseconds:/health,/scalar,/openapiRegistered as the outermost middleware (before
GlobalExceptionMiddleware) so it always captures the final status code.3. Infrastructure domain logging
Added
ILogger<T>to the classes with meaningful state transitions:ImageServiceDoujinServiceBackupServiceUploadPagesUseCaseUploadZipPagesUseCaseDeletePageUseCaseAll messages use structured logging placeholders (
{DoujinId},{VariantId}, etc.) so they're queryable in log aggregators.4. Package reference
Added
Microsoft.Extensions.Logging.AbstractionstoApplicationCore(via CPM) soILogger<T>is available across all layers without pulling in the full logging implementation.Tests
4 new
RequestLoggingMiddlewareTests:SuccessfulRequest_LogsAtInformation_WithStructuredFields— verifies GET /api/ok → 200 at Information with method/path/status/msNotFoundRequest_LogsAtWarning— verifies 404 → WarningServerError_LogsAtError— verifies 500 → ErrorHealthEndpoint_LogsAtDebugLevel— verifies /health routes to Debug (direct middleware unit test)Updated
ImageUseCaseTeststo passNullLogger<T>.Instanceto the new constructor params.All 238 tests pass (13 ApplicationCore + 43 Infrastructure + 1 Integration + 181 RestAdapter).
Files changed
2 new files:
RestAdapter/Middleware/RequestLoggingMiddleware.csRestAdapter.Tests/Middleware/RequestLoggingMiddlewareTests.cs10 modified:
Program.cs,appsettings.json,Directory.Packages.propsApplicationCore.csproj(added logging abstractions package ref)RestAdapterExtensions.cs(register new middleware)ImageService.cs,DoujinService.cs,BackupService.csImageUseCases.cs(Upload/Zip/DeletePage use cases)ImageUseCaseTests.cs(constructor param updates)Summary
Summary
Coverage
DoujinManager.ApplicationCore - 84.8%
DoujinManager.Infrastructure - 91.6%
pshot
DoujinManager.RestAdapter - 83.9%
E5CB12CEAC5BBBEA65844E1C05F9ADA4DA38B848075C41304FC6A1ABF77__ValidationAttr
ibuteCache
DoujinManager.Server - 16.6%
🤖 Hermes automated review: no blocking issues found
Reviewed all 12 changed files (+302/-18) on head
a0fca665. The PR adds structured logging infrastructure cleanly and safely. Static security scan on added lines: clean (no secrets, shell injection, eval/exec, or SQL injection).What's good
RequestLoggingMiddleware— try/finally guarantees the status code is logged even when downstream throws; status-based log levels (5xx→Error, 4xx→Warning, 2xx/3xx→Info,/health&docs→Debug) are sensible. Structured placeholders ({Method},{Path},{StatusCode},{ElapsedMs}) are used correctly as template parameters.ImageUseCases.csconverts previously-swallowedcatch {}blocks intocatch (Exception ex)+logger.LogError(ex, ...)inUploadPagesUseCase,UploadZipPagesUseCase, andDeletePageUseCase. This strictly improves observability without changing control flow (rollback + best-effort cleanup behavior is unchanged). 👍Microsoft.Extensions.Logging.Abstractionsto ApplicationCore (via CPM) makesILogger<T>available across layers without pulling the full logging implementation. Clean.RequestLoggingMiddlewareTestscover the status→log-level routing and structured fields; existing use-case tests updated withNullLogger<T>.Instance.Minor notes (non-blocking)
RestAdapter.Tests/Middleware/RequestLoggingMiddlewareTests.csis missing a trailing newline (\ No newline at end of file). Trivial.BackupService.cs:71logs the full filesystem backup path at Information (Database backup created: {BackupPath}). Fine for ops, but be aware it exposes the on-disk directory layout in shared log sinks.ExecuteSqlRawAsync($"VACUUM INTO '{escaped}'", ct)inBackupServiceuses string interpolation with single-quote-doubling escaping. It's unchanged by this PR (only a nearby log line was added), and was covered in prior reviews. Mentioning only for completeness.Verification
a0fca665(line 83.5%, branch 49.4%; coverage dated 10:46:45–10:46:57 UTC, matching PR creation at 12:46 CEST). The repo'sci.ymlposts coverage only on successful build+test, so build+test passed. Local build/test skipped per CI-evidence policy.RequestLoggingMiddlewareshows 100% line / 100% branch coverage in the CI report.Note: this is not a formal Forgejo review approval — the current MCP integration can post conversation comments but cannot create inline review comments or approval states.
Automated review. I never merge PRs.