Alarms ve tenant scoping
Alarmlar Grafana-tabanlı alert kurallarıdır. DT Edge Platform org'ların birbirinin verisini görmesini PromQL injection ile engeller — her org'a kendi Grafana'sı vermez.
Tek Grafana
Her DT Edge Platform kurulumu başına bir Grafana instance'ı vardır.
Her org'un alarmları aynı Grafana'da, aynı folder'da (dtedge),
aynı rule group'ta yaşar. Eski docs per-edge Grafana'lardan söz
ediyordu; o gitti.
Peki org'lar birbirinin alarmlarını nasıl görmüyor?
İki katman scoping
Katman 1 — kural üzerinde label'lar
DT Edge Platform bir alarm kuralı oluşturduğunda iki label damgalar:
dtedge_managed=true— dtedge-owned kuralları birinin doğrudan Grafana'da elle yazdığı kurallardan ayırt ederdtedge_org_id=<bu-org-uuid>— tenant identity
dtedge'deki list/get/update/delete handler'ları bu label'lara
göre filtreler. GET /api/orgs/.../alarms çağıran bir org
kullanıcısı sadece kendi dtedge_org_id'li kuralları görür.
Arkadaki Grafana 50 org boyunca bin kural barındırabilir —
kullanıcı sadece kendininkini görür.
Katman 2 — PromQL injection
Bir kuralın PromQL'i kendi başına org identity taşımaz; sadece metric expression. Ek scoping olmadan org A için bir kural org B'nin edge'lerinin yaydığı data point'lerle eşleşebilir (çünkü central Prometheus her ikisini de barındırıyor).
Yani: DT Edge Platform her kuralın PromQL'ini Grafana'ya göndermeden önce
rewrite eder. AST'yi yürür, her VectorSelector'u bulur ve
bir label matcher ekler:
kullanıcı yazdı: rate(http_requests_total[5m]) > 0.9
backend gönderir: rate(http_requests_total{telemetry_id=~"<edge-uuid-1>|<edge-uuid-2>|..."}[5m]) > 0.9
telemetry_id matcher'ı bu org'a ait her edge'i listeler. Liste
istek başına taze inşa edilir — bir edge eklemek onun verisinde
hemen eşleşmeleri toplar; bir edge kaldırmak bir sonraki eval
döngüsünde eşleşmeyi durdurur.
Kullanıcı matcher'ı asla yazmaz. UI okumada gizler (read'de
strip + write'de inject — round-trip görünmez). Server defence
in depth olarak literal telemetry_id referansı içeren herhangi
bir kullanıcı PromQL'ini reddeder.
Bu tasarım neden
Üç seçenek vardı:
- Org başına bir Grafana. En temiz isolation, operasyonel olarak pahalı (yönetilecek çok Grafana, kendi login'leriyle çok kullanıcı, cross-correlate etmek zor).
- Bir Grafana, DT Edge Platform her şeye aracılık eder. Bizim olduğumuz şey. PromQL injection tenancy'yi query AST seviyesinde uygular; label'lar ownership'i kural list seviyesinde uygular.
- Bir Grafana, sadece kullanıcılara birbirinin kurallarına bakmamasını söyle. Aslında bir multi-tenant story değil. Reddedildi.
Seçenek 2 operasyonel sadelik üzerinde kazandı (yedeklenecek,
yükseltilecek, izlenecek bir Grafana) injection hakkında
dikkatli olmak zorunda olmanın bedeline (AST walker bir
VectorSelector'ı kaçırırsa, bu bir tenant-isolation bug'ı). Injection
internal/services/grafana/promql_inject.go'da yaşar ve testleri
vardır.
Burada "tenant" ne demek
Tenant = dtedge_org_id. Yani:
- Aynı org'un iki üyesi aynı alarmları görür (evet)
- Bir super-admin org context'ini değiştirebilir ve farklı alarm setleri görebilir (evet — aynı veritabanı, sadece istek başına farklı filtrelenmiş)
- Bir admin user yalnızca aktif org'unun alarmlarını görür (evet — A org'unda iseniz ama B org'unu seçtiyseniz B'nin alarmlarını görürsünüz)
- "Public Edges" admin yüzeyi (lisans onu taşıdığında) kendi alarmlarına sahip değildir — alarmlar hâlâ org gerektirir
Per-rule eval interval neden yok
Her DT Edge Platform alarmı platformun varsayılan eval cadence'inde (60 saniye) çalışır. UI bir "her X saniyede değerlendir" picker'ı yüzeylemez.
Sebep: ops sadelik. Bir Grafana'yı paylaşan birçok org ile, bir org'da 5 saniyede bir çalışan bir kural herkesin yükünü etkiler. Tune ettiğimiz şey platform varsayılanı; kural yazarları onun hakkında tartışmaz.
Belirli bir koşul için gerçekten dakika-altı çözünürlüğe ihtiyacınız varsa DT Edge Platform doğru tool değil — o kuralı Prometheus'un kendi alerting katmanında çalıştırırsınız (edge cluster'da PrometheusRule manifest'i ile) ve direkt page yapar.
Alertmanager + silence'lar
Firing alert'ler Grafana'nın bundle'lı Alertmanager'ına gider, bu notification routing katmanıdır. Silence'lar (zaman bağlı mute'lar) Alertmanager feature'ıdır, DT Edge Platform'un değil. DT Edge Platform'un kendi silence UI'ı yok — firing list'ten "Open in Grafana" tıklayıp orada silence oluşturursunuz.
Bu bölmenin iki sebebi:
- Silence'lar doğal olarak bir notification window'a bağlıdır ("şu önümüzdeki 2 saat boyunca bu migration sırasında konuşma"). DT Edge Platform'un görünümü kural-merkezli, silence-merkezli değil.
- Alertmanager silence'ları zaten iyi yapar. Onları DT Edge Platform'da yeniden uygulamak no win için mükemmel bir feature'ı re-skinning olur.
Bir alarm-receiving sistem ne görür
Alertmanager'ı bir paging sistemine wire ettiyseniz (PagerDuty / Opsgenie / Slack / özel webhook), payload kuralın label'larını içerir. Yani:
dtedge_managed=true— sadece DT Edge Platform alarmlarını istiyorsanız bunu filtreleyin (örn: o'ları bir kanala, manuel alarmları diğerine gönder)dtedge_org_id=<uuid>— per-team kanallarına per-org routeseverity=...— severity'ye göre farklı escalation path'lere route
dtedge_org_id receiver'a opaque'tır — UUID, friendly name
değil. Page metninde okunabilir org adlarına ihtiyacınız varsa
Alertmanager config'inizde (veya downstream router'da) küçük bir
mapping kurun.
Ayrıca bakın
- Nasıl yapılır: alarmları yönet
- Nasıl yapılır: aktif alarmları görüntüle
- Eğitim 3 — İlk alarmınızı kurun
- Backend docs: Concept → Alarms