CodeGym /Kurslar /C# SELF /Strukturlaşdırılmış logging və

Strukturlaşdırılmış logging və Serilog

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Əgər adi mətn şəklində logging — sizin "Mən bu gün yemək yedim" tipli qeyd dəftərinizdirsə, strukturlaşdırılmış logging hər bir yazını sahələri olan kartçaya çevirir: {Tarix: ..., Hadisə: "Yedim", Kalori: 500, Yemək: "Qızardılmış ət"}. Bu o deməkdir ki, daha sonra siz təkcə qeyd oxumaqla kifayətlənməyib, həftəlik/qabaq aylıq kalori qrafiki çəkə, yeməyə görə filtrləyə və gec vaxt nə vaxt yeməyinizə baxa bilərsiniz.

Niyə sadə mətn kifayət etmir?

Sadə mətn ilə hər şey asandır... müəyyən vaxta qədər. Xətaların statistikası, onlayn mağazada satış həcmlərinin toplanması, bir istifadəçinin əməliyyat zəncirini onun ID-sinə görə (məsələn, 42) toplamaq cəhd edin — əgər bütün məlumatlar mətn bloklarıdırsa, bu çətin olacaq. Strukturlaşdırılmış logging loglara analiz və hətta AI əlavə etməyə imkan verir. Onunla anomaliyaları tapmaq, dashboard-lar qurmaq və problemlərə avtomatik reaksiya vermək olar.

Üstünlüklər

  • Yalnız mesaj deyil, ona bağlı məlumatları (field/sahə və properties) də loglamağa imkan verir.
  • Logları avtomatlaşdırılmış şəkildə analiz etmək mümkündür: saymaq, filtrləmək, hesabatlar hazırlamaq.
  • JSON kimi standart formatlar istifadə olunur ki, maşınlar üçün parse etmək asandır.

Serilog: nədir və niyə məhz o?

Serilog (rəsmi sayt: serilog.net, sənədlər: github.com/serilog/serilog/wiki) — .NET üçün məşhur strukturlaşdırılmış logging kitabxanasıdır. O, Microsoft.Extensions.Logging ilə yaxşı inteqrasiya edir, fayl, konsole, Seq, ElasticSearch, Grafana, Azure və s. kimi çoxsaylı sistemlərə çıxışı dəstəkləyir, performansa minimal təsir edir və konfiqurasiyası sadədir.

Serilog "sadə logging"-dən nə ilə fərqlənir?

  • Struktur: loglar filtrlənə bilən sahələri olan obyektlərdir (məsələn, bütün istifadəçi ID-si 42 olan xətalar).
  • Formatlar: yalnız mətn deyil, həm də JSON, XML yazmaq mümkündür — sonrakı emal üçün əlverişlidir.
  • Elastiklik: logları istənilən yerə göndərmək üçün çoxsaylı hazır sink-paketlər mövcuddur.

Serilog ilə log yazısının strukturu

Kod yazmazdan əvvəl strukturlaşdırılmış log-a bir nəzər salaq.

{
  "Timestamp": "2024-06-22T10:23:45.123Z",
  "Level": "Information",
  "MessageTemplate": "İstifadəçi {UserId} sisteme daxil oldu",
  "Properties": {
    "UserId": 42,
    "IpAddress": "127.0.0.1"
  }
}

Buradan ən sadə analiz belə başa düşər: söhbət 42 nömrəli istifadəçidən və onun IP ünvanından gedir.

2. C# layihəsində Serilog-un quraşdırılması və əsas konfiqurasiya

Addım 1. NuGet paketlərini quraşdırmaq

Rider/Visual Studio-da NuGet Package Manager vasitəsilə quraşdırın:

  • Serilog
  • Serilog.Sinks.Console (konsole çıxışı)
  • Serilog.Extensions.Logging (Microsoft.Extensions.Logging ilə inteqrasiya üçün)

Komanda sətri ilə:

