স্বাগতম! আজকে আমরা Serilog-এর অত্যন্ত চমৎকার এবং পাওয়ারফুল একটি ফিচার শিখতে যাচ্ছি—Serilog Enrichers

আপনার Outline অনুযায়ী, আমরা এখন Section 20: Logging-এর ত্রয়োদশ লেকচার “278. Serilog Enrichers”-এ আছি। আগের লেকচারগুলোতে আমরা দেখেছি যে, Serilog লগ মেসেজের সাথে RequestId, ConnectionId ইত্যাদি ডিটেইলস সেভ করে (যাকে Log Context বলা হয়)। কিন্তু আপনি চাইলে আপনার নিজের মতো করে কাস্টম ডেটা (যেমন: অ্যাপ্লিকেশন নাম, সার্ভার নাম, বা ইউজারের তথ্য) প্রতিটি লগের সাথে যুক্ত করে দিতে পারেন। এই কাজটাই করে Enrichers।

চলুন শুরু করা যাক!

📝 Short Summary for Quick Revision

  • What are Enrichers: Enrichers হলো এমন কিছু অ্যাড-অন যা আপনার মূল লগ মেসেজের সাথে কিছু অতিরিক্ত (Additional) ডিটেইলস বা প্রোপার্টি স্বয়ংক্রিয়ভাবে যুক্ত করে দেয়।
  • Types of Enrichment:
  1. Predefined Enrichers: যেমন- সার্ভারের নাম (Machine Name), থ্রেড আইডি (ThreadId)।
  2. Custom Properties: appsettings.json-এর মাধ্যমে নিজের তৈরি করা যেকোনো Key-Value ডেটা (যেমন: ApplicationName).
  • Configuration: appsettings.json-এ "Enrich" অ্যারেতে "FromLogContext" দিতে হয় এবং "Properties" সেকশনে কাস্টম ডেটাগুলো ডিফাইন করতে হয়।
  • Use Case in Seq: যখন আপনি Seq ড্যাশবোর্ডে লগ ফিল্টার করবেন, তখন এই কাস্টম প্রোপার্টিগুলো (যেমন: ApplicationName) দিয়ে খুব সহজেই ফিল্টার করতে পারবেন।

🧠 Comprehensive Breakdown

এখানে আমরা লেকচারের প্রতিটি বিষয় বিস্তারিতভাবে আলোচনা করব এবং সাথে Code Implementation দেখব।

১. Enrichers কী এবং এর কাজ (Priority: 10/10)

যখন আপনি আপনার কোড থেকে একটি লগ লেখেন (যেমন: LogInformation("User logged in")), তখন Serilog শুধু এই মেসেজটাই সেভ করে না; এর সাথে RequestId বা Timestamp-ও যুক্ত করে।

Enrichment বলতে বোঝায় এই লগের সাথে আরও কিছু অতিরিক্ত তথ্য যুক্ত করে লগকে “সমৃদ্ধ” (Enrich) করা। যেমন, আপনার যদি ৫টি মাইক্রোসার্ভিস থাকে, তবে আপনি চাইবেন প্রতিটি লগের সাথে ওই সার্ভিসের নাম লেখা থাকুক, যাতে বুঝতে সুবিধা হয় লগটি কোথা থেকে এসেছে।

২. Configuration: appsettings.json-এ Custom Properties যুক্ত করা (Priority: 10/10)

আপনি চাইলে কোনো কোড না লিখেই appsettings.json ফাইল থেকে প্রতিটি লগের সাথে স্ট্যাটিক (Static) ডেটা যুক্ত করতে পারেন।

Code Implementation:

{
  "Serilog": {
    "MinimumLevel": "Information",
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.Seq"
    ],
    
    // Enrich Section: Log Context-এর ডেটাগুলো অ্যাক্সেপ্ট করবে
    "Enrich": [ "FromLogContext" ],
    
    // Properties Section: কাস্টম Key-Value ডেটা যা প্রতিটি লগের সাথে যুক্ত হবে
    "Properties": {
      "ApplicationName": "CRUD Demo Application",
      "Environment": "Development"
    },
    
    "WriteTo": [
      {
        "Name": "Seq",
        "Args": {
          "serverUrl": "http://localhost:5341"
        }
      }
    ]
  },
  "AllowedHosts": "*"
}
 

