CSharpEssentials.LoggerHelper 1.2.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package CSharpEssentials.LoggerHelper --version 1.2.2
                    
NuGet\Install-Package CSharpEssentials.LoggerHelper -Version 1.2.2
                    
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="CSharpEssentials.LoggerHelper" Version="1.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CSharpEssentials.LoggerHelper" Version="1.2.2" />
                    
Directory.Packages.props
<PackageReference Include="CSharpEssentials.LoggerHelper" />
                    
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 CSharpEssentials.LoggerHelper --version 1.2.2
                    
#r "nuget: CSharpEssentials.LoggerHelper, 1.2.2"
                    
#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.
#addin nuget:?package=CSharpEssentials.LoggerHelper&version=1.2.2
                    
Install CSharpEssentials.LoggerHelper as a Cake Addin
#tool nuget:?package=CSharpEssentials.LoggerHelper&version=1.2.2
                    
Install CSharpEssentials.LoggerHelper as a Cake Tool

CodeQL NuGet Downloads Last Commit

๐Ÿ“ฆ CSharpEssentials.LoggerHelper

Introduction

LoggerHelper is a library designed to simplify, standardize, and enhance logging management in .NET applications, using Serilog as the core engine.

It allows you to:

  • Send structured logs with guaranteed fields like Action, IdTransaction, ApplicationName, MachineName
  • Dynamically enable multi-sink support (Console, File, HTML Email, PostgreSQL, ElasticSearch)
  • Automatically validate message {} placeholders
  • Centralize configuration through LoggerBuilder, just by editing the appsettings.json file

In common usage scenarios, it is advisable to avoid logging Information level events to sinks like Telegram, MSSQL, or PostgreSQL. This practice prevents issues such as HTTP 429 (rate limits) on Telegram and reduces risks of deadlocks or insufficient storage in database systems.


๐Ÿ“š Table of Contents


โœจ Features

  • โœ… Multi-sink logging support:

    • Console
    • File
    • SQL Server
    • PostgreSQL
    • Elasticsearch
    • Email
    • Telegram
  • โœ… Structured logs with custom properties

  • โœ… Sync and async logging

  • โœ… Request/response middleware logger

  • โœ… Transaction ID, action, machine name

  • โœ… Custom levels per sink

  • โœ… JSON configuration via appsettings.LoggerHelper.json


๐Ÿš€ Installation

dotnet add package CSharpEssentials.LoggerHelper

โš™๏ธ Configuration

Create a file named appsettings.LoggerHelper.json in your project root:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug",
        "System": "Debug"
      }
    },
    "SerilogConfiguration": {
      "ApplicationName": "TestApp",
      "SerilogCondition": [
        {"Sink": "ElasticSearch","Level": []},
        {"Sink": "MSSqlServer","Level": []},
        {"Sink": "Email","Level": []},
        {"Sink": "PostgreSQL","Level": ["Information","Warning","Error","Fatal"]},
        {"Sink": "Telegram","Level": []},
        {"Sink": "Console","Level": [ "Information" ]},
        {"Sink": "File","Level": ["Information","Warning","Error","Fatal"]}
      ],
      "SerilogOption": {
        "File": {
          "Path": "D:\\Logs\\ServerDemo",
          "RollingInterval": "Day",
          "RetainedFileCountLimit": 7,
          "Shared": true
        },
        "TelegramOption": {
          "chatId": "xxxxx",
          "Api_Key": "sssss:ttttttttt"
        },
        "PostgreSQL": {
          "connectionString": "<YOUR CONNECTIONSTRING>",
          "tableName": "public",
          "schemaName": "dbo",
          "needAutoCreateTable": true
        },
        "ElasticSearch": {
          "nodeUris": "http://10.0.1.119:9200",
          "indexFormat": "PixeloApp"
        },
        "Email": {
          "From": "<Email Alert>",
          "Port": 587,
          "Host": "<Host EMail>",
          "To": [ "recipient#1", "recipient#2" ],
          "CredentialHost": "<UserName SMTP>",
          "CredentialPassword": "<Password SMTP>"
        },
        "MSSqlServer": {
          "connectionString": "<YOUR CONNECTIONSTRING>",
          "sinkOptionsSection": {
            "tableName": "logs",
            "schemaName": "dbo",
            "autoCreateSqlTable": true,
            "batchPostingLimit": 100,
            "period": "0.00:00:10"
          },
          "columnOptionsSection": {
            "addStandardColumns": [
              "LogEvent"
            ],
            "removeStandardColumns": [
              "Properties"
            ]
          }
        },
        "GeneralConfig": {
          "EnableSelfLogging": false
        }
      }
    }
  }
}

