InfluxDB ile Uyarı Sistemi: Kapacitor Kullanımı

Monitoring sistemleri kurarken en sık yapılan hata, veriyi toplamak ama üzerine aksiyon almamaktır. InfluxDB ile metriklerinizi güzelce saklıyorsunuz, Grafana ile harika dashboardlar yapıyorsunuz, ama gece 3’te disk dolduğunda sizi kim uyaracak? İşte tam bu noktada Kapacitor devreye giriyor.

Kapacitor, InfluxDB’nin resmi stream ve batch veri işleme motorudur. TICKscript adı verilen kendine özgü bir dil kullanır ve bu sayede gerçek zamanlı anomali tespiti, uyarı gönderimi ve hatta otomatik düzeltme aksiyonları alabilirsiniz. Bu yazıda Kapacitor’u sıfırdan kurup, production ortamında işinize yarayacak gerçek uyarı senaryoları yazacağız.

Kapacitor Nedir ve TICK Stack İçindeki Yeri

TICK Stack dört bileşenden oluşur: Telegraf (veri toplama), InfluxDB (depolama), Chronograf (görselleştirme) ve Kapacitor (işleme ve uyarı). Kapacitor bu zincirin son halkasıdır ve en çok göz ardı edilen parçasıdır.

Kapacitor iki modda çalışır:

  • Stream modu: InfluxDB’ye gelen veriyi gerçek zamanlı olarak işler, düşük gecikme ister
  • Batch modu: Belirli aralıklarla InfluxDB’ye sorgu atar ve sonuçları işler, daha az kaynak tüketir

Küçük ortamlar için batch modu yeterlidir. Saniyede binlerce metrik işliyorsanız stream modunu tercih edin.

Kurulum

Ubuntu/Debian Üzerinde Kurulum

# InfluxDB repository zaten ekliyse direkt kurabilirsiniz
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null

echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list

sudo apt-get update && sudo apt-get install kapacitor -y

CentOS/RHEL Üzerinde Kurulum

cat <<EOF | sudo tee /etc/yum.repos.d/influxdata.repo
[influxdata]
name = InfluxData Repository - Stable
baseurl = https://repos.influxdata.com/rhel/$releasever/$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive_compat.key
EOF

sudo yum install kapacitor -y
sudo systemctl enable kapacitor
sudo systemctl start kapacitor

Temel Yapılandırma

Kapacitor’un ana konfigürasyon dosyası /etc/kapacitor/kapacitor.conf adresindedir. En kritik kısımlar şunlardır:

# Temel ayarları düzenleyelim
sudo nano /etc/kapacitor/kapacitor.conf

Dosya içinde dikkat etmeniz gereken bölümler:

  • hostname: Kapacitor’un kendini tanımladığı isim, log takibi için önemli
  • data_dir: TICKscript ve task verilerinin tutulduğu dizin
  • [influxdb]]: InfluxDB bağlantı bilgileri, URL ve kimlik doğrulama
  • [smtp]: E-posta bildirimleri için SMTP ayarları
  • [slack]: Slack webhook entegrasyonu

Minimal bir InfluxDB bağlantısı şöyle görünür:

[[influxdb]]
  enabled = true
  name = "localdb"
  default = true
  urls = ["http://localhost:8086"]
  username = "kapacitor_user"
  password = "guclu_sifre_buraya"
  timeout = 0
  
[smtp]
  enabled = true
  host = "smtp.sirketiniz.com"
  port = 587
  username = "[email protected]"
  password = "smtp_sifresi"
  from = "[email protected]"
  to = ["[email protected]", "[email protected]"]
  no-verify = false
  global = false
  state-changes-only = true

Yapılandırmayı tamamlayıp servisi başlatın:

sudo systemctl restart kapacitor
sudo systemctl status kapacitor

# Bağlantıyı test edin
kapacitor list tasks

TICKscript Temelleri

TICKscript, zincirleme metodlar (method chaining) kullanır. Her satır bir öncekinin üzerine inşa edilir. Sözdizimi başta garip gelebilir ama mantığını kavradıktan sonra oldukça okunabilirdir.

Temel bir TICKscript şu akışla ilerler:

Veri Kaynağı -> Filtre -> Hesaplama -> Eşik Kontrolü -> Bildirim

İlk TICKscript: CPU Uyarısı

Şimdi gerçek bir senaryo yazalım. Diyelim ki CPU kullanımı 5 dakika boyunca %80’in üzerinde kalırsa uyarı almak istiyorsunuz:

// cpu_alert.tick
// Stream modu: Gerçek zamanlı CPU izleme

var db = 'telegraf'
var rp = 'autogen'
var measurement = 'cpu'
var groupBy = ['host', 'cpu']

var info = 80.0
var warn = 90.0
var crit = 95.0

stream
    |from()
        .database(db)
        .retentionPolicy(rp)
        .measurement(measurement)
        .groupBy(groupBy)
    |where(lambda: "cpu" == 'cpu-total')
    |eval(lambda: 100.0 - "usage_idle")
        .as('usage_active')
    |movingAverage('usage_active', 5)
        .as('moving_avg')
    |alert()
        .id('cpu_usage_{{ index .Tags "host" }}')
        .message('{{ .ID }}: CPU kullanimi {{ index .Fields "moving_avg" | printf "%.2f" }}% seviyesinde')
        .info(lambda: "moving_avg" > info)
        .warn(lambda: "moving_avg" > warn)
        .crit(lambda: "moving_avg" > crit)
        .stateChangesOnly()
        .email()
        .slack()
        .log('/var/log/kapacitor/cpu_alerts.log')

Bu scripti Kapacitor’a yükleyin ve aktif edin:

# Task oluştur
kapacitor define cpu_alert 
    -type stream 
    -tick cpu_alert.tick 
    -dbrp telegraf.autogen

# Task'ı etkinleştir
kapacitor enable cpu_alert

# Durumunu kontrol et
kapacitor show cpu_alert

Disk Doluluk Uyarısı: Batch Mod

CPU örneği stream modundaydı. Şimdi batch modunda disk izleme yapalım. Disk doluluk kontrolü her dakika sorgulamayı gerektirmez, 5 dakikada bir yeterlidir:

// disk_alert.tick
// Batch modu: 5 dakikada bir disk kontrolü

var info = 75.0
var warn = 85.0
var crit = 90.0

batch
    |query('''
        SELECT mean("used_percent") AS "used_percent"
        FROM "telegraf"."autogen"."disk"
        WHERE time > now() - 5m
        AND "fstype" != 'tmpfs'
        AND "fstype" != 'devtmpfs'
    ''')
        .period(5m)
        .every(5m)
        .groupBy('host', 'path')
    |alert()
        .id('disk_{{ index .Tags "host" }}_{{ index .Tags "path" }}')
        .message('DISK UYARISI: {{ index .Tags "host" }} sunucusunda {{ index .Tags "path" }} yolu {{ index .Fields "used_percent" | printf "%.1f" }}% dolu!')
        .info(lambda: "used_percent" > info)
        .warn(lambda: "used_percent" > warn)
        .crit(lambda: "used_percent" > crit)
        .stateChangesOnly()
        .email('[email protected]')
        .victorOps()
        .log('/var/log/kapacitor/disk_alerts.log')
kapacitor define disk_alert 
    -type batch 
    -tick disk_alert.tick 
    -dbrp telegraf.autogen

kapacitor enable disk_alert

Slack Entegrasyonu ve Özelleştirme

Slack muhtemelen en çok kullanılan bildirim kanalıdır. Kapacitor’da Slack’i konfigürasyon dosyasında aktif edin:

[slack]
  enabled = true
  default = true
  workspace = "sirketiniz"
  url = "https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYY/ZZZZZZZZZZ"
  channel = "#alerts"
  username = "Kapacitor"
  icon-emoji = ":warning:"
  global = false
  state-changes-only = true

Şimdi Slack mesajını özelleştiren gelişmiş bir örnek yazalım. Bu sefer web sunucusu yanıt süresini izleyeceğiz:

// web_response_alert.tick
// HTTP yanıt süresi izleme

var warnThreshold = 1000.0   // 1 saniye
var critThreshold = 3000.0   // 3 saniye

stream
    |from()
        .database('telegraf')
        .retentionPolicy('autogen')
        .measurement('http_response')
        .groupBy('host', 'server')
    |eval(lambda: "response_time" * 1000)
        .as('response_ms')
    |alert()
        .id('web_response_{{ index .Tags "host" }}_{{ index .Tags "server" }}')
        .message('''
:rotating_light: *Web Sunucu Uyarisi*
*Sunucu:* {{ index .Tags "server" }}
*Host:* {{ index .Tags "host" }}
*Yanit Suresi:* {{ index .Fields "response_ms" | printf "%.0f" }} ms
*Seviye:* {{ .Level }}
*Zaman:* {{ .Time }}
        ''')
        .warn(lambda: "response_ms" > warnThreshold)
        .crit(lambda: "response_ms" > critThreshold)
        .stateChangesOnly()
        .slack()
            .channel('#web-alerts')

