Genocs.Logging Agent Reference
This document is optimized for AI-assisted development sessions.
Genocs.Logging Agent Reference
Purpose
This document is optimized for AI-assisted development sessions. It prioritizes fast retrieval of:
- What Genocs.Logging is responsible for
- Which APIs to call for specific logging goals
- Where source of truth lives for sinks, options, and decorators
- What constraints and runtime behaviors matter
Quick Facts
| Key | Value |
|---|---|
| Package | Genocs.Logging |
| Project file | src/Genocs.Logging/Genocs.Logging.csproj |
| Target frameworks | net10.0, net9.0, net8.0 |
| Primary role | Serilog-based structured logging with multi-sink support, correlation context enrichment, dynamic log level control, and CQRS handler logging decorators |
| Core themes | Serilog pipeline setup, sink configuration (Console, File, ELK, Seq, Loki, Azure App Insights, OTLP), log level switching at runtime, HTTP request/response body capture, CQRS decorator logging |
Use This Package When
- Bootstrapping Serilog in an ASP.NET Core or Worker host
- Routing structured logs to Elasticsearch, Seq, Grafana/Loki, or Azure Application Insights simultaneously
- Enriching logs with OpenTelemetry span IDs, machine name, process/thread IDs, and custom tags
- Injecting request/response body content into log scopes for debugging HTTP traffic
- Wrapping command or event handlers with automatic before/after/on-error log entries
- Exposing a dynamic log-level change HTTP endpoint without restarting the service
Do Not Assume
UseLogging()must be called onIHostBuilder— calling it onWebApplicationBuilder.Hostis the ASP.NET Core entry path; calling it on aHostBuilderworks for Worker services- Sinks are opt-in via
appsettings.json— every sink block has anEnabledgate; an empty or missing config section leaves all sinks off except what is wired manually StaticLogger.EnsureInitialized()is a bootstrap-only logger — it is intended for use beforeUseLogging()is called so that startup exceptions are captured; it is not a substitute for configuring the main logger
High-Value Entry Points
Host Setup
UseLogging(this IHostBuilder, Action<HostBuilderContext, LoggerConfiguration>?, string?, string?)in src/Genocs.Logging/Extensions.csStaticLogger.EnsureInitialized()in src/Genocs.Logging/Startup.cs
Correlation & Middleware
AddCorrelationContextLogging(this IGenocsBuilder)in src/Genocs.Logging/Extensions.csUseCorrelationContextLogging(this IApplicationBuilder)in src/Genocs.Logging/Extensions.csCorrelationContextLoggingMiddlewarein src/Genocs.Logging/CorrelationContextLoggingMiddleware.cs
Dynamic Log Level
MapLogLevelHandler(this IEndpointRouteBuilder, string endpointRoute)in src/Genocs.Logging/Extensions.csILoggingService.SetLoggingLevel(string)in src/Genocs.Logging/LoggingService.csLoggingServicein src/Genocs.Logging/LoggingService.cs
CQRS Decorator Logging
AddCommandHandlersLogging(this IGenocsBuilder, Assembly?)in src/Genocs.Logging/CQRS/Extensions.csAddEventHandlersLogging(this IGenocsBuilder, Assembly?)in src/Genocs.Logging/CQRS/Extensions.csCommandHandlerLoggingDecorator<TCommand>in src/Genocs.Logging/CQRS/Decorators/CommandHandlerLoggingDecorator.csEventHandlerLoggingDecorator<TEvent>in src/Genocs.Logging/CQRS/Decorators/EventHandlerLoggingDecorator.csIMessageToLogTemplateMapperin src/Genocs.Logging/CQRS/IMessageToLogTemplateMapper.csHandlerLogTemplatein src/Genocs.Logging/CQRS/HandlerLogTemplate.cs
Configuration Options
LoggerOptions(config key:logger) in src/Genocs.Logging/Configurations/LoggerOptions.csConsoleOptionsin src/Genocs.Logging/Configurations/ConsoleOptions.csLocalFileOptionsin src/Genocs.Logging/Configurations/LocalFileOptions.csElkOptionsin src/Genocs.Logging/Configurations/ElkOptions.csSeqOptionsin src/Genocs.Logging/Configurations/SeqOptions.csLokiOptionsin src/Genocs.Logging/Configurations/LokiOptions.csAzureOptionsin src/Genocs.Logging/Configurations/AzureOptions.csHttpPayloadOptionsin src/Genocs.Logging/Configurations/HttpPayloadOptions.cs
Decision Matrix For Agents
| Goal | Preferred API | Notes |
|---|---|---|
| Bootstrap Serilog in a host | hostBuilder.UseLogging() | Call before builder.Build(); reads logger and app config sections |
| Capture startup errors before Serilog is ready | StaticLogger.EnsureInitialized() | Call at the very top of Program.cs, before any Serilog setup |
| Enrich logs with HTTP baggage and request/response bodies | AddCorrelationContextLogging() + UseCorrelationContextLogging() | Opt-in body capture via HttpPayloadOptions.CaptureRequestBody / CaptureResponseBody |
| Change log level at runtime without restart | MapLogLevelHandler(app, "/logging/level") | Exposes a POST endpoint; body param level accepts Serilog level names |
| Add structured log entries around every command | AddCommandHandlersLogging(gnxBuilder) | Uses [Decorator] + Scrutor to wrap all ICommandHandler<> in the assembly |
| Add structured log entries around every event handler | AddEventHandlersLogging(gnxBuilder) | Same Scrutor decoration pattern for IEventHandler<> |
| Customize log message templates per command/event | Implement IMessageToLogTemplateMapper | Return a HandlerLogTemplate with Before, After, and per-exception templates; uses SmartFormat |
| Route logs to Elasticsearch | Set logger:elk:enabled: true and logger:elk:url | Supports basic auth and configurable index format |
| Route logs to Grafana/Loki | Set logger:loki:enabled: true and logger:loki:url | Supports optional credentials and batch posting settings |
| Route logs to Azure Application Insights | Set logger:azure:enabled: true and logger:azure:connectionString | Uses Serilog.Sinks.ApplicationInsights |
| Send logs over OpenTelemetry | Set logger:otlpEndpoint | Writes to Serilog.Sinks.OpenTelemetry OTLP exporter |
Minimal Integration Recipe
Install
dotnet add package Genocs.Logging
Setup in Program.cs
using Genocs.Common.Configurations;
using Genocs.Core.Builders;
using Genocs.Logging;
// Bootstrap logger for startup diagnostics (before host builds)
StaticLogger.EnsureInitialized();
var builder = WebApplication.CreateBuilder(args);
// Wire Serilog via IHostBuilder
builder.Host.UseLogging();
// Register correlation context middleware (optional)
IGenocsBuilder gnxBuilder = builder.AddGenocs();
gnxBuilder.AddCorrelationContextLogging();
// If using CQRS decorator logging (optional)
// gnxBuilder.AddCommandHandlersLogging();
// gnxBuilder.AddEventHandlersLogging();
gnxBuilder.Build();
var app = builder.Build();
// Activate correlation context enrichment (optional)
app.UseCorrelationContextLogging();
// Expose dynamic log-level endpoint (optional)
app.MapLogLevelHandler("/logging/level");
app.Run();
appsettings.json
{
"app": {
"name": "MyService",
"service": "my-service",
"instance": "1",
"version": "1.0.0"
},
"logger": {
"enabled": true,
"level": "Information",
"otlpEndpoint": "",
"console": { "enabled": true, "enableStructured": false },
"file": { "enabled": false, "path": "logs/logs.txt", "interval": "Day" },
"elk": { "enabled": false, "url": "http://localhost:9200", "indexFormat": "my-service-{0:yyyy.MM.dd}" },
"seq": { "enabled": false, "url": "http://localhost:5341" },
"loki": { "enabled": false, "url": "http://localhost:3100" },
"azure": { "enabled": false, "connectionString": "" },
"httpPayload": { "enabled": false, "captureRequestBody": false, "captureResponseBody": false },
"minimumLevelOverrides": { "Microsoft": "Warning", "System": "Warning" },
"excludePaths": ["/health", "/metrics"],
"tags": { "team": "backend" }
}
}
Behavior Notes That Affect Agent Decisions
UseLogging()registersILoggingServiceas a singleton automatically;MapLogLevelHandlerrelies on it — do not forget to callUseLogging()if using the dynamic level endpoint- The minimum log level is managed through a shared
LoggingLevelSwitchinstance; changing the level viaSetLoggingLevel()affects all sinks simultaneously AddCommandHandlersLogging/AddEventHandlersLoggingdiscover handlers inAssembly.GetCallingAssembly()by default; pass an explicitAssemblyparameter if handlers live in a different project- Structured console output (JSON) is activated by
console.enableStructured: true— use plain-text console for local dev, structured JSON for production log aggregation - Elasticsearch sink uses
AutoRegisterTemplate = truewith v6 format; explicitindexFormatoverride is strongly recommended for production to avoid date-partitioned index name collisions CorrelationContextLoggingMiddlewarereadsActivity.Current.Baggage(W3C trace baggage) and injects it as log scope properties; ensureAddCorrelationContextLogging()is called beforegnxBuilder.Build()- HTTP body capture is opt-in per direction (
CaptureRequestBody,CaptureResponseBody); enabling response body capture buffers the response stream and may affect memory allocation under high load HandlerLogTemplatemessages are formatted using SmartFormat.NET syntax, allowing property interpolation from the command/event object (e.g.,"Handling order {OrderId}")
Source-Accurate Capability Map
Host & Serilog Pipeline Setup
UseLogging(IHostBuilder, ...)— main entry point; readsLoggerOptionsfrom config, applies all enrichers and sink wiring, registersILoggingServiceMapOptions(...)— internal; applies enrichers:FromLogContext,WithProperty,WithExceptionDetails,WithMachineName,WithProcessId,WithThreadId,WithSpan,MinimumLevelOverrides,ExcludePaths,TagsConfigure(...)— internal; activates each sink based on itsEnabledflag; supports Console, File, ELK, Seq, Loki, Azure AI, OTLP
Files:
Correlation Context Middleware
CorrelationContextLoggingMiddleware— reads W3C Activity baggage and injects into log scope; optionally captures request/response bodies into log scope and as Activity tagsAddCorrelationContextLogging(IGenocsBuilder)— registers middleware as transient DI serviceUseCorrelationContextLogging(IApplicationBuilder)— adds middleware to HTTP pipeline
Files:
Dynamic Log Level Control
ILoggingService/LoggingService— thin service withSetLoggingLevel(string)that updates the sharedLoggingLevelSwitchMapLogLevelHandler(IEndpointRouteBuilder, string)— maps a POST endpoint; reads?level=query param and callsILoggingServiceLoggingLevelSwitch— internal SerilogLoggingLevelSwitchinstance; updated without restarting the host
Files:
CQRS Handler Logging Decorators
AddCommandHandlersLogging(IGenocsBuilder, Assembly?)— discovers allICommandHandler<>implementations and wraps each inCommandHandlerLoggingDecorator<TCommand>using Scrutor’sTryDecorateAddEventHandlersLogging(IGenocsBuilder, Assembly?)— same forIEventHandler<>CommandHandlerLoggingDecorator<TCommand>— logsBefore,After, and per-exception messages usingHandlerLogTemplateformatted via SmartFormat; falls back silently if no template is registeredEventHandlerLoggingDecorator<TEvent>— identical structure for event handlers
Files:
- src/Genocs.Logging/CQRS/Extensions.cs
- src/Genocs.Logging/CQRS/Decorators/CommandHandlerLoggingDecorator.cs
- src/Genocs.Logging/CQRS/Decorators/EventHandlerLoggingDecorator.cs
Message-to-Template Mapping
IMessageToLogTemplateMapper— resolves aHandlerLogTemplatefor a given message instance; returnnullto skip loggingHandlerLogTemplate—Before,After, and exception-specific template strings;GetExceptionTemplate(Exception)selector method- Default behavior: if
IMessageToLogTemplateMapperis not registered in DI, the decorator uses an internal no-op mapper and skips log emission
Files:
Sink Configuration Options
LoggerOptions— root config:Enabled,Level,OtlpEndpoint, sub-objects per sink,Tags,MinimumLevelOverrides,ExcludePaths,ExcludePropertiesConsoleOptions—Enabled,EnableStructured(JSON formatter for structured output)LocalFileOptions—Enabled,Path,Interval(e.g.,"Day","Hour")ElkOptions—Enabled,Url,BasicAuthEnabled,Username,Password,IndexFormatSeqOptions—Enabled,Url,ApiKeyLokiOptions—Enabled,Url,LokiUsername,LokiPassword,BatchPostingLimit,QueueLimit,PeriodAzureOptions—Enabled,ConnectionStringHttpPayloadOptions—Enabled,CaptureRequestBody,CaptureResponseBody
Files:
- src/Genocs.Logging/Configurations/LoggerOptions.cs
- src/Genocs.Logging/Configurations/ElkOptions.cs
- src/Genocs.Logging/Configurations/SeqOptions.cs
- src/Genocs.Logging/Configurations/LokiOptions.cs
- src/Genocs.Logging/Configurations/AzureOptions.cs
- src/Genocs.Logging/Configurations/HttpPayloadOptions.cs
Dependencies
From src/Genocs.Logging/Genocs.Logging.csproj:
Genocs.Core—IGenocsBuilder,GetOptions<T>()configuration helperSerilog.AspNetCore— Serilog / ASP.NET Core integration,UseSerilog()onIHostBuilderSerilog.Sinks.ElasticSearch— Elasticsearch sinkSerilog.Sinks.Seq— Seq sinkSerilog.Sinks.Grafana.Loki— Grafana/Loki sinkSerilog.Sinks.ApplicationInsights— Azure Application Insights sinkSerilog.Sinks.OpenTelemetry— OTLP exporter sinkSerilog.Sinks.File— rolling file sinkSerilog.Sinks.Async— wraps other sinks in async buffered modeSerilog.Enrichers.Environment/.Process/.Thread/.Span— standard enrichersSerilog.Exceptions—WithExceptionDetails()enricherMicrosoft.ApplicationInsights— Azure AI telemetry infrastructureSmartFormat.NET—Smart.Format(template, command)in CQRS decorators
Related Docs
- NuGet package readme: src/Genocs.Logging/README_NUGET.md
- Repository guide: README.md
- Package documentation: docs/Genocs.Logging-Agent-Documentation.md
- Genocs.Core reference: docs/Genocs.Core-Agent-Documentation.md