dotnet add package Serilog
dotnet add package Serilog.Sinks.Console

Addım 2. Minimal konfiqurasiya

Program.cs-ə konfiqurasiya əlavə edib ilk log-u yazacağıq.

using System;
using Serilog;

namespace MySuperApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. Serilog üçün əsas konfiqurasiya: konsole çıxışı
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .CreateLogger();

            // 2. Strukturlaşdırılmış logging nümunəsi
            int userId = 42;
            string ip = "127.0.0.1";
            Log.Information("İstifadəçi {UserId} sisteme daxil oldu, IP ilə {IpAddress}", userId, ip);

            Log.CloseAndFlush();
        }
    }
}

Konsoleda təxminən belə görünəcək:

[10:30:16 INF] İstifadəçi 42 sisteme daxil oldu, IP ilə 127.0.0.1

Sonra çıxışı JSON-fayla, Seq-ə və ya başqa sistemə yönləndirmək asandır.

3. Log formatlaşdırma: Message Template

Serilog-də string concatenation əvəzinə template sintaksisi istifadə olunur:

Log.Information("Fayl üzərində əməliyyat {Operation} fayl {FileName}", "silinmə", "test.txt");

Bu sadəcə gözəl yazı deyil — bu strukturlaşdırılmış logging-dir: yazıya OperationFileName sahələri daxil olur, onlar filtrləmə və aqreqasiya üçün əlçatandır.

string.Format-dan nə ilə fərqlənir?

string.Format("Əməliyyat {0} fayl üzərində {1}", operation, fileName) sadəcə placeholder-ları birləşdirir ({0}, {1}). Serilog isə ayrıca sahələr yaradır ki, sonradan analytika üçün istifadə oluna bilsin.

Elastik konfiqurasiya: səviyyələr, filter-lər, müxtəlif "sink"-lər

Serilog logları eyni anda bir neçə yerə yazdıra bilər.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

İndi loglar həm konsole, həm də günlük rotasiyalı fayla yazılır.

4. Nümunə

Tutaq ki, konsol "notebook" tətbiqi yazırıq — istifadəçinin qeydlərini yaratmağa imkan verir. Biz istifadəçi əməliyyatlarını strukturlaşdırılmış şəkildə loglayaq.

using System;
using Serilog;

namespace NotesApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.Console()
                .WriteTo.File("notes-log.json", rollingInterval: RollingInterval.Day, 
                              formatter: new Serilog.Formatting.Json.JsonFormatter())
                .CreateLogger();

            Console.WriteLine("İstifadəçi adını daxil edin:");
            string userName = Console.ReadLine();

            Log.Information("İstifadəçi {UserName} NotesApp tətbiqini işə saldı", userName);

            while (true)
            {
                Console.WriteLine("Qeyd mətnini daxil edin (və ya 'çıxış' yazın):");
                string note = Console.ReadLine();

                if (note == "çıxış")
                {
                    Log.Information("İstifadəçi {UserName} işi dayandırdı", userName);
                    break;
                }

                Log.Information("İstifadəçi {UserName} qeyd yaratdı: {NoteText}", userName, note);
            }

            Log.CloseAndFlush();
        }
    }
}

Şərh:
Log kim tətbiqi işə saldığını, nə daxil etdiyini və işi nə vaxt dayandırdığını qeyd edir. notes-log.json faylında hər bir yazı asan analiz olunan JSON-obyektdir.

5. Faydalı nüanslar

Strukturlaşdırılmış logging üçün ən yaxşı təcrübələr

  • Prodakşnda Debug/Trace səviyyələrindən sui-istifadə etməyin — InformationWarning-dən ağıllı şəkildə istifadə edin.
  • Template-lərdə concatenation əvəzinə named parameters istifadə edin.
  • Heç vaxt həssas məlumatları (parollar, tokenlər, açarlar) loglamayın.
  • Yalnız xətaları deyil, mühüm biznes-hadisələri loglayın.
  • Disk dolmasın deyə log rotasiyası və təmizləmə qurun.

