KhaosKode.Logging 1.0.7

Additional Details

This was a bit of an experiment to see how to use nuget. I understand a tiny bit more now than before. Please feel free to look at the KhaosKoder.* series of packages. They replace this package - with absolutely minimal code changes required. I will try to keep the packages stable under those names from here on.

dotnet add package KhaosKode.Logging --version 1.0.7
                    
NuGet\Install-Package KhaosKode.Logging -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KhaosKode.Logging" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KhaosKode.Logging" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="KhaosKode.Logging" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KhaosKode.Logging --version 1.0.7
                    
#r "nuget: KhaosKode.Logging, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KhaosKode.Logging@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KhaosKode.Logging&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=KhaosKode.Logging&version=1.0.7
                    
Install as a Cake Tool

Khaos.Logging

Typed, discoverable logging built on top of Microsoft.Extensions.Logging. Khaos.Logging lets you describe every loggable event once—as an enum—and generates a fully navigable logger surface so you can write _log.DB.Connection.Open.LogInformation("Opening connection") without manually wiring scopes, event IDs, or categories.

Why Another Logging Layer?

ILogger is flexible, but large applications end up with stringly-typed event IDs, ad-hoc scopes, and no shared vocabulary. We wanted:

  • A single source of truth for events (enums) that doubles as documentation.
  • Automatic, hierarchical loggers that mirror your domain while preserving ILogger<T> categories.
  • Guardrails: analyzers that catch duplicate IDs, naming mistakes, or invalid values.
  • Zero runtime reflection and no magic DI setup—everything compiles ahead of time.

Khaos.Logging keeps ILogger in the picture; it simply builds strongly-typed façades over it so your team can reason about events the same way they reason about APIs.

How It Works

  1. Annotate an enum with [LogEventSource] and follow the AREA_Group_Action naming convention.
  2. The incremental source generator emits:
    • A root logger (customizable name) and nested loggers for each area/group token.
    • IEventLogger properties per enum member, prewired with EventId and an EventPath scope.
    • A DI extension AddGeneratedLogging() registering everything as scoped generics.
  3. The runtime provides the lightweight EventLogger implementation and attribute definitions.
  4. The analyzer project enforces duplicate-ID detection, naming guidance, and other correctness checks.

Quick Start

  1. Install the package

     dotnet add package KhaosCode.Logging
    
  2. Declare your log events

     using Khaos.Logging;
    
     namespace MyApp.Logging;
    
     [LogEventSource(LoggerRootTypeName = "MyLogger", BasePath = "MyApp")]
     public enum LogEventIds
     {
     	 APP_Startup = 1000,
     	 APP_ReadConfiguration = 1001,
     	 DB_Connection_Open = 2000,
     	 DB_Connection_Close = 2001
     }
    
  3. Register generated loggers

     builder.Services.AddLogging();
     builder.Services.AddGeneratedLogging();
    

    Or use Serilog with LogStash:

     builder.Services.AddKhaosSerilogLogging(options =>
     {
         options.WriteToConsole = true;
         options.LogStash = new LogStashOptions
         {
             Host = "elk.example.com",
             Port = 5044,
             ApplicationName = "MyApp"
         };
     });
     builder.Services.AddGeneratedLogging();
    
  4. Inject and use

     public sealed class StartupService
     {
     	 private readonly MyLogger<StartupService> _log;
    
     	 public StartupService(MyLogger<StartupService> log) => _log = log;
    
     	 public void Start()
     	 {
     		  _log.App.Startup.LogInformation("StartupService online");
     		  _log.DB.Connection.Open.LogDebug("Opening DB for {Tenant}", "Contoso");
     	 }
     }
    

Generated loggers always respect ILogger<T> categories, emit scopes with EventPath = "MyApp.DB.Connection.Open", and keep the enum value wired to EventId.Id. You can still inject a plain ILogger<T> anywhere—it remains the same DI container and the two coexist without adapters.

FAQ: Why Not Just Use ILogger?

You absolutely can (and still do). Khaos.Logging is a layer on top of ILogger that eliminates repetitive plumbing:

  • Discoverability: Instead of searching for numeric IDs or message templates, IDE completion guides you through areas/groups/actions.
  • Consistency: Event IDs, names, and scopes are generated from the enum, so they cannot drift.
  • Safety nets: The analyzers fail the build if you accidentally duplicate IDs or misapply attributes.

When a dependency expects ILogger you keep supplying ILogger; generated loggers internally use the same ILogger<T> instances, so you can mix and match without wrappers. Think of the generated APIs as purpose-built entry points into the existing logging infrastructure, not a replacement.

Serilog Integration

For production scenarios requiring structured logging to ELK/LogStash, install the Serilog package:

dotnet add package KhaosCode.Logging.Serilog

See the User Guide for full configuration options.

Design Principles

  • Enums as contracts: Everything—EventId, scope metadata, documentation—derives from the annotated enum.
  • Hierarchical surface: Area/group/action tokens become nested types, mirroring the shape of your domain.
  • No runtime surprises: All code is generated at build time; DI registration is explicit and scoped.
  • Pluggable backends: Use Microsoft.Extensions.Logging (default) or Serilog with LogStash.
  • Documentation included: The NuGet ships the docs/ folder plus build-transitive targets that copy it into consuming solutions for easy reference.

Documentation

  • Specification – end-to-end, low-level requirements.
  • User Guide – installation, configuration, and day-to-day usage tips.
  • Developer Guide – repo layout, build/test workflow, release checklist.
  • Versioning Guide – explains MinVer tagging conventions and release numbering.
  • Scripts Reference – details each helper script, parameters, and expected output.

Explore the guides, run scripts/test-with-coverage.ps1, and open TestResults/.../coverage-html/index.html to see test coverage while you iterate. When you're ready to publish, scripts/publish.ps1 -ApiKey <token> handles packing and pushing both the runtime and symbol packages.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 100 3/12/2026 1.0.7 is deprecated because it is no longer maintained.