CSharpEssentials.LoggerHelper is a modular, centralized hub for Serilog sinks that delivers comprehensive observability . Its flexible JSON‑based configuration lets you decide which log levels go to which sink—for example, routing only Error messages to email while sending all logs to ElasticSearch—without touching your code . The package unifies logs, metrics and traces via OpenTelemetry; every log entry carries a trace_id to correlate distributed requests, and an interactive dashboard lets you visualize traces, sink failures and telemetry, and configure alerts . Standard structured fields (e.g., IdTransaction, ApplicationName, MachineName, Action) are included by default, and you can enrich logs with custom properties that propagate across all sinks . Each sink—Console, File, MSSQL, PostgreSQL, ElasticSearch, Email, Telegram, xUnit, Telemetry, Dashboard and AI—is delivered as a separate NuGet package, so you install only what you need; the core loads them dynamically and exposes CurrentError and an in‑memory Errors queue to simplify debugging . The latest AI integration enables natural‑language queries against logs, trace correlation for root‑cause analysis, anomaly detection and automatic incident summaries , while the new xUnit sink captures full traces of failed tests directly in your test output—ideal for debugging flaky tests or disconnected environments
$ dotnet add package CSharpEssentials.LoggerHelperA flexible and powerful logging library for .NET applications that simplifies the implementation of structured logging with multiple sink options.
dotnet add package CSharpEssentials.LoggerHelper
The library requires an external configuration file named appsettings.LoggerHelper.json in your project root directory. The library will read its configuration exclusively from this file.
Create an appsettings.LoggerHelper.json file in your project root with the following structure:
{
"Serilog": {
"SerilogConfiguration": {
"SerilogCondition": [
{
"Sink": "Console",
"Level": ["Information", "Warning", "Error", "Fatal"]
},
{
"Sink": "File",
"Level": ["Error", "Fatal"]
},
{
"Sink": "PostgreSQL",
"Level": ["Error", "Fatal"]
},
{
"Sink": "MSSqlServer",
"Level": ["Error", "Fatal"]
},
{
"Sink": "Telegram",
"Level": ["Fatal"]
},
{
"Sink": "ElasticSearch",
"Level": []
}
],
"SerilogOption": {
"PostgreSQL": {
"connectionstring": "Host=localhost;Database=logs;Username=postgres;Password=yourpassword"
},
"MSSqlServer": {
"connectionString": "Server=localhost;Database=Logs;Trusted_Connection=True;",
"sinkOptionsSection": {
"tableName": "Logs",
"schemaName": "dbo",
"autoCreateSqlTable": true,
"batchPostingLimit": 50,
"period": "00:00:30"
}
},
"TelegramOption": {
"Api_Key": "your-telegram-bot-api-key",
"chatId": "your-chat-id"
},
"File": {
"Path": "logs"
},
"GeneralConfig": {
"EnableSelfLogging": false
}
}
}
}
}
The library uses the SerilogCondition array in the configuration to determine which log levels should be written to each sink:
Level array for a sink is empty (like "Level": []), no logs will be written to that sink regardless of their levelSerilogCondition array, it won't be usedFor example, in the configuration above:
Register the logger in your Program.cs:
using CSharpEssentials.LoggerHelper;
var builder = WebApplication.CreateBuilder(args);
// Add logger configuration
builder.Services.addloggerConfiguration(builder);
// ... other services
var app = builder.Build();
// ... configure app
// Add this middleware to automatically log all requests and responses with Information level
app.UseMiddleware<RequestResponseLoggingMiddleware>();
app.Run();Note: By adding
app.UseMiddleware<RequestResponseLoggingMiddleware>()to your Program.cs, all HTTP requests and responses in your Web API will be automatically logged with Information level.
First, implement the IRequest interface in your request model:
public class MyRequest : IRequest
{
public string IdTransaction { get; set; } = Guid.NewGuid().ToString();
public string Action { get; set; } = "YourActionName";
// Other properties
}Then use the logger in your code:
using CSharpEssentials.LoggerHelper;
using Serilog.Events;
// For synchronous logging
var request = new MyRequest();
loggerExtension<MyRequest>.TraceSync(
request,
LogEventLevel.Information,
null,
"Operation completed successfully: {OperationName}",
"CreateUser"
);
// For asynchronous logging
await Task.Run(() => loggerExtension<MyRequest>.TraceAsync(
request,
LogEventLevel.Error,
exception,
"Error during operation: {OperationName}",
"UpdateUser"
));
// For logging without a request object
loggerExtension<IRequest>.TraceSync(
null,
LogEventLevel.Warning,
null,
"System warning: {WarningMessage}",
"Low disk space"
);The TraceSync and TraceAsync methods accept the following parameters:
IRequest (contains IdTransaction and Action)The logger creates a table with the following columns:
The logger creates a table with the following columns:
Alessandro Chiodo
Current version: 1.0.1