โš ๏ธ Important: The logger will only write to a sink if the Level array in SerilogCondition contains at least one valid log level (e.g., "Error", "Warning"). If the Level array is empty (e.g., "Level": []), that sink will be ignored, and WriteTo** will not be applied**, even if the sink configuration exists.

๐Ÿงฉ PostgreSQL is preconfigured with a default column mapping for logs. The following columns are used automatically: message, message_template, level, raise_date, exception, properties, props_test, machine_name. No custom mapping is required in the JSON.


๐Ÿ“Œ Log Levels

๐Ÿ–ผ๏ธ Example of a Telegram-formatted log message: Telegram Sample

๐Ÿ’ฌ Telegram Notice: When using the Telegram sink, log messages are formatted for human readability, and may include emojis or markdown. For this reason, it's strongly recommended to set the Level to only Error or Fatal to avoid exceeding Telegram's rate limits and to prevent excessive message noise.

๐Ÿ›  Tip: Before publishing to production, test each sink you plan to use. You can enable Serilog self-logging to capture internal errors using:

Serilog.Debugging.SelfLog.Enable(msg =>
    File.AppendAllText(Path.Combine(logPath, "serilog-selflog.txt"), msg));

Replace logPath with your local or shared log directory. This helps identify misconfigurations or sink loading issues early.

Each sink only receives log levels specified in the SerilogCondition array. If a sink's Level array is empty, that sink will be ignored entirely, and no log will be written to it, even if it's configured elsewhere:

Sink Levels
Console Information, Warning, Error, Fatal
File Error, Fatal
PostgreSQL Error, Fatal
MSSqlServer Error, Fatal
Telegram Fatal
Elasticsearch (disabled)

๐Ÿงช ASP.NET Core Setup

Request/Response Logging Middleware

The LoggerHelper package includes a built-in middleware that logs every incoming HTTP request and outgoing response automatically. It captures:

  • HTTP method, path, status code
  • Request body (if available)
  • Response body (if possible)
  • Duration in milliseconds

To enable it, just call:

app.UseMiddleware<RequestResponseLoggingMiddleware>();

๐Ÿ“Œ This middleware uses LogEventLevel.Information by default and is automatically compatible with sinks that accept that level.

Register the logger in Program.cs:

using CSharpEssentials.LoggerHelper;

var builder = WebApplication.CreateBuilder(args);

// Add LoggerHelper configuration
builder.Services.addloggerConfiguration(builder);
builder.Services.AddControllers();

var app = builder.Build();

// Logs every HTTP request and response
app.UseMiddleware<RequestResponseLoggingMiddleware>();

app.MapControllers();
app.Run();

๐Ÿง‘โ€๐Ÿ’ป Usage Examples

๐Ÿ”น With request object

loggerExtension<MyRequest>.TraceSync(
    request,
    LogEventLevel.Information,
    null,
    "Operation successful: {OperationName}",
    "CreateUser"
);

๐Ÿ”น Async logging

await loggerExtension<MyRequest>.TraceAsync(
    request,
    LogEventLevel.Error,
    exception,
    "Error during operation: {OperationName}",
    "UpdateUser"
);

๐Ÿ”น Without request object

loggerExtension<IRequest>.TraceSync(
    null,
    LogEventLevel.Warning,
    null,
    "System warning: {WarningMessage}",
    "Low disk space"
);

