1. Giriş
Proqramlaşdırmada logging — sadəcə "konsola nəsə yazmaq" deyil. Logging — sizin qara qutu, GPS-tracker və indikatorun birləşməsi kimidir. Loglar olmadan böyük proqram qara qutu-məxluq olur: "niyə service dondu?", "niyə istifadəçi mail almadı?", "ümumiyyətlə bu modul son 3 ayda işə salınıbmı?" — bu kimi suallara çox vaxt yalnız loglar saxlanılırsa və əlçatan olarsa cavab tapmaq olur.
Reallıqda logging nəyə lazımdır?
Problem axtarışı və diaqnostika
Proqram çöksə — loglar harada və niyə baş verdiyini deyəcək. Çökməyibsə, amma qəribə davranırsa — loglar bu vəziyyətə gətirən addımları göstərəcək.
Monitoring
Loglardan sistemin hazırda işləyib-işləmədiyini, serverə neçə sorğu gəldiyini, səhvlərin baş verib-vermədiyini, kim nə etdiyini öyrənmək olar.
Təhlükəsizlik
Avtorizasiya cəhdlərinin, şübhəli fəaliyyətin, autentifikasiya xətalarının loglanması.
Audit
Kimin, nə və nə vaxt etdiyini. Pis niyyətli admin işdən çıxıb məlumatları sildiyi halda, loglar vasitəsilə hər şeyi bərpa etmək (və ya ən azı nə edildiyini anlamaq) mümkündür.
İnkişaf və əməliyyat dəstəyi
Loglar yalnız developer üçün deyil, tester, operator və admin üçün də vacibdir. Altı ay sonra özünüzə deyəcəksiniz: 'Təşəkkürlər, log əlavə etdiyin üçün!'
Console.WriteLine-dən sənaye səviyyəli logging-ə
Yeni başlayanların ilk reaksiyası: "Bəs, sadəcə Console.WriteLine kifayət etmir?" Kiçik tədris proqramları üçün bəli. Amma tətbiq serverdə işləyirsə, paralel işləyirsə və ya ondan onlarla və yüzlərlə istifadəçi istifadə edirsə, konsol artıq kömək etmir. Lazımdır:
- Vacib məlumatı və debugging məlumatını ayırmaq.
- Logları yalnız konsola deyil, fayllara, verilənlər bazasına, mərkəzləşdirilmiş sistemlərə göndərmək.
- Log detallılıq səviyyəsini dəyişmək (minimum — yalnız səhvlər, maksimum — hər şey).
- Qeydləri avtomatik olaraq tarix, vaxt və əlavə məlumatla zənginləşdirmək.
- Elastik konfiqurasiya imkanı.
- Və ən əsası — logların istiqamətini dəyişmək üçün kodu yenidən dəyişməmək.
Budur "həqiqi" logger-lərin dövrü başlayır.
2. .NET-də müasir logging sistemi əsasları
.NET ekosistemində güclü və elastik logging framework-ü mövcuddur — Microsoft.Extensions.Logging. Bu ASP.NET Core ilə birlikdə ortaya çıxan "yeniləşmiş" .NET kitlərindən biridir, amma indi hər yerdə istifadə olunur: serverdə, desktop-da və hətta mobil tətbiqlərdə.
Niyə bu framework yaxşıdır?
- Abstraction — sizi konkret implementasiyaya bağlamır (logger fayla, konsola, buluda və ya hamısına yazmaq olar).
- Logging səviyyələrinin dəstəyi (Trace, Debug, Information, Warning, Error, Critical).
- DI-container-a inteqrasiya və bütün müasir .NET tətbiqlərinə inteqrasiya.
- Strukturlaşdırılmış logging, inkişaf etmiş formatter-lər və inteqrasiyalar üçün zəngin ekosistem.
Əsas anlayışlar və klasslar
Gəlin Microsoft.Extensions.Logging-lə işləmək üçün lazım olacaq əsas obyektlərlə tanış olaq:
| Class/Interface | Təyinat |
|---|---|
|
Tipizə edilmiş class üzrə logging interfeysi |
|
Generic olmayan logger interfeysi |
|
Logger nümunələrinin yaradılması fabriki |
|
Tətbiqdə logging-i konfigurasiya etməyə imkan verir |
|
Log səviyyələrinin enum-u (Trace, Debug, Information, ...) |
Logging səviyyələri
Mesajların önəmlik səviyyəsinə görə bölünməsi "səs-küyü" filtrə salmağa və lazım olanı tapmağa imkan verir:
| Səviyyə (LogLevel) | Necə istifadə etmək? |
|---|---|
|
Ən detallı debugging, "səs-küy", zamana bağlı məlumatlar |
|
Əsas debugging məlumatı |
|
Normal işləmə üçün əsas event mesajları |
|
Potenial problemlər haqqında xəbərdarlıqlar, amma sistem davam edir |
|
Diqqət tələb edən xətalar, amma tətbiq hələ işləkdir |
|
Bütün sistemi təhdid edən kritik pozuntular |
3. Praktika: tətbiqimizə logging əlavə edək
Gəlin abstrakt kod yazmayaq, onun əvəzinə demo tətbiqimizi inkişaf etdirək. Tutaq ki, bizim artıq sadə Calculator klassımız var və kurs boyunca onu genişləndirəcəyik.
Nümunə: əsas calculator
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
// Digər metodlar...
}
İndi ora logging əlavə edək. Bunun üçün bizə ILogger<Calculator> interfeysi lazımdır, onu xaricdən alacağıq (məsələn, Dependency Injection, DI vasitəsilə).
using Microsoft.Extensions.Logging;
public class Calculator
{
private readonly ILogger<Calculator> _logger;
public Calculator(ILogger<Calculator> logger)
{
_logger = logger;
}
public int Add(int a, int b)
{
int result = a + b;
_logger.LogInformation("Yerinə yetirildi toplama: {A} + {B} = {Result}", a, b, result);
return result;
}
}
Maraqlı fakt:
String concatenation yerinə logger-lər template-ləri və adlandırılmış parametrleri ({A}, {B}, {Result}) dəstəkləyir, bu da logları strukturlaşdırılmış və avtomatik emal və axtarış üçün əlverişli edir.
4. Konsol tətbiqində logger necə yaratmaq və konfiqurasiya etmək
1. NuGet paketlərini əlavə edirik
Layihənizdə lazım olacaq:
- Microsoft.Extensions.Logging
- Microsoft.Extensions.Logging.Console (konsola yazmaq istəyirsinizsə)
- (opsional) digər provider-lər, əgər lazım olarsa
2. Logger-i konfiqurasiya edirik
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// DI-container yaradırıq
var serviceProvider = new ServiceCollection()
.AddLogging(builder => {
builder.AddConsole(); // Konsola çıxış
builder.SetMinimumLevel(LogLevel.Debug); // Minimal log səviyyəsi
})
.BuildServiceProvider();
// Lazımı tip üzrə logger nümunəsini götürürük
var logger = serviceProvider.GetRequiredService<ILogger<Calculator>>();
var calculator = new Calculator(logger);
calculator.Add(5, 3); // Loglara mesaj düşəcək
Yeni başlayanların tipik səhvi
"Niye log konsolda görünmür?" — yoxlayın ki, uyğun provider əlavə edilibmi (.AddConsole()) və minimal logging səviyyəsi düzgün təyin edilibmi (SetMinimumLevel). Əgər səviyyə daha yüksəkdirsə, mesajlar sadəcə "filtrlənə" bilər!
5. Faydalı nüanslar
Xətaları və istisnai hallar loglamaq
Tutaq ki, sıfıra bölməni loglamaq istəyirik. Müvafiq metodu əlavə edək:
public int Divide(int a, int b)
{
if (b == 0)
{
_logger.LogError("Sıfıra bölmə cəhdi! a={A}", a);
throw new DivideByZeroException();
}
int result = a / b;
_logger.LogInformation("Yerinə yetirildi bölmə: {A} / {B} = {Result}", a, b, result);
return result;
}
Niyə bu lazımdır?
Real tətbiqdə nəsə səhv gedəndə, Error səviyyəli loglar adətən xüsusi diqqət cəlb edir: onlar avtomatik admin-ə göndərilir, monitoring-də işıqlandırılır və alert/notification üçün istifadə olunur.
Kategoriya və etiketlərdən (scopes) istifadə
.NET logger-ləri scopes dəstəkləyir — müəyyən kod blokunda bütün loglara avtomatik əlavə olunan əlavə metadata-lardır. Məsələn, web-request və ya user session zamanı onun identifikatorunu scope-a əlavə etmək olar.
using (_logger.BeginScope("UserId: {UserId}", 42))
{
_logger.LogInformation("İstifadəçi məlumatlarının emalı başladı");
// ...
}
Blok daxilindəki bütün mesajlar əlavə etiket UserId: 42 alacaq, bu da sonradan istifadəçi və ya əməliyyat üzrə log tapmağı asanlaşdırır.
Nümunə: logging səviyyələrinin işləməsi
_logger.LogTrace("Bu Trace-dir — demək olar ki, heç kim görməyəcək");
_logger.LogDebug("Bu Debug-dir — developer-lər üçün");
_logger.LogInformation("Bu Information-dir — normal iş hadisələri üçün");
_logger.LogWarning("Bu Warning-dir — potensial problem haqqında xəbərdarlıq");
_logger.LogError("Bu Error-dir — diqqət tələb edən xəta");
_logger.LogCritical("Bu Critical-dir — Sistem yanır, yanğınsöndürən lazımdır!");
Əgər SetMinimumLevel(LogLevel.Information) təyin etmisinizsə, yalnız Information, Warning, Error, Critical səviyyələrini görəcəksiniz.
Fayda:
Trace və Debug loglarını inkişaf mərhələsində ətraflı diaqnostika üçün saxlayın, amma production serverdə adətən yalnız Information və yuxarı səviyyələr aktiv edilir ki, logların həcmi böyüməsin və vacib olanı "səs-küy" arasında itirməyəsiniz.
Vizual sxem: müasir logging arxitekturası
graph TD
A[Proqram kodu] --ILogger<YourClass>--> B[Microsoft.Extensions.Logging]
B --> C1[Console Provider]
B --> C2[File Provider]
B --> C3[Cloud/Database Provider]
C1 -.-> D1[Loglar konsola]
C2 -.-> D2[Loglar fayla]
C3 -.-> D3[Loglar monitoring sisteminə]
subgraph Providers
C1
C2
C3
end
6. Əlavə imkanlar və extension-lar
Strukturlaşdırılmış logging:
Parametrlərin dəyərlərini yalnız string-də saxlamaq yox, key-value şəklində saxlamaq mümkündür, bu isə Seq, ELK/ElasticSearch və ya Application Insights kimi sistemlərdə axtarış və aqreqasiya etməyə imkan verir.
Logging provider-ləri:
Fayl, Windows EventLog, Azure və s. üçün çoxsaylı provider-lər əlavə etmək olar.
Logging-in appsettings.json-lə konfiqurasiyası
ASP.NET Core-da loglar konfiqurasiya faylı ilə elastik şəkildə idarə olunur, tətbiqi yenidən kompilyasiya etmədən.
Konfiqdən minimal log səviyyəsini təyin etmə nümunəsi (appsettings.json):
{
"Logging": {
"LogLevel": {
"Default": "Information",
"MyApp.Calculator": "Debug",
"Microsoft": "Warning"
}
}
}
7. Microsoft.Extensions.Logging ilə işləyərkən tipik səhvlər
Səhv №1: Logging səviyyəsinin səhv seçimi.
LogInformation-i xətalar üçün LogError və ya LogCritical əvəzinə istifadə etmək production-da problemlərin tapılmasını çətinləşdirir.
Səhv №2: Strukturlaşdırılmış logging-i görməzdən gəlmək.
String concatenation yerinə placeholder-lı template-lərdən ({Parameter}) istifadə etməmək strukturlaşdırılmış logging-in üstünlüklərindən məhrum edir, məsələn parametrlərlə axtarış mümkün olmur.
Səhv №3: Logging səviyyələrinin səhv konfiqurasiyası.
Əgər minimal log səviyyəsi lazımi səviyyədən yüksək təyin edilibsə (məsələn Warning əvəzinə Debug tələb olunursa), əhəmiyyətli mesajlar filtrlənə bilər.
Səhv №4: Artıq və ya kifayət qədər olmayan logging.
Production-da çox detallı loglar (məsələn, Trace) "səs-küy" yaradır, az log isə diaqnostikanı çətinləşdirir.
GO TO FULL VERSION