<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex</title>
    <description>The latest articles on DEV Community by Alex (@alessandro_chiodo_d820969).</description>
    <link>https://dev.to/alessandro_chiodo_d820969</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1701067%2F229087c8-5115-4191-b9b6-1127ea43557f.png</url>
      <title>DEV Community: Alex</title>
      <link>https://dev.to/alessandro_chiodo_d820969</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alessandro_chiodo_d820969"/>
    <language>en</language>
    <item>
      <title>Thanks to your great feedback, v5.3 is here! 🚀 Now with automatic Correlation ID propagation on outgoing HTTP calls, structured metrics (StatusCode, ElapsedMs), and verified secret masking benchmarks across all sinks.</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Sun, 11 Oct 2026 09:04:17 +0000</pubDate>
      <link>https://dev.to/alessandro_chiodo_d820969/thanks-to-your-great-feedback-v53-is-here-now-with-automatic-correlation-id-propagation-on-ga2</link>
      <guid>https://dev.to/alessandro_chiodo_d820969/thanks-to-your-great-feedback-v53-is-here-now-with-automatic-correlation-id-propagation-on-ga2</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3" class="crayons-story__hidden-navigation-link"&gt;One ILogger&amp;lt;T&amp;gt;, 10 sinks, secrets masked everywhere: LoggerHelper + HttpHelper for .NET (and a playground to try them)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/alessandro_chiodo_d820969" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1701067%2F229087c8-5115-4191-b9b6-1127ea43557f.png" alt="alessandro_chiodo_d820969 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/alessandro_chiodo_d820969" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Alex
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Alex
                
                
              
              &lt;div id="story-author-preview-content-4806913" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/alessandro_chiodo_d820969" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1701067%2F229087c8-5115-4191-b9b6-1127ea43557f.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Alex&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 6&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3" id="article-link-4806913"&gt;
          One ILogger&amp;lt;T&amp;gt;, 10 sinks, secrets masked everywhere: LoggerHelper + HttpHelper for .NET (and a playground to try them)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/dotnet"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;dotnet&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/csharp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;csharp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/logging"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;logging&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              6&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>backend</category>
      <category>dotnet</category>
      <category>performance</category>
      <category>security</category>
    </item>
    <item>
      <title>One ILogger&lt;T&gt;, 10 sinks, secrets masked everywhere: LoggerHelper + HttpHelper for .NET (and a playground to try them)</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 06 Oct 2026 13:03:48 +0000</pubDate>
      <link>https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3</link>
      <guid>https://dev.to/alessandro_chiodo_d820969/one-ilogger-10-sinks-secrets-masked-everywhere-loggerhelper-httphelper-for-net-and-a-6k3</guid>
      <description>&lt;p&gt;Every .NET backend team encounters the exact same operational dilemmas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Routing headaches:&lt;/strong&gt; We want &lt;code&gt;Information&lt;/code&gt; in the Console, &lt;code&gt;Warning&lt;/code&gt; in Seq/Elasticsearch, &lt;code&gt;Error&lt;/code&gt; in SQL Server, and &lt;code&gt;Fatal&lt;/code&gt; instant alerts to Telegram or Email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration bloat:&lt;/strong&gt; Achieving this with plain Serilog requires sub-loggers, verbose C# filters, and redeploying code just to adjust log destinations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data security nightmares:&lt;/strong&gt; Passwords, JWTs, Bearer tokens, or credit cards accidentally ending up in log aggregators (violating GDPR / PCI-DSS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sink failure cascading:&lt;/strong&gt; One unreachable database sink shouldn't crash the startup of the entire web API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP resiliency &amp;amp; tracing boilerplate:&lt;/strong&gt; Standard &lt;code&gt;HttpClient&lt;/code&gt; needs Polly retries, per-call timeouts, header masking, and correlation IDs glued together over and over again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this once and for all across microservices, I maintain two high-performance, MIT-licensed NuGet packages: &lt;strong&gt;&lt;code&gt;CSharpEssentials.LoggerHelper&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;CSharpEssentials.HttpHelper&lt;/code&gt;&lt;/strong&gt; (now updated to &lt;strong&gt;v5.3.1&lt;/strong&gt;, supporting .NET 8, 9, and 10).&lt;/p&gt;




&lt;h2&gt;
  
  
  1. LoggerHelper: Native ILogger Meets Declarative Routing
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CSharpEssentials.LoggerHelper&lt;/code&gt; acts as a high-level &lt;strong&gt;orchestrator&lt;/strong&gt; on top of Serilog and registers as a standard &lt;code&gt;ILoggerProvider&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Zero Application Code Changes:&lt;/strong&gt; If your services already inject &lt;code&gt;ILogger&amp;lt;T&amp;gt;&lt;/code&gt;, you do not touch a single line of business logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Modular "Pay-Only-For-What-You-Use" Sinks
&lt;/h3&gt;

&lt;p&gt;Install the core plus &lt;strong&gt;only&lt;/strong&gt; the sink packages you actually need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Console&lt;/strong&gt; (&lt;code&gt;CSharpEssentials.LoggerHelper.Sink.Console&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;📁 &lt;strong&gt;File&lt;/strong&gt; (with tenant/property folder splitting)&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Seq&lt;/strong&gt; &amp;amp; &lt;strong&gt;Elasticsearch&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🗄️ &lt;strong&gt;SQL Server&lt;/strong&gt;, &lt;strong&gt;PostgreSQL&lt;/strong&gt;, &lt;strong&gt;MySQL / MariaDB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Telegram&lt;/strong&gt; &amp;amp; &lt;strong&gt;Email&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚙️ &lt;strong&gt;Hangfire Console&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sinks register themselves automatically via .NET &lt;code&gt;[ModuleInitializer]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Declarative Routing in 5 Lines of JSON
&lt;/h3&gt;

&lt;p&gt;No more hand-crafted sub-loggers. Just declare your routes in &lt;code&gt;appsettings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"LoggerHelper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ApplicationName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OrderService"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Sink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Console"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Levels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Warning"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Sink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Seq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nl"&gt;"Levels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Sink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MSSqlServer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Levels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fatal"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Sink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Telegram"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"Levels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Fatal"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or configure it with the type-safe Fluent API in &lt;code&gt;Program.cs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddLoggerHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithApplicationName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OrderService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Console"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Warning&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Seq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Warning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Telegram"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogEventLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnableSensitiveDataMasking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Presets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CreditCard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BearerToken"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"JwtToken"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SensitiveProperties&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ApiKey"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automatic Sensitive Data Masking
&lt;/h3&gt;

&lt;p&gt;Masking is implemented as an enricher executed &lt;strong&gt;once&lt;/strong&gt; per log event before routing. Both template properties and the rendered message string are sanitized automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Application Code:&lt;/span&gt;
&lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User {Email} logged in with token {BearerToken}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Sinks receive:&lt;/span&gt;
&lt;span class="c1"&gt;// "User alice@***.com logged in with token ***MASKED***"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. HttpHelper v5.3: Resilient HttpClient with Zero Exceptions
&lt;/h2&gt;

&lt;p&gt;Pairing logging with outgoing HTTP calls is where real-world systems shine. &lt;code&gt;CSharpEssentials.HttpHelper&lt;/code&gt; wraps &lt;code&gt;IHttpClientFactory&lt;/code&gt; with an ergonomic fluent pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Transport Exceptions:&lt;/strong&gt; Network failures, DNS drops, and timeouts are mapped to clean &lt;code&gt;408 RequestTimeout&lt;/code&gt;, &lt;code&gt;502 BadGateway&lt;/code&gt;, or &lt;code&gt;500 InternalServerError&lt;/code&gt; responses instead of unhandled crashes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exponential Backoff &amp;amp; Rate Limiting:&lt;/strong&gt; Built-in sliding-window rate limiters and Polly retry policies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Mocking (&lt;code&gt;IHttpMockScenario&lt;/code&gt;):&lt;/strong&gt; Unit and integration test HTTP clients without launching WireMock or local servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🆕 What's New in v5.3: Hot-Reload Logging &amp;amp; Correlation ID
&lt;/h3&gt;

&lt;p&gt;In v5.3, outgoing HTTP calls integrate natively with the LoggerHelper pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"HttpHelperLogging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"LogRequests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CorrelationIdHeader"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-Correlation-ID"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Hot-Reload:&lt;/strong&gt; Turn request logging on/off per client name at runtime via &lt;code&gt;IOptionsMonitor&lt;/code&gt; without restarting the process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Correlation:&lt;/strong&gt; Propagates an end-to-end &lt;code&gt;CorrelationId&lt;/code&gt; across retries (and downstream microservices).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanitized Logs:&lt;/strong&gt; Automatically masks headers like &lt;code&gt;Authorization: Bearer ***MASKED***&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOrGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"payment-gateway"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRetryCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retryCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backoffFactor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SendAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.gateway.com/charge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JsonContentBuilder&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Experience It Live: The Interactive Playground
&lt;/h2&gt;

&lt;p&gt;Reading about architecture is good, but testing it live is better. The repository includes an interactive &lt;strong&gt;Playground&lt;/strong&gt; (&lt;code&gt;/playground.html&lt;/code&gt; in the Demo project) that builds pipelines on the fly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faow6tcqfj0upc7xlnz6c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faow6tcqfj0upc7xlnz6c.gif" alt=" " width="560" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Watch the playground live recording: testing multi-sink routing, instant secret masking, and flaky HTTP retry flows)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What you can test in the Playground:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Live Multi-Sink Dispatch:&lt;/strong&gt; Check Console, File, Seq, Postgres, SQL Server, and Telegram checkboxes, pick individual minimum levels, and see which sink accepted or filtered the event.

&lt;ul&gt;
&lt;li&gt;💡 &lt;strong&gt;Zero Local Setup needed:&lt;/strong&gt; &lt;code&gt;Console&lt;/code&gt; and &lt;code&gt;File&lt;/code&gt; work immediately with no dependencies.&lt;/li&gt;
&lt;li&gt;🐳 &lt;strong&gt;No need to install databases locally:&lt;/strong&gt; To test the external sinks (Seq, Elasticsearch, SQL Server, PostgreSQL), you don't need to install anything on your machine — the repository includes a ready-made Docker Compose setup that spins up all of them in isolated containers with one command!&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Telegram:&lt;/strong&gt; Just set your bot token via &lt;code&gt;dotnet user-secrets&lt;/code&gt; to receive instant push alerts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant Secret Masking:&lt;/strong&gt; Type a credit card, password, or custom regex (&lt;code&gt;ORD-\d+&lt;/code&gt;) and inspect the sanitized event payload in real time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;End-to-End E-Commerce Scenario:&lt;/strong&gt; Run the multi-step &lt;code&gt;order&lt;/code&gt; scenario (Login ➡️ Order ➡️ Flaky Payment: Timeout ➡️ 503 ➡️ 200 Success). Watch every retry attempt get logged with the same &lt;code&gt;CorrelationId&lt;/code&gt;!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generated C# Fluent Code Preview:&lt;/strong&gt; The right panel automatically prints the exact C# code required to reproduce what you just clicked.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. Run the Playground in 3 Commands
&lt;/h2&gt;

&lt;p&gt;You can run the entire environment (including Seq, Elasticsearch, and databases in Docker) right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Clone the repo&lt;/span&gt;
git clone https://github.com/alexbypa/CSharp.Essentials.git
&lt;span class="nb"&gt;cd &lt;/span&gt;CSharp.Essentials/src/CSharpEssentials.LoggerHelper.Demo/docker

&lt;span class="c"&gt;# 2. Start the sinks in Docker&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# 3. Launch the Demo app&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
dotnet run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:5123/playground.html&lt;/code&gt; in your browser!&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Summary &amp;amp; Benchmarks
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Serilog Alone&lt;/th&gt;
&lt;th&gt;Refit / Polly Raw&lt;/th&gt;
&lt;th&gt;LoggerHelper + HttpHelper&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native &lt;code&gt;ILogger&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;✅ (Zero code refactor)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-sink JSON routing&lt;/td&gt;
&lt;td&gt;❌ (requires C# code)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;✅ (5 lines of JSON)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sensitive Data Masking&lt;/td&gt;
&lt;td&gt;⚠️ (manual enrichers)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (Pre-configured presets)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sink Failure Isolation&lt;/td&gt;
&lt;td&gt;❌ (can crash host)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;✅ (&lt;code&gt;ILogErrorStore&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP No-Exception Contract&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (&lt;code&gt;408&lt;/code&gt;/&lt;code&gt;502&lt;/code&gt;/&lt;code&gt;500&lt;/code&gt; status codes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outgoing Request Correlation&lt;/td&gt;
&lt;td&gt;⚠️ (manual setup)&lt;/td&gt;
&lt;td&gt;⚠️ (manual setup)&lt;/td&gt;
&lt;td&gt;✅ (Automatic propagation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interactive Playground&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ (&lt;code&gt;playground.html&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Honest Performance Overhead
&lt;/h3&gt;

&lt;p&gt;LoggerHelper is an &lt;strong&gt;orchestrator&lt;/strong&gt;, not a replacement. In our BenchmarkDotNet runs (.NET 9), baseline framework overhead is ~590 ns vs ~180 ns for Serilog directly. For real-world web APIs handling business workloads, this difference is negligible, but you gain maintainability, security, and developer ergonomics.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started on NuGet &amp;amp; GitHub
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;Core Logger:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/CSharpEssentials.LoggerHelper" rel="noopener noreferrer"&gt;&lt;code&gt;CSharpEssentials.LoggerHelper&lt;/code&gt; on NuGet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Resilient HTTP:&lt;/strong&gt; &lt;a href="https://www.nuget.org/packages/CSharpEssentials.HttpHelper" rel="noopener noreferrer"&gt;&lt;code&gt;CSharpEssentials.HttpHelper&lt;/code&gt; on NuGet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/alexbypa/CSharp.Essentials" rel="noopener noreferrer"&gt;alexbypa/CSharp.Essentials&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find this useful for your .NET projects, &lt;strong&gt;leave a star on GitHub&lt;/strong&gt; and let me know your thoughts in the comments!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>logging</category>
      <category>docker</category>
    </item>
    <item>
      <title>LoggerHelper</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Sat, 10 May 2025 19:48:10 +0000</pubDate>
      <link>https://dev.to/alessandro_chiodo_d820969/loggerhelper-77j</link>
      <guid>https://dev.to/alessandro_chiodo_d820969/loggerhelper-77j</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Introducing CSharpEssentials.LoggerHelper: A Modular and Powerful Logger for .NET Developers
&lt;/h1&gt;

&lt;p&gt;In the world of software development, &lt;strong&gt;structured and reliable logging&lt;/strong&gt; is crucial for debugging, monitoring, and maintaining applications.&lt;br&gt;&lt;br&gt;
Today, I'm excited to introduce &lt;strong&gt;CSharpEssentials.LoggerHelper&lt;/strong&gt;, a lightweight, modular library built on top of &lt;strong&gt;Serilog&lt;/strong&gt;, designed to make logging in .NET applications &lt;strong&gt;easier&lt;/strong&gt;, &lt;strong&gt;cleaner&lt;/strong&gt;, and &lt;strong&gt;more powerful&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  📦 What is LoggerHelper?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LoggerHelper&lt;/strong&gt; is a wrapper around Serilog that allows you to configure &lt;strong&gt;multi-sink&lt;/strong&gt; logging quickly and flexibly, without having to write complex boilerplate code.&lt;/p&gt;

&lt;p&gt;It helps you set up a professional logging system with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Console&lt;/li&gt;
&lt;li&gt;File&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Telegram&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;… and it's &lt;strong&gt;easy to extend&lt;/strong&gt; with your own custom sinks!&lt;/p&gt;


&lt;h2&gt;
  
  
  🌟 Key Features
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Modular Configuration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With the &lt;code&gt;LoggerBuilder&lt;/code&gt;, you can configure exactly the sinks you need — no unnecessary setup.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Standardized Log Format&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every log automatically includes essential fields like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Action&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IdTransaction&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ApplicationName&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MachineName&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;.NET 8 Compatible&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Built for modern applications, ready for production.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Lightweight and Performant&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No heavy dependencies, only the essentials.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Telegram Notifications&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Receive critical logs directly on Telegram in real-time!&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ How to Install
&lt;/h2&gt;

&lt;p&gt;You can install LoggerHelper directly from NuGet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package CSharpEssentials.LoggerHelper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or visit the &lt;a href="https://www.nuget.org/packages/CSharpEssentials.LoggerHelper" rel="noopener noreferrer"&gt;NuGet page&lt;/a&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚀 Quick Start Example
&lt;/h1&gt;

&lt;p&gt;Here’s how simple it is to set up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define your logging configuration in &lt;code&gt;appsettings.json&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"LoggerHelper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ApplicationName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyApp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sinks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Console"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"File"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/log-.txt"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"PostgreSQL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ConnectionString"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-connection-string"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Telegram"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"BotToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-bot-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ChatId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-chat-id"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Initialize the logger in your &lt;code&gt;Program.cs&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoggerBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BuildFromConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the logger will automatically configure all the sinks based on your &lt;code&gt;appsettings.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Application started successfully!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can enable or disable sinks dynamically just by changing the settings — no need to modify the code!&lt;/p&gt;




&lt;h1&gt;
  
  
  📌 Important
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;LoggerHelper&lt;/strong&gt; is designed to be &lt;strong&gt;configuration-driven&lt;/strong&gt;, keeping your application code clean and letting you control the behavior through simple settings.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🧩 Extending LoggerHelper
&lt;/h2&gt;

&lt;p&gt;LoggerHelper is designed to be easily extendable.&lt;/p&gt;

&lt;p&gt;If you want to add a new sink or customize your logs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can create your own extension methods.&lt;/li&gt;
&lt;li&gt;You can inject contextual properties dynamically.&lt;/li&gt;
&lt;li&gt;You can customize the enrichment to match your domain requirements.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✨ Why Use LoggerHelper Instead of Raw Serilog?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Less Setup&lt;/strong&gt;: No more cluttered Program.cs with tons of configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Always log the most critical context fields automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Add or remove sinks in a modular way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Productivity&lt;/strong&gt;: Focus on your business logic — not on writing logger configuration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Documentation &amp;amp; GitHub
&lt;/h2&gt;

&lt;p&gt;You can find full examples, usage tips, and source code on GitHub:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/alexbypa/CSharp.Essentials" rel="noopener noreferrer"&gt;https://github.com/alexbypa/CSharp.Essentials&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to open issues, suggest improvements, or contribute!&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Conclusion
&lt;/h2&gt;

&lt;p&gt;If you're looking for a clean, modular, and extensible logging solution for your .NET projects,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;CSharpEssentials.LoggerHelper&lt;/strong&gt; is made for you.&lt;/p&gt;

&lt;p&gt;It’s simple enough for small applications, yet powerful enough for enterprise-grade systems.&lt;/p&gt;

&lt;p&gt;If you find it useful, consider leaving a ⭐ on GitHub — it really helps the project grow!&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;Have questions or suggestions?&lt;/strong&gt; Feel free to leave a comment below! I'd love to hear your feedback.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>logging</category>
      <category>multisinks</category>
    </item>
  </channel>
</rss>