Deadman: Veri Gelmediğinde Uyarı

Bu özellik çok az sysadmin tarafından kullanılır ama son derece değerlidir. Telegraf ajanı çöktüğünde veya sunucu erişilemez olduğunda veri gelmeyi durdurur. Deadman check tam olarak bu durumu yakalar:

// deadman_check.tick
// Sunucudan veri gelmezse uyar

var period = 5m
var every = 1m

stream
    |from()
        .database('telegraf')
        .retentionPolicy('autogen')
        .measurement('cpu')
        .groupBy('host')
    |deadman(0.0, period)
        .message('KRITIK: {{ index .Tags "host" }} sunucusundan {{ .Period }} suredir veri gelmiyor! Sunucu down olabilir.')
        .email('[email protected]')
        .slack()
            .channel('#critical-alerts')
        .log('/var/log/kapacitor/deadman.log')

Bu scripti yükleyip aktif ettikten sonra, herhangi bir sunucunuzdan veri gelmesi durduğunda 5 dakika içinde uyarı alırsınız. Gecenin 3’ünde sunucu çöktüğünde hayat kurtarıcı olduğunu söylesem abartı olmaz.

Anomali Tespiti: Sigma Yöntemi

Statik eşikler bazen yetersiz kalır. Örneğin, bir e-ticaret sitesinde Cuma akşamları trafik normalde yüksektir ama Salı sabahı aynı trafik anomali sayılabilir. Kapacitor’un istatistiksel yöntemleri burada devreye girer:

// anomaly_detection.tick
// Sigma tabanlı anomali tespiti

var period = 1h
var every = 5m
var sigma = 3.0

stream
    |from()
        .database('telegraf')
        .retentionPolicy('autogen')
        .measurement('requests')
        .groupBy('host', 'endpoint')
    |window()
        .period(period)
        .every(every)
    |stddev('count')
        .as('stddev')
    |mean('count')
        .as('mean')
    |eval(lambda: abs("count" - "mean") / "stddev")
        .as('sigma_value')
        .keep('count', 'mean', 'stddev', 'sigma_value')
    |alert()
        .id('anomaly_{{ index .Tags "host" }}_{{ index .Tags "endpoint" }}')
        .message('''
Anomali Tespit Edildi!
Endpoint: {{ index .Tags "endpoint" }}
Sunucu: {{ index .Tags "host" }}
Mevcut Deger: {{ index .Fields "count" }}
Beklenen Ortalama: {{ index .Fields "mean" | printf "%.2f" }}
Sigma Degeri: {{ index .Fields "sigma_value" | printf "%.2f" }}
        ''')
        .warn(lambda: "sigma_value" > sigma)
        .crit(lambda: "sigma_value" > sigma * 1.5)
        .stateChangesOnly()
        .slack()

Task Yönetimi ve Hata Ayıklama

Kapacitor CLI, task yönetimi için oldukça güçlüdür. Günlük operasyonlarda işinize yarayacak komutlar:

# Tüm taskları listele
kapacitor list tasks

# Belirli bir taskın detaylarını gör
kapacitor show cpu_alert

# Taskı geçici olarak devre dışı bırak
kapacitor disable cpu_alert

# Taskı sil
kapacitor delete tasks cpu_alert

# Task istatistiklerini görüntüle
kapacitor stats ingress

# Kapacitor log seviyesini geçici değiştir (hata ayıklama için)
kapacitor level debug

# Recording ile test yap
# Önce 30 saniyelik veri kaydet
kapacitor record stream 
    --task cpu_alert 
    --duration 30s

# Kaydedilen veriyi listele
kapacitor list recordings

# Kaydı replay et (test amaçlı)
kapacitor replay 
    --recording <recording-id> 
    --task cpu_alert 
    --real-clock

Recording ve replay özelliği production’a geçmeden önce TICKscriptlerinizi test etmenin en güvenli yoludur. Gerçek veriyi kaydedip tekrar tekrar çalıştırabilirsiniz.

Uyarı Yorgunluğunu Önlemek

Sysadminlerin en büyük düşmanlarından biri “alert fatigue”, yani uyarı yorgunluğudur. Her küçük dalgalanmada e-posta atılırsa, zamanla uyarılar görmezden gelinmeye başlar. Kapacitor’da bunu önlemenin birkaç yolu vardır:

  • stateChangesOnly(): Sadece durum değiştiğinde bildir, aynı durumda tekrar bildirim yapma
  • inhibit(): Bir uyarı aktifken başka uyarıları bastır
  • flapping(): Hızlı açılıp kapanan (flapping) uyarıları filtrele