Database Schema

PostgreSQL

Column Description
ApplicationName Application name
message Message content
message_template Message template
level Log level
raise_date Log timestamp
exception Exception details
properties Serialized properties
props_test Additional serialized data
MachineName Machine name
Action Action name
IdTransaction Unique transaction ID

SQL Server

Column Type Description
Message nvarchar Message content
MessageTemplate nvarchar Message template
Level nvarchar Log level
TimeStamp datetime Log timestamp
Exception nvarchar Exception details
Properties nvarchar Serialized properties
LogEvent nvarchar Serialized log event
IdTransaction varchar Unique transaction ID
MachineName varchar Machine name
Action varchar Action name

Swagger Example

Field Description
action Action name
message Text to log
applicationName Application name
level Log level (Information, Warning, Error, etc.)

HTML Email Screenshot

Field Value
Timestamp 2025-05-10 17:45:00
Level Error
IdTransaction 7e7b9f65-ed13-439a-852b-18d9d28dd6ec
MachineName PIXELO30
Action GetUserDetails
ApplicationName LoggerHelperDemo
Message Error occurred during request

Demo API

Try it live with a demo Web API to validate each log level dynamically:

Method Endpoint Query Parameters Description
GET /loggerHelper action, message, level Sends a structured log with the specified level

๐Ÿ”— GitHub Repository (Demo)


๐Ÿงช Troubleshooting

File access denied?

  • โŒ If you get System.IO.IOException like: "file is being used by another process", make sure:

    • No other process (e.g. text editor, logging library) is locking the file.
    • The file is not open in append-only exclusive mode.
  • โœ… For self-log output (serilog-selflog.txt), ensure that:

    • The target folder exists.
    • The executing process has write permission to it.
    • Use FileShare.ReadWrite if needed.

Sink not writing logs?

  • โœ… Make sure the Level array in SerilogCondition is not empty.
  • โœ… Check serilog-selflog.txt if enabled โ€” it often reveals silent misconfigurations.

๐Ÿ™Œ Contributing

Contributions, ideas and issues are welcome! Feel free to open a pull request or discussion on GitHub.


๐Ÿ“„ License

This project is licensed under the MIT License.


๐Ÿ‘ค Author

Alessandro Chiodo ๐Ÿ“ง GitHub ยท NuGet ยท LinkedIn ๐Ÿ“ฆ NuGet Package

Product 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 was computed.  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 (5)

Showing the top 5 NuGet packages that depend on CSharpEssentials.LoggerHelper:

Package Downloads
CSharpEssentials.LoggerHelper.Sink.File

Sink File for package LoggerHelper

CSharpEssentials.LoggerHelper.Sink.Postgresql

Package Description

CSharpEssentials.LoggerHelper.Sink.MSSqlServer

Package Description

CSharpEssentials.LoggerHelper.Sink.Elasticsearch

Sink ElasticSearch for CSharpEssentials.LoggerHelper

CSharpEssentials.LoggerHelper.Sink.Console

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.6 90 2 days ago
3.0.5 83 2 days ago
3.0.4 116 4 days ago
3.0.3 118 4 days ago
3.0.2 234 6 days ago
3.0.1 130 8 days ago
3.0.0 140 8 days ago
2.0.9 59 14 days ago
2.0.8 94 15 days ago
2.0.7 94 15 days ago
2.0.6 128 19 days ago
2.0.5 211 23 days ago
2.0.4 237 25 days ago
2.0.1 119 a month ago
2.0.0 120 a month ago
1.3.1 122 a month ago
1.2.3 69 a month ago
1.2.2 57 a month ago
1.2.1 102 a month ago
1.1.6 132 a month ago
1.1.5 151 a month ago
1.1.4 135 a month ago
1.1.3 140 a month ago
1.1.2 139 a month ago
1.1.1 131 a month ago
1.0.1 99 4 months ago
1.0.0 94 4 months ago