1. Giriş
Tutaq ki, siz saytın administratorusunuz və hər gün sizə minlərlə istifadəçi gəlir. Loglarda görürsünüz ki, hər şey işləyir, səhvlər demək olar yox dərəcəsindədir (bəzən kimsə şifrəni unudur və ya captcha-da səhv edir). «Hər şey əladır!» — deyə düşünürsünüz.
Və birdən kiminsə dəstəyə yazır ki, sayt çox yavaşdır, səhifələr 10 saniyə açılır. Siz loglara baxırsınız — səhv yoxdur! Xoşbəxtlik? Yox, çünki loglar nə baş verdiyini (və ya baş vermədiyini) deyir, amma hansı sürətlə və ya yavaşlıqla baş verdiyini, bunun üçün nə qədər resurs lazım olduğunu və yüklə dəyişərkən bu davranışın necə dəyişdiyini demirlər.
Burada səhnəyə metrikalar çıxır — tətbiqin işləməsinin ölçülə bilən göstəriciləri. Bu yalnız səhvlərin sayı deyil, həm də orta cavab müddəti, istifadə olunan yaddaş həcmi, saniyədə sorğular sayı və sistemin sağlamlığını qiymətləndirməyə imkan verən digər göstəricilərdir.
Müqayisə:
Loglar — bu "nə baş verdi".
Metrikalar — bu "sistem nə dərəcədə yaxşı/pis işləyir".
Tracing — bu "nə üçün sistem belə işləyir (ətraflı)".
Hansı metrikalar olur və nəyi yığmaq lazımdır?
Əsas metrika növləri:
| Metrika tipi | Nümunə | Nəyə lazımdır |
|---|---|---|
| Sayıcılar (Counters) | Sorğuların, səhvlərin, uğursuzluqların sayı | Trendler, alertlər, yüklənmə |
| Histogramlar | Cavab vaxtı, paket ölçüsü | Qiymətlərin paylanması, percentillər |
| Gauge-lar (Gauge) | Yaddaş istifadəsi, CPU | Resursun cari vəziyyəti |
| Cəmçilər (Sum) | Ümumi məlumat həcmi, bayt | Müəyyən dövrdə əməliyyatların ümumi həcmi |
Nümunələr:
- Orta və 95-ci percentil GET sorğusunun cavab vaxtı.
- Hazırda onlayn olan istifadəçilərin sayı.
- Yaddaş istifadəsi (Private Bytes, Working Set).
- 500/503 tipli səhvlərin baş vermə tezliyi.
- Dəqiqədə DB sorğuları.
Bu göstəricilər yalnız problemləri tapmağa yox, həm də onları qarşısını almağa kömək edir — məsələn serverdə artan yük və ya cavab vaxtının «sürüşməsi» gələcəkdə nasazlıqların siqnalı ola bilər.
2. .NET-də metrikaların yığılması və OpenTelemetry ekosistemi necə işləyir
Ümumi arxitektura
Müasir .NET-də (NET 6-dan başlayaraq, xüsusən .NET 8/9-da) metrikaların yığılması üçün standart sistem var, bu sistem OpenTelemetry-yə əsaslanır.
Bu necə işləyir:
- Tətbiq kodu sayğacları artırmaq, gauge-ları qeyd etmək, histogramlara dəyərlər yazmaq üçün metodları çağırır.
- OpenTelemetry Metrics SDK bu metrikaları (yaddaşda) toplayır və periodik olaraq göndərir.
- Metrika exporteri onları seçilmiş monitorinq sisteminə (Prometheus, Application Insights, Grafana Cloud, Datadog və s.) ötürür.
- Monitorinq backend-i agregasiya edir, saxlayır, vizuallaşdırır, alertlər və dashboardlar qurur.
Sadə blok-sxema:
[Sizin tətbiq]
⬇
[Metrikaların yığılması (OpenTelemetry SDK)]
⬇
[Metrika exporteri (Prometheus, AI, Datadog, ...)]
⬇
[Monitorinq sistemi/dashboardlar/alertlər]
3. Praktika: C#-da metrikalarla işləməyin əsasları
Sadə daxili metrikalar: System.Diagnostics.Metrics
.NET metrikalar üçün daxili mexanizm təqdim edir — System.Diagnostics.Metrics.
Əsas oyunçular: Meter, Counter<T>, Histogram<T>, ObservableGauge<T>.
Nümunə: səhifə ziyarətləri sayğacı
// Meter yaradırıq (adətən bütün tətbiq üçün bir)
using System.Diagnostics.Metrics;
static Meter meter = new Meter("MyCompany.MyApp", "1.0");
// Sayğacı qeyd edirik
static Counter<long> homePageVisits = meter.CreateCounter<long>("HomePageVisits");
// Haradasa controller və ya servisdə...
public void HomePageRequested()
{
homePageVisits.Add(1);
// Səhifə emalının qalan hissəsi
}
Şərhlər:
- Meter — metrikalar üçün «fabrika», unikal adla (tətbiq/şirkət namespace).
- CreateCounter<long> — sayğacı yaradır; inkrement üçün Add(1).
Nümunə: cavab vaxtının ölçülməsi
static Histogram<double> pageLoadTime = meter.CreateHistogram<double>("PageLoadTimeMs");
// Sorğu handlerində:
public void OnRequest()
{
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// ...sorğunun özü...
stopwatch.Stop();
pageLoadTime.Record(stopwatch.Elapsed.TotalMilliseconds);
}
Dinamik dəyərlər üçün gauge-ların toplanması
Gauge — zamanla dəyişən göstərici: qoşulmuş istifadəçilərin sayı, cari yaddaş həcmi və s.
static ObservableGauge<int> onlineUserGauge = meter.CreateObservableGauge(
"OnlineUsers",
() => GetOnlineUserCount());
// GetOnlineUserCount - cari dəyəri qaytaran metod
static int GetOnlineUserCount()
{
// Burada sizin real loqikanız olmalıdır!
return ActiveUserList.Count;
}
Real dünyada bütün bu iş asinxron işləyir: tətbiq metrik dəyərlərini verir, exporter onları götürür və xaricə ötürür (məsələn, Prometheus "/metrics" endpoint-i scrapp edir).
Modern ASP.NET Core tətbiqinə metrik əlavə etmək
ASP.NET Core üçün bir çox şey box-dan çıxanda mövcuddur. OpenTelemetry.Instrumentation.AspNetCore paketini əlavə etmək kifayətdir və HTTP sorğular, cavab vaxtı, səhv sayı və s. metrikaları avtomatik görünəcək.
Program.cs-də konfiqurasiya nümunəsi:
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyApp"))
.AddAspNetCoreInstrumentation() // HTTP metrikaları
.AddRuntimeInstrumentation() // .NET CLR runtime metrikaları
.AddProcessInstrumentation() // prosesin CPU/yaddaşı
.AddMeter("MyCompany.MyApp") // sizin metrikalarınız
.AddPrometheusExporter(); // Prometheus-a eksport
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
İndi tətbiqiniz /metrics ünvanında metrikalar verəcək, onları Prometheus və ya digər sistemlər scrapp edə bilər.
4. Metrikaların praktik istifadəsi nümunələri
Real layihələrdə performansın monitorinqi
Metrikaları qoşuruq ki, bilək:
- API orta və pik RPS (requests per second) nə qədər davam gətirir?
- Harada «bottleneck» var: bir endpoint 300 ms işləyir, digəri — 2000 ms?
- DB çağırışlarına nə qədər vaxt gedir? (öz histogramlarımızı əlavə edirik)
Nümunə: DB cavab vaxtını nəzarət edirik
static Histogram<double> dbQueryDuration = meter.CreateHistogram<double>("DbQueryDurationMs");
public async Task<List<Product>> GetProductsAsync()
{
var sw = Stopwatch.StartNew();
var result = await _db.Products.ToListAsync();
sw.Stop();
dbQueryDuration.Record(sw.Elapsed.TotalMilliseconds);
return result;
}
Nümunə: səhvlərin sayını sayırıq
static Counter<long> apiErrors = meter.CreateCounter<long>("ApiErrors");
public IActionResult SomeEndpoint()
{
try
{
// bəzi əməliyyat
return Ok();
}
catch (Exception)
{
apiErrors.Add(1);
throw;
}
}
Metrikalarda label (tag) ilə işləmək
Məlumatları faydalı xüsusiyyətlər üzrə qruplaşdırmaq vacibdir: endpoint, səhv tipi, istifadəçi tipi və s.
homePageVisits.Add(
1,
KeyValuePair.Create<string, object>("UserType", "Admin"));
Yaxud histogram üçün:
dbQueryDuration.Record(
sw.Elapsed.TotalMilliseconds,
KeyValuePair.Create<string, object>("QueryType", "GetProducts"));
Tag-lar sayəsində Grafana-da yalnız ümumi tətbiq üzrə deyil, həm də konkret seqmentlər üzrə qrafiklər çəkə bilərsiniz.
5. Prometheus, Application Insights, Datadog, Grafana ilə inteqrasiya
Exporter-lər və inteqrasiyalar
- Prometheus — geniş istifadə olunan open-source monitorinq, buludlar və Kubernetes üçün de-facto standart.
- Application Insights — Azure üçün bulud inteqrasiyası.
- Datadog, Grafana Cloud — peşəkar infrastrukturlar üçün.
Bütün bu sistemlər .NET-dən metrikaları OpenTelemetry exporterləri vasitəsilə toplaya bilərlər. OTel exporter-ləri üçün sənədlər
Prometheus (addımlar):
- NuGet paketi əlavə et: OpenTelemetry.Exporter.Prometheus.
- .AddPrometheusExporter()-u metric qeydiyyatına əlavə et.
- Grafana-da datasource kimi Prometheus-u konfiqurasiya edib dashboard-lar yarat.
Faydalı linklər:
6. Xüsusiyyətlər, minalar və tipik səhvlər
Tez-tez olan səhvlərdən biri — tag-larda həddindən artıq detal. Tag-lara çoxlu unik dəyərlər (məsələn, istifadəçi/əmr ID-si) vermək zaman seriyalarının sayını partladır — bu, metrika saxlama sisteminin overload olmasına və xərclərin artmasına gətirəcək (bu hal cardinality explosion adlanır). Tag-ları «qabaqdili» saxlayın.
Tərtibatçılar bəzən System.Diagnostics.Metrics və hazır alətləri nəzərə almırlar və loglar və taymerlər ilə «velosiped» düzəldirlər. Nəticədə monitorinq daha pis inteqrasiya olunur və idarə olunması çətinləşir. Standart alətlərdən və avtomatik instrumentasiyadan istifadə edin.
Başqa bir yaygın səhv — metrikalar toplanır, amma eksport olunmur. Exporter konfiqurasiyası vacibdir: məsələn, .AddPrometheusExporter() əlavə edin və /metrics endpoint-inin scrapp üçün əlçatan olduğuna əmin olun.
Və nəhayət, metrika tiplərinin qarışması: orta cavab vaxtını Counter ilə hesablamaq lazımdır deyə düşünmək səhvdir, əslində Histogram istifadə edilməlidir — yoxsa pikləri və paylanmanı görməyəcəksiniz. Counters — miqdarı üçün; histograms — vaxt/ölçü/paylanma üçün; gauges — cari vəziyyətlər üçün.
GO TO FULL VERSION