// anti_fatigue_example.tick
// Uyarı yorgunluğunu önleme teknikleri

stream
    |from()
        .database('telegraf')
        .measurement('mem')
        .groupBy('host')
    |eval(lambda: 100.0 - "available_percent")
        .as('used_percent')
    |alert()
        .id('memory_{{ index .Tags "host" }}')
        .message('Bellek kullanimi: {{ index .Fields "used_percent" | printf "%.1f" }}%')
        .warn(lambda: "used_percent" > 80.0)
        .crit(lambda: "used_percent" > 90.0)
        .stateChangesOnly()         // Sadece durum degistiginde bildir
        .flapping(0.25, 0.50)       // Flapping tespiti aktif
        .email()
        .slack()

Kapacitor REST API Kullanımı

Eğer otomasyon scriptleri yazıyorsanız, Kapacitor’un REST API’sini tercih edebilirsiniz. Özellikle CI/CD pipeline’larında alert kurallarını otomatik deploy etmek için idealdir:

# Tüm taskları API ile listele
curl -G http://localhost:9092/kapacitor/v1/tasks

# Yeni task oluştur
curl -X POST http://localhost:9092/kapacitor/v1/tasks 
  -H 'Content-Type: application/json' 
  -d '{
    "id": "cpu_alert_api",
    "type": "stream",
    "dbrps": [{"db": "telegraf", "rp": "autogen"}],
    "script": "streamn    |from()n        .database("telegraf")n        .measurement("cpu")n    |alert()n        .crit(lambda: "usage_user" > 90)n        .email()n",
    "status": "enabled"
  }'

# Task durumunu değiştir
curl -X PATCH http://localhost:9092/kapacitor/v1/tasks/cpu_alert_api 
  -H 'Content-Type: application/json' 
  -d '{"status": "disabled"}'

# Alert geçmişini sorgula
curl -G http://localhost:9092/kapacitor/v1/alerts/topics

Production Ortamı İçin Tavsiyeler

Kapacitor’u canlı ortamda kullanırken dikkat etmeniz gereken birkaç önemli nokta var:

  • Kaynak yönetimi: Her stream task bir goroutine başlatır. Yüzlerce task çalıştırıyorsanız bellek tüketimine dikkat edin. Mümkün olduğunda batch modunu tercih edin.
  • Log rotasyonu: Kapacitor alert logları hızla büyür. /etc/logrotate.d/kapacitor dosyası oluşturup düzenli rotasyon yapılandırın.
  • Yedekleme: /var/lib/kapacitor dizinini yedekleme planınıza dahil edin. Tüm task tanımları burada saklanır.
  • Versiyon kontrolü: TICKscriptlerinizi Git reposunda tutun. Bir şeyler ters giderse kolayca geri dönebilirsiniz.
  • Ortam değişkenleri: Şifre ve webhook URL gibi hassas bilgileri konfigürasyon dosyasına gömmeyin. Kapacitor ortam değişkenlerini destekler: ${SLACK_WEBHOOK_URL} şeklinde kullanabilirsiniz.
  • Monitoring the monitor: Kapacitor’un kendisini de izleyin. /kapacitor/v1/debug/vars endpoint’i Prometheus formatında metrik sunar.

Sonuç

Kapacitor, InfluxDB ekosisteminin en güçlü ama en az kullanılan parçasıdır. CPU ve disk uyarılarından başlayıp, deadman check ile sunucu erişilebilirlik tespitine, oradan sigma tabanlı anomali algılamaya kadar geniş bir yelpazede kullanılabilir.

Bu yazıda anlattıklarımı uygulamak için önerdiğim sıra şudur: Önce disk ve CPU için basit batch mode uyarıları kurun ve bunların düzgün çalıştığından emin olun. Sonra deadman check ekleyin. Ortam stabilize oldukça daha karmaşık anomali tespiti kuralları ekleyebilirsiniz. stateChangesOnly() kullanmayı alışkanlık haline getirin, gelen uyarı sayısını dramatik biçimde azaltır.

TICKscript sözdizimi ilk başta garip gelebilir ama birkaç senaryo yazdıktan sonra oldukça doğal hale geliyor. Kapacitor 2.x ile birlikte Flux dili desteği de geldi, ama production ortamları için TICKscript hala daha stabil ve yaygın kullanılan seçenek olmayı sürdürüyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir