Ana içeriğe geç

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 eder
  • dtedge_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ı:

  1. 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).
  2. 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.
  3. 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:

  1. 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.
  2. 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 route
  • severity=... — 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​