Vizualizasiya və analiz: Seq, Kibana, Application Insights

Serilog çoxlu sink-ləri dəstəkləyir — yəni logların göndərildiyi son nöqtələr.

Sink Qısa təsvir Harada istifadə olunur
Console Birbaşa konsole İnkişaf, test
File Yerli və ya şəbəkə faylı Kiçik layihələr, dev
Seq Filtrləmə və dashboard-larla veb interfeys Enterprise, analitika
ElasticSearch Güclü saxlama və analiz sistemi Böyük şirkətlər
Azure Application Insights Bulud monitorinqi və telemetriya Azure-yüklü servisler

Seq (datalust.co/seq) — inkişaf və daxili istifadədə çox populyar çözüm: əlverişli filtrləmə, sahələr üzrə axtarış və sürətli deployment.

Cədvəllər və vizualizasiya

Aşağıda strukturlaşdırılmış şəkildə nə loglana biləcəyinin qısa cədvəlini göstərirəm:

Nə loglanır Serilog-də necə görünür Nümunə dəyər
İstifadəçi ID-si
{UserId}
123
Əməliyyat
{Action}
"Silinmə"
Xəta
Log.Error(ex, "Xəta {Module}-də")
"Qeydiyyat modulu"
Əməliyyat vaxtı {Elapsed:0.000} s 1.234
Fayl adı
{FileName}
"report.pdf"

Serilog-un maraqlı funksiyaları və əlavə imkanları

  • Enrichers: hər log-a əlavə xassələr əlavə edir (məsələn, .Enrich.WithMachineName()).
  • Correlation: hadisə zəncirini əlaqələndirmək üçün RequestId əlavə edin.
  • appsettings.json vasitəsilə konfiqurasiya: prod üçün rahatdır.
{
  "Serilog": {
    "MinimumLevel": "Debug",
    "WriteTo": [
      { "Name": "Console" },
      { "Name": "File", "Args": { "path": "log.txt" } }
    ]
  }
}

Advanced sinks: logları Slack, Telegram, e-poçt və s.-yə göndərmək olar (amma ehtiyatlı olun — hər xəta üçün minlərlə e-poçt gəlməməsi üçün).

6. Praktik hissə: Microsoft.Extensions.Logging-lə inteqrasiya

.NET-də çox vaxt konkret kitabxanaya bağlanmamaq üçün standart ILogger interfeysindən istifadə olunur. Serilog provider kimi qoşula bilər.

Addım 1. Paket quraşdırılması

dotnet add package Serilog.Extensions.Logging

Addım 2. Konfiqurasiya

using Microsoft.Extensions.Logging;
using Serilog;

// ...

// Serilog-u adi qaydada konfiqurasiya edin:
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

// İndi Microsoft.Extensions.Logging istifadə edirik
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddSerilog();
});

ILogger<Program> logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Test mesajı: {TestValue}", 123);

// Unutmayın bağlamağı:
Log.CloseAndFlush();

Şərh:
İndi kodunuz ILogger<T> üzərində yazılıb və provider-dən asılı deyil — istəsəniz asanlıqla NLog və ya Log4Net-ə keçə bilərsiniz.

7. Serilog ilə işləyərkən tipik səhvlər

Log overload: hər şeyi yazmaq faydalı məlumatı tapmağı çətinləşdirir.

Xətanı mətn kimi loglamaq: exception overload-dan istifadə edin — beləliklə xətanın strukturu logda qalacaq.

try
{
    // some code
}
catch (Exception ex)
{
    Log.Error(ex, "Sorğu işlənərkən xəta baş verdi");
}

Konfiqurasiya ilə sui-istifadə: konfiqurasiyanı "səfərbər koması" etməyin — yalnız lazım olan sink-ləri və səviyyələri əlavə edin.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION