Enrichment & Correlation IDs

Attach useful properties (enrichment) to your log events and add a per-request correlation ID so you can trace a single request across multiple log lines and even across languages (PowerShell and C# routes).

See the Logging guide for in-depth enrichment options and Serilog helpers.

Full source

File: pwsh/tutorial/examples/5.3-Enrichment-Correlation-IDs.ps1

<#
    Sample demonstrating enrichment and correlation IDs.
    - Adds a global property 'App' to the logger
    - For each request, generates a CorrelationId and attaches it to log events
    FileName: 5.3-Enrichment-Correlation-IDs.ps1
#>

param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

$appLogger = New-KrLogger |
    Set-KrLoggerLevel -Value Debug |
    Add-KrEnrichProperty -Name 'App' -Value 'LoggingSamples' |
    Add-KrEnrichFromLogContext |
    Add-KrSinkConsole -OutputTemplate "[{App} {Timestamp:HH:mm:ss} {Level:u3} {CorrelationId}] {Message:lj}{NewLine}{Exception}" |
    Add-KrSinkFile -Path '.\logs\enrichment.log' -RollingInterval Hour -OutputTemplate "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] ({App}) {CorrelationId} {Message:lj}{NewLine}{Exception}" |
    Register-KrLogger -Name 'app' -PassThru

New-KrServer -Name "Enrichment & Correlation IDs"
Add-KrEndpoint -Port $Port -IPAddress $IPAddress


Enable-KrConfiguration

# PowerShell route that adds a correlation id to each log event as a property
Add-KrMapRoute -Verbs Get -Path "/ps-correlation" -ScriptBlock {
    $corr = [guid]::NewGuid().ToString('N')
    $scope = Push-KrLogContextProperty -Name CorrelationId -Value $corr
    try {
        Write-KrLog -Logger $appLogger -Level Information -Message "Handling /ps-correlation"
        Write-KrLog -Logger $appLogger -Level Debug -Message "Processing details"
        Write-KrTextResponse -InputObject "ps-correlation: $corr" -StatusCode 200
    } finally {
        $scope.Dispose()
    }
}

# C# route demonstrating per-request context using ForContext
Add-KrMapRoute -Verbs Get -Path "/csharp-correlation" -Code @"
    var correlationId = Guid.NewGuid().ToString("N");
    var log = appLogger.ForContext("CorrelationId", correlationId);
    log.Information("Handling /csharp-correlation");
    log.Debug("Processing details");
    Context.Response.WriteTextResponse($"csharp-correlation: {correlationId}", 200);
"@ -Language CSharp



# Start the server
Start-KrServer


# Clean up and close the logger when the server stops
Close-KrLogger -Logger $appLogger

Step-by-step

  1. Build a logger with minimum Debug, add a global property App, enable FromLogContext, and sinks (console + file).
  2. Standard server, listener, PowerShell runtime; then apply config with Enable-KrConfiguration.
  3. PowerShell route /ps-correlation:
    • Generate a correlation ID per request ([guid]::NewGuid().ToString('N')).
    • Push to LogContext using Push-KrLogContextProperty -Name CorrelationId -Value $corr for the scope of the request.
  4. C# route /csharp-correlation:
    • Use appLogger.ForContext("CorrelationId", id) to enrich subsequent events.
  5. Start with Start-KrServer.

Try it

Save the sample locally so the log file is easy to find. Copy the contents of pwsh/tutorial/examples/5.3-Enrichment-Correlation-IDs.ps1 into a new file in an empty working folder (for example, enrichment.ps1), then run:

# From your working folder
pwsh .\enrichment.ps1
curl http://127.0.0.1:5000/ps-correlation
curl http://127.0.0.1:5000/csharp-correlation
Get-Content .\logs\enrichment.log -Tail 40

Expected: Each request shows a unique CorrelationId on all events for that request.

Note:

Custom properties like CorrelationId and App must be referenced in the sink OutputTemplate to be displayed. The example sets console to [{App} {Timestamp:HH:mm:ss} {Level:u3} {CorrelationId}] {Message} and file to {Timestamp} [{Level}] ({App}) {CorrelationId} {Message}.

Customizing

  • Add more properties globally with Add-KrEnrichProperty (e.g., Environment, Version).
  • Use Serilog enrichers (machine name, thread id, etc.).
  • Consider setting a request header (e.g., X-Correlation-Id) and reusing it if present.
  • To enable Kestrun framework logs, set your logger as default or pass it via New-KrServer.

Troubleshooting

Symptom Cause Fix
No CorrelationId appears in events Property name mismatch Ensure key is exactly CorrelationId
Different IDs in one request’s lines New GUID generated per log call Generate once per request and reuse
No logs written Minimum level too high / bad path Lower minimum; verify file path and permissions
Cannot delete/rename log file Logger still open / file handle Run Close-KrLogger; let the process exit

References


Previous / Next

Go back to Multiple Loggers & Levels or continue to Sinks (Console/File/JSON). Guide: Logging (Concepts)