CSharpEssentials.LoggerHelper 2.0.7

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

Frameworks CodeQL NuGet Downloads Last Commit

πŸ“¦ CSharpEssentials.LoggerHelper

πŸ“œ Version History

  • 1.1.2 – Added Middleware
  • 1.1.4 – Removed TraceAsync on finally block of RequestResponseLoggingMiddleware
  • 1.1.6 – Fixed issues detected by CodeQL
  • 1.2.1 – Optimized with test Web API
  • 1.2.2 – Optimized Properties handling and Email sink
  • 1.3.1 – Added compatibility with .NET 6.0
  • 2.0.0 – Fixed Email configuration and sink behavior
  • 2.0.2 – Optimized HTML template for middleware
  • 2.0.4 – Rollback: removed .NET 7.0 support
  • 2.0.5 – Fixed IRequest interface
  • 2.0.6 – Added external email template support

<a id='table-of-contents'></a>

πŸ“‘ Table of Contents

πŸ“˜ Introduction<a id='introduction'></a> πŸ”

LoggerHelper is a flexible and modular structured logging library for .NET (6.0/8.0) applications based on Serilog. It enables structured, multi-sink logging through a plug-and-play approach.

πŸ”‘ Key Benefits:

  • βœ… Structured logs: Action, IdTransaction, ApplicationName, MachineName
  • βœ… Multi-sink: Console, File, Email (HTML), PostgreSQL, ElasticSearch, Telegram
  • βœ… Placeholder validation: avoids runtime {} mismatch errors
  • βœ… One config file: appsettings.LoggerHelper.json
  • βœ… Modular integration via LoggerBuilder

⚠️ Important for developers: In development mode, LoggerHelper automatically uses appsettings.LoggerHelper.debug.json. This allows safe testing without affecting production settings.

#if DEBUG
    .AddJsonFile("appsettings.LoggerHelper.debug.json")
#else
    .AddJsonFile("appsettings.LoggerHelper.json")
#endif

πŸš€ Installation <a id='installation'></a> πŸ”

dotnet add package CSharpEssentials.LoggerHelper

βš™οΈ Configuration

The full configuration JSON can be found in the original README. Important:

  • Define the SerilogCondition for each sink with the desired Level
  • If Level is empty, the sink is ignored

βš™οΈ General Setup

To activate LoggerHelper and enable request/response logging, configure your application in Program.cs as follows:

#if NET6_0
    builder.AddLoggerConfiguration();
#else
    builder.Services.AddLoggerConfiguration(builder);
#endif

Enable HTTP middleware logging:

app.UseMiddleware<RequestResponseLoggingMiddleware>();

Example appsettings.LoggerHelper.json configuration (⚠️ or appsettings.LoggerHelper.debug.json during development):

{
  "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": ["Fatal"]},
        {"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,          
          "addAutoIncrementColumn": true,
          "ColumnsPostGreSQL": [
              {"Name": "Message","Writer": "Rendered","Type": "text"},
              {"Name": "MessageTemplate","Writer": "Template","Type": "text"},
              {"Name": "Level","Writer": "Level","Type": "varchar"},
              {"Name": "TimeStamp","Writer": "timestamp","Type": "timestamp"},
              {"Name": "Exception","Writer": "Exception","Type": "text"},
              {"Name": "Properties","Writer": "Properties","Type": "jsonb"},
              {"Name": "LogEvent","Writer": "Serialized","Type": "jsonb"},
              {"Name": "IdTransaction","Writer": "Single","Property": "IdTransaction","Type": "varchar"},
              {"Name": "MachineName","Writer": "Single","Property": "MachineName","Type": "varchar"},
              {"Name": "Action","Writer": "Single","Property": "Action","Type": "varchar"},
              {"Name": "ApplicationName","Writer": "Single","Property": "ApplicationName","Type": "varchar"}
          ]

        },
        "ElasticSearch": {
          "nodeUris": "http://10.0.1.100:9200",
          "indexFormat": "<YOUR INDEX FORMAT>"
        },
        "Email": {
          "From": "<Email Alert>",
          "Port": 587,
          "Host": "<Host EMail>",
          "To": [ "recipient#1", "recipient#2" ],
          "username": "<UserName SMTP>",
          "password": "<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
        }
      }
    }
  }
}

🐘 PostgreSQL Sink<a id='postgresql-sink'></a> πŸ”

LoggerHelper supports logging to PostgreSQL with optional custom schema definition.

  • If ColumnsPostGreSQL is not set, the following default columns will be created and used:

    • message, message_template, level, raise_date, exception, properties, props_test, machine_name
  • If ColumnsPostGreSQL is defined, LoggerHelper will use the exact fields provided.

  • Setting addAutoIncrementColumn: true will add an id SERIAL PRIMARY KEY automatically.

