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 Operation və FileName 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 — Information və Warning-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 | |
123 |
| Əməliyyat | |
"Silinmə" |
| Xəta | |
"Qeydiyyat modulu" |
| Əməliyyat vaxtı | {Elapsed:0.000} s | 1.234 |
| Fayl adı | |
"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.
GO TO FULL VERSION