ব্যাখ্যা:

  • "Enrich": [ "FromLogContext" ]: এটি Serilog-কে নির্দেশ দেয় যে, লগের সাথে যে অতিরিক্ত প্রোপার্টিগুলো দেওয়া হবে (যেমন- RequestId বা নিচের Properties), সেগুলো যেন লগ ডেটার সাথে মার্জ করে সেভ করা হয়।
  • "Properties": এখানে আমরা "ApplicationName" নামে একটি Key এবং "CRUD Demo Application" নামে তার Value দিয়েছি। এটি একটি স্ট্যাটিক ডেটা।

৩. Seq ড্যাশবোর্ডে আউটপুট দেখা (Priority: 9/10)

উপরের কনফিগারেশন করার পর আপনি যখন অ্যাপ্লিকেশন রান করবেন এবং Seq ড্যাশবোর্ডে (http://localhost:5341) যাবেন, তখন যেকোনো লগের ওপর ক্লিক করলে এর বিস্তারিত প্রোপার্টি (Log Context) ওপেন হবে। সেখানে আপনি ConnectionId, RequestId-এর পাশাপাশি আপনার যুক্ত করা ApplicationName: "CRUD Demo Application" দেখতে পাবেন।

সবচেয়ে দারুণ ব্যাপার হলো, শুধুমাত্র আপনার লেখা লগের সাথেই নয়, বরং ASP.NET Core-এর জেনারেট করা প্রতিটি ফ্রেমওয়ার্ক লগের (যেমন: Route matched...) সাথেও এই ডেটাটি স্বয়ংক্রিয়ভাবে যুক্ত হয়ে যাবে।

৪. Static vs Dynamic Enrichment (Priority: 8/10)

appsettings.json-এ আমরা যে ডেটাগুলো যুক্ত করলাম, সেগুলো হলো স্ট্যাটিক। অর্থাৎ, অ্যাপ্লিকেশন রান হওয়ার সময় এই ভ্যালুটি একবারই সেট হয় এবং সব লগের জন্য একই থাকে।

কিন্তু ধরুন, আপনি চান কোনো ইউজার লগইন করলে তার UserId বা ডেটাবেস থেকে আসা কোনো নির্দিষ্ট ডেটা লগের সাথে যুক্ত করতে। এই ধরনের ডায়নামিক ডেটা appsettings.json দিয়ে করা সম্ভব নয়। এর জন্য কোড লিখতে হবে এবং IDiagnosticContext ব্যবহার করতে হবে, যা আপনারা ঠিক এর পরের লেকচারেই শিখবেন।


🚀 Best Practices & .NET Modern Updates

Best Practices for Enrichers:

  • Use NuGet Enrichers: Serilog-এর কিছু অসাধারণ অফিশিয়াল প্যাকেজ রয়েছে যা আপনার ম্যানুয়াল কাজ কমিয়ে দেয়। যেমন:

  • Serilog.Enrichers.Environment (MachineName এবং EnvironmentName যুক্ত করে)

  • Serilog.Enrichers.Thread (ThreadId যুক্ত করে)

  • Serilog.Enrichers.Process (ProcessId যুক্ত করে)

  • Global Filters in Seq: আপনি যখন ApplicationName অ্যাড করেন, তখন Seq ড্যাশবোর্ডে ApplicationName = 'CRUD Demo Application' লিখে সার্চ করলে শুধুমাত্র এই প্রজেক্টের লগগুলো ফিল্টার হয়ে আসবে। একাধিক প্রজেক্ট এক Seq সার্ভারে রাখলে এটি খুবই দরকারি।

Modern .NET Updates (Programmatic Enrichment): আধুনিক .NET 10-এ JSON কনফিগারেশনের পাশাপাশি কোডের মাধ্যমে Enrich করা বেশ জনপ্রিয়।

.NET 10 Code Implementation:

using Serilog;
 
var builder = WebApplication.CreateBuilder(args);
 
// .NET 10 Programmatic Setup with Enrichers
builder.Host.UseSerilog((context, services, loggerConfiguration) =>
{
    loggerConfiguration
        .ReadFrom.Configuration(context.Configuration)
        .Enrich.FromLogContext()
        .Enrich.WithProperty("Application", "Modern API .NET 10") // ম্যানুয়াল কাস্টম প্রোপার্টি
        .Enrich.WithMachineName(); // (Requires 'Serilog.Enrichers.Environment' package)
});
 

সামনের লেকচারটি আরও মজাদার হতে চলেছে, যেখানে আপনারা ডায়নামিক ডেটা লগে যুক্ত করার পদ্ধতি শিখবেন!