Example configuration:

"PostgreSQL": {
  "connectionString": "...",
  "tableName": "Logs",
  "schemaName": "public",
  "addAutoIncrementColumn": true,
  "ColumnsPostGreSQL": [
    { "Name": "Message", "Writer": "Rendered", "Type": "text" },
    { "Name": "Level", "Writer": "Level", "Type": "varchar" }
  ]
}

πŸ§ͺ PostgreSQL Table Structure

If custom ColumnsPostGreSQL is defined, logs will include all specified fields.

🧩 Tip: PostgreSQL sink is ideal for deep analytics and long-term log storage. ⚠️ Note: When using ColumnsPostGreSQL, always enable SelfLog during development to detect unsupported or misconfigured column definitions. Invalid types or property names will be silently ignored unless explicitly logged via Serilog’s internal diagnostics.

🐘 Telegram Sink<a id='telegram-sink'></a> πŸ”

LoggerHelper supports Telegram notifications to alert on critical events.

⚠️ Recommended Levels: Use only Error or Fatal to avoid exceeding Telegram rate limits.

πŸ›  Example Configuration

"TelegramOption": {
  "chatId": "<YOUR_CHAT_ID>",
  "Api_Key": "<YOUR_BOT_API_KEY>"
}

To configure a Telegram Bot:

  1. Open Telegram and search for @BotFather
  2. Create a new bot and copy the API token
  3. Use https://api.telegram.org/bot<YourBotToken>/getUpdates to get your chat ID after sending a message to the bot

πŸ“Έ Example of a formatted Telegram message: Telegram Sample

πŸ’‘ Usage Examples

_logger.TraceSync(
    new Request {
        IdTransaction = Guid.NewGuid().ToString(),
        Action = "SampleAction",
        ApplicationName = "MyApp"
    },
    LogEventLevel.Information,
    null,
    "Sample log message: {Parameter}",
    123
);

Or async:

await _logger.TraceAsync(
    request,
    LogEventLevel.Error,
    ex,
    "Something failed: {ErrorMessage}",
    ex.Message
);

πŸ“¨ HTML Email Sink<a id='html-email-sink'></a> πŸ”


⚠️ Version 2.0.0 - Breaking Change

Starting from version 2.0.0, the Email configuration section has been renamed.

If you are upgrading from 1.x.x, you MUST update your appsettings.LoggerHelper.json.

Old (before 2.0.0):

"Email": {
  "From": "...",
  "Host": "...",
  "Port": 587,
  "To": ["..."],
  "CredentialHost": "...",
  "CredentialPassword": "..."
}

New (since 2.0.0):

"Email": {
  "From": "...",
  "Host": "...",
  "Port": 587,
  "To": "...",
  "username": "...",
  "password": "...",
  "EnableSsl": true
}

🚨 Why Email Handling Changed

Starting from version 2.0.0, LoggerHelper no longer uses the standard Serilog.Sinks.Email for sending emails.

Reason: The official Serilog Email Sink does not support custom body formatting (HTML templates, structured logs, color coding, etc). It only supports plain text messages generated via RenderMessage(), without the ability to control the message content.

πŸ”Ž See discussion: GitHub Issue - serilog/serilog-sinks-email

What changed:

  • LoggerHelper now uses a custom internal SMTP sink: LoggerHelperEmailSink.
  • This allows sending fully customized HTML-formatted emails.
  • Supports dynamic coloring based on log level (Information, Warning, Error).
  • Supports secure SMTP with SSL/TLS.

βœ… No third-party dependencies added. βœ… Full control over email appearance and content.

Since v2.0.0, LoggerHelper no longer uses Serilog.Sinks.Email. It ships with LoggerHelperEmailSink, allowing:

  • βœ… Full HTML customization via external template
  • βœ… Dynamic styling based on log level
  • βœ… Secure SMTP (SSL/TLS)

Example HTML placeholders:

{{Timestamp}}, {{Level}}, {{Message}}, {{Action}}, {{IdTransaction}}, {{MachineName}}, {{ApplicationName}}, {{LevelClass}}

πŸ–ŒοΈ Email Template Customization (optional)

LoggerHelper allows you to customize the HTML structure and appearance of the email body. You can provide an external .html file with placeholders like:

{{Timestamp}}, {{Level}}, {{Message}}, {{Action}}, {{IdTransaction}}, {{MachineName}}, {{ApplicationName}}, {{LevelClass}}

Then, in the appsettings.LoggerHelper.json configuration file, set:

"LoggerHelper": {
  "SerilogOption": {
    "Email": {
      ...
      "TemplatePath": "Templates/email-template-default.html"
    }
  }
}

If the file is missing or invalid, LoggerHelper will fall back to the internal default template, ensuring backward compatibility.

πŸ’Ύ MS SQL Sink<a id='ms-sql-sink'></a> πŸ”

This sink writes logs to a Microsoft SQL Server table and supports additional context properties out of the box.

Configuration Example

"MSSqlServer": {
  "connectionString": "<YOUR CONNECTIONSTRING>",
  "sinkOptionsSection": {
    "tableName": "logs",
    "schemaName": "dbo",
    "autoCreateSqlTable": true,
    "batchPostingLimit": 100,
    "period": "0.00:00:10"
  },
  "columnOptionsSection": {
    "addStandardColumns": [
      "LogEvent"
    ],
    "removeStandardColumns": [
      "Properties"
    ]
  }
}

Explanation

  • connectionString: Full connection string to the SQL Server instance.
  • tableName: Name of the table that will receive log entries.
  • schemaName: Schema to use for the log table (default is dbo).
  • autoCreateSqlTable: If true, the log table will be created automatically if it does not exist.
  • batchPostingLimit: Number of log events to post in each batch.
  • period: Interval for batching log posts.
  • addStandardColumns: Additional default Serilog columns to include (e.g., LogEvent).
  • removeStandardColumns: Columns to exclude from the standard set.

Additional Columns

This sink automatically adds the following custom fields to each log:

  • IdTransaction: a unique identifier for tracking a transaction.
  • MachineName: name of the server or machine.
  • Action: custom action tag if set via Request.Action.
  • ApplicationName: name of the application logging the message.

πŸ” ElasticSearch Sink<a id='elasticsearch'></a> πŸ”

ElasticSearch is ideal for indexing and searching logs at scale. When integrated with Kibana, it enables advanced analytics and visualization of log data.

Benefits

  • πŸ”Ž Fast full-text search and filtering
  • πŸ“Š Seamless integration with Kibana for dashboards
  • πŸ“ Efficient storage and querying for large volumes of structured logs

Example Configuration

"ElasticSearch": {
  "nodeUris": "http://<YOUR_IP>:9200",
  "indexFormat": "<YOUR_INDEX>"
}
  • nodeUris: The ElasticSearch node endpoint.
  • indexFormat: The format or name of the index that will store log entries.

πŸ§ͺ Demo API <a id='demo-api'></a> πŸ”

Try live with full logging and structured output:

πŸ“ [Demo Project]

βœ… Now available for both .NET 6.0 and .NET 8.0:

  • /Test6.0 β†’ Compatible with legacy environments
  • /Test8.0 β†’ Optimized for latest runtime features

🧰 Troubleshooting

Enable Serilog internal diagnostics:

SelfLog.Enable(msg => File.AppendAllText("serilog-selflog.txt", msg));

πŸ‘€ Author

Alessandro Chiodo πŸ“¦ NuGet Package πŸ”— GitHub

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 (8)

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

Package Downloads
CSharpEssentials.LoggerHelper.Sink.Postgresql

Package Description

CSharpEssentials.LoggerHelper.Sink.File

Sink File for package LoggerHelper

CSharpEssentials.LoggerHelper.Sink.Elasticsearch

Sink ElasticSearch for CSharpEssentials.LoggerHelper

CSharpEssentials.LoggerHelper.Sink.MSSqlServer

Package Description

CSharpEssentials.LoggerHelper.Sink.Console

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.1.5 137 5 days ago
3.1.4 327 8 days ago
3.1.3 273 9 days ago
3.1.2 196 11 days ago
3.1.1 393 11 days ago
3.1.0 176 11 days ago
3.0.6 137 15 days ago
3.0.5 130 15 days ago
3.0.4 127 17 days ago
3.0.3 129 17 days ago
3.0.2 335 19 days ago
3.0.1 133 21 days ago
3.0.0 143 21 days ago
2.0.9 62 a month ago
2.0.8 97 a month ago
2.0.7 97 a month ago
2.0.6 129 a month ago
2.0.5 213 a month ago
2.0.4 239 a month ago
2.0.1 121 a month ago
2.0.0 122 a month ago
1.3.1 124 a month ago
1.2.3 71 a month ago
1.2.2 59 a month ago
1.2.1 105 a month ago
1.1.6 134 a month ago
1.1.5 153 a month ago
1.1.4 139 2 months ago
1.1.3 142 2 months ago
1.1.2 141 2 months ago
1.1.1 133 2 months ago
1.0.1 109 4 months ago
1.0.0 94 4 months ago