CSharpEssentials.LoggerHelper.Sink.HangfireConsole
5.3.2
See the version list below for details.
dotnet add package CSharpEssentials.LoggerHelper.Sink.HangfireConsole --version 5.3.2
NuGet\Install-Package CSharpEssentials.LoggerHelper.Sink.HangfireConsole -Version 5.3.2
<PackageReference Include="CSharpEssentials.LoggerHelper.Sink.HangfireConsole" Version="5.3.2" />
<PackageVersion Include="CSharpEssentials.LoggerHelper.Sink.HangfireConsole" Version="5.3.2" />
<PackageReference Include="CSharpEssentials.LoggerHelper.Sink.HangfireConsole" />
paket add CSharpEssentials.LoggerHelper.Sink.HangfireConsole --version 5.3.2
#r "nuget: CSharpEssentials.LoggerHelper.Sink.HangfireConsole, 5.3.2"
#:package CSharpEssentials.LoggerHelper.Sink.HangfireConsole@5.3.2
#addin nuget:?package=CSharpEssentials.LoggerHelper.Sink.HangfireConsole&version=5.3.2
#tool nuget:?package=CSharpEssentials.LoggerHelper.Sink.HangfireConsole&version=5.3.2
CSharpEssentials.LoggerHelper.Sink.HangfireConsole
Route your
ILogger<T>output directly to the Hangfire Dashboard console — with colors, levels, and zero manual Serilog wiring.
Part of the CSharpEssentials.LoggerHelper ecosystem — install only the sinks you need.
Install
dotnet add package CSharpEssentials.LoggerHelper
dotnet add package CSharpEssentials.LoggerHelper.Sink.HangfireConsole
dotnet add package Hangfire.Console
Supported frameworks: net8.0, net9.0, net10.0.
Quick Start (3 steps)
1. Register the sink BEFORE LoggerHelper
Order matters.
AddHangfireConsoleSink()must be called beforeAddLoggerHelper()because the sink plugin reads the accessor during pipeline construction.
Generic Host (Worker / BackgroundJobs)
Host.CreateDefaultBuilder(args)
.ConfigureServices((ctx, services) => {
services.AddHangfireConsoleSink(); // 1st — register accessor
services.AddLoggerHelper(ctx.Configuration); // 2nd — build Serilog pipeline
services.AddHangfire(cfg => cfg
.UseRedisStorage(connectionString)
.UseConsole()); // 3rd — enable Hangfire.Console
services.AddHangfireServer();
});
WebApplicationBuilder (ASP.NET Core)
builder.Services.AddHangfireConsoleSink();
builder.Services.AddLoggerHelper(builder.Configuration);
2. Add the route in appsettings.LoggerHelper.json
{
"LoggerHelper": {
"ApplicationName": "MyWorker",
"Routes": [
{ "Sink": "Console", "Levels": ["Information","Warning","Error","Fatal"] },
{ "Sink": "HangfireConsole", "Levels": ["Information","Warning","Error","Fatal"] }
]
}
}
No additional configuration needed in the Sinks section. The sink works out of the box with just the route declaration.
3. Set the PerformContext in your job
public class MyJob {
private readonly IPerformContextAccessor _ctx;
private readonly ILogger<MyJob> _logger;
public MyJob(IPerformContextAccessor ctx, ILogger<MyJob> logger) {
_ctx = ctx;
_logger = logger;
}
public async Task Execute(PerformContext performContext) {
_ctx.Set(performContext);
try {
_logger.LogInformation("This appears on the Dashboard!");
_logger.LogWarning("This is yellow on the Dashboard");
} finally {
_ctx.Clear();
}
}
}
All ILogger calls between Set() and Clear() are routed to the Hangfire Dashboard with color-coded log levels.
How It Works
ILogger.LogXxx()
-> Serilog pipeline (built by LoggerHelper)
-> HangfireConsoleSerilogSink.Emit()
-> reads IPerformContextAccessor.Current (AsyncLocal, thread-safe)
-> if inside a job -> writes to Dashboard with color
-> if outside a job -> skips silently
Fluent API (alternative to JSON)
services.AddHangfireConsoleSink();
services.AddLoggerHelper(b => b
.WithApplicationName("MyWorker")
.AddRoute("HangfireConsole",
LogEventLevel.Information, LogEventLevel.Warning,
LogEventLevel.Error, LogEventLevel.Fatal)
.ConfigureHangfireConsole(opts => {
opts.FormatProvider = CultureInfo.InvariantCulture; // optional
})
);
Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
FormatProvider |
IFormatProvider? |
null |
Custom format provider for rendering log messages |
Color Mapping
| Level | Color |
|---|---|
| Verbose | DarkGray |
| Debug | Gray |
| Information | White |
| Warning | Yellow |
| Error | Red |
| Fatal | DarkRed |
Thread Safety
IPerformContextAccessor uses AsyncLocal<T> internally, so parallel jobs running on the same server never interfere with each other. Each async flow sees only its own PerformContext.
Docker / Containerized Environments
Ensure appsettings.LoggerHelper.json is available inside the container:
Option A — Volume mount (recommended for dev)
# docker-compose.yml
volumes:
- ./MyWorker/appsettings.LoggerHelper.json:/app/appsettings.LoggerHelper.json
Option B — Include in publish output (recommended for production)
<Content Include="appsettings.LoggerHelper.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| ILogger on console but not on Dashboard; sink shows FAILED in LoggerHelper Dashboard/MCP | AddHangfireConsoleSink() called after AddLoggerHelper() (or never): the accessor is not registered, so the sink throws InvalidOperationException at configure time |
Swap the call order |
| Nothing anywhere | Config file missing or wrong format | Verify LoggerHelper:Routes exists (v5 format) |
Only RaiseMessage on Dashboard |
Set(performContext) not called |
Inject IPerformContextAccessor, call Set/Clear |
| Works locally, not in Docker | Volume mounts wrong config file | Point to the per-project file, not a root-level copy |
The accessor is held in a process-wide static holder by design (one per process, it keeps no per-request data): it is not a memory leak.
Requirements
| Dependency | Minimum Version |
|---|---|
| .NET | 6.0+ |
| CSharpEssentials.LoggerHelper | 5.0.1+ |
| Hangfire.Console | 1.4.3+ |
Changelog
5.0.2
- Fix:
AddHangfireConsoleSink()now sets the internal static accessor — sink was silently inactive in 5.0.1.
5.0.1
- Initial release with LoggerHelper v5 plugin architecture.
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 is compatible. 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. |
-
net10.0
- CSharpEssentials.LoggerHelper (>= 5.3.2)
- Hangfire.Console (>= 1.4.3)
- Microsoft.NETCore.Jit (>= 2.0.8)
- Newtonsoft.Json (>= 13.0.4)
- Npgsql (>= 10.0.3)
-
net8.0
- CSharpEssentials.LoggerHelper (>= 5.3.2)
- Hangfire.Console (>= 1.4.3)
- Microsoft.NETCore.Jit (>= 2.0.8)
- Newtonsoft.Json (>= 13.0.4)
- Npgsql (>= 10.0.3)
-
net9.0
- CSharpEssentials.LoggerHelper (>= 5.3.2)
- Hangfire.Console (>= 1.4.3)
- Microsoft.NETCore.Jit (>= 2.0.8)
- Newtonsoft.Json (>= 13.0.4)
- Npgsql (>= 10.0.3)
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 |
|---|---|---|
| 5.4.0 | 84 | 10/16/2026 |
| 5.3.3 | 104 | 10/16/2026 |
| 5.3.2 | 87 | 10/11/2026 |
| 5.3.1 | 91 | 10/10/2026 |
| 5.3.0 | 84 | 10/10/2026 |
| 5.2.11 | 89 | 10/9/2026 |
| 5.2.10 | 85 | 10/7/2026 |
| 5.2.9 | 87 | 10/6/2026 |
| 5.2.8 | 95 | 10/6/2026 |
| 5.2.7 | 91 | 10/6/2026 |
| 5.2.6 | 145 | 8/31/2026 |
| 5.2.4.1 | 117 | 8/27/2026 |
| 5.2.4 | 115 | 8/25/2026 |
| 5.2.3 | 114 | 8/25/2026 |
| 5.2.2.9 | 142 | 7/11/2026 |
| 5.2.2.8 | 133 | 7/11/2026 |
| 5.2.2.7 | 130 | 7/10/2026 |
| 5.2.2.6 | 130 | 7/6/2026 |
| 5.2.2.5 | 124 | 7/5/2026 |
| 5.2.2.4 | 125 | 7/5/2026 |