n8n ile Sunucu İzleme ve Alarm Otomasyonu

Gecen yıl bir müşterimizin production ortamında disk doluluk alarmı gece 2’de tetiklendi. Alarm sistem yöneticisine e-posta attı, ama müşteri o gece e-postasını açmadı. Sabah 9’da uygulamalar çökmüş, loglar durmuş, veritabanı transaction’ları başarısız oluyordu. Klasik “alarm vardı ama kimse görüp işlem yapmadı” senaryosu. İşte bu tür vakaları yaşadıktan sonra n8n ile kurduğumuz izleme ve alarm otomasyonu sistemini paylaşmak istedim.

n8n Nedir ve Neden Sunucu İzlemede Kullanılır

n8n, açık kaynaklı bir iş akışı otomasyon aracıdır. Zapier veya Make’e benzer ama self-hosted çalışır, yani kendi sunucunuzda barındırırsınız. Bu özelliği, sistem yöneticileri için kritiktir: sunucu metrikleri, log verileri ve hassas altyapı bilgileri üçüncü taraf bulut servislerine gitmez.

Sunucu izleme konusunda n8n’i tercih etmemizin birkaç somut nedeni var. Birincisi, HTTP istekleri, SSH bağlantıları, veritabanı sorguları ve webhook’ları tek bir görsel arayüzde birleştirebilirsiniz. İkincisi, Prometheus, Grafana veya Zabbix gibi araçlarla entegrasyon kurabilirsiniz. Üçüncüsü ve en önemlisi, alarm mantığını kod yazmadan veya çok az kod yazarak oluşturabilirsiniz.

n8n’in sunucu izlemede tek başına yeterli olmadığını da belirtmek gerekir. Düşünün ki n8n de bir sunucuda çalışıyor ve o sunucu çökerse n8n de çöker. Bu yüzden n8n’i izleme sisteminin orkestratörü olarak konumlandırmak, birincil metrik toplayıcı olarak değil, daha sağlıklıdır.

Kurulum ve Temel Yapılandırma

Docker ile kurulum en pratik yaklaşım. Ayrı bir izleme sunucusuna kurmanızı öneririm, production sunucularınıza değil.

# docker-compose.yml
version: "3"
services:
  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=guclu_sifre_buraya
      - N8N_HOST=izleme.sirketiniz.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://izleme.sirketiniz.com/
      - GENERIC_TIMEZONE=Europe/Istanbul
      - TZ=Europe/Istanbul
    volumes:
      - ~/.n8n:/home/node/.root

docker-compose up -d

Timezone ayarını mutlaka yapın. Türkiye saatiyle çalışmazsanız alarm loglarında saat karışıklığı yaşarsınız ve bir olayı analiz ederken “bu alarm saat 14’te mi yoksa 17’de mi tetiklendi?” sorusuyla boğuşursunuz.

n8n arayüzüne ilk girişte credentials oluşturmanız gerekecek. Slack, Telegram, SMTP gibi bildirim kanallarını buradan tanımlayın. Bu credential’lar şifreli saklanır ve workflow içinde doğrudan referans edilir.

İlk Workflow: HTTP ile Servis Sağlık Kontrolü

En basit ve en değerli otomasyon, HTTP endpoint’lerinizin ayakta olup olmadığını periyodik olarak kontrol etmektir. n8n’de bir workflow şu node’lardan oluşur:

Cron Trigger –> HTTP Request –> IF (Durum Kodu Kontrolü) –> Slack/Telegram Bildirim

Cron node’unu her 5 dakikada bir çalışacak şekilde ayarlayın. HTTP Request node’unda endpoint URL’nizi girin, timeout değerini 10 saniye olarak belirleyin. IF node’unda şu koşulu kontrol edin:

// IF Node - Expression alanına yazılacak
{{ $json["statusCode"] !== 200 || $json["headers"]["x-response-time"] > 2000 }}

Bu ifade hem HTTP 200 olmayan durumları hem de 2 saniyeden uzun süren yanıtları yakalar. Yavaş yanıt veren bir servis teknik olarak “up” sayılabilir ama kullanıcı deneyimi açısından zaten problem var demektir.

Bildirim mesajını da anlamlı hazırlayın:

// Telegram Message node - Message alanı
🚨 *SERVİS ALARMI*

Servis: {{ $node["HTTP Request"].json["url"] }}
Durum: {{ $node["HTTP Request"].json["statusCode"] }}
Yanıt Süresi: {{ $node["HTTP Request"].json["headers"]["x-response-time"] }}ms
Zaman: {{ new Date().toLocaleString("tr-TR", {timeZone: "Europe/Istanbul"}) }}

@sysadmin-team dikkat!

Disk ve CPU Metriklerini Toplamak

Sunucu metriklerini n8n’e taşımanın birkaç yolu var. En temiz yöntem, her sunucuda küçük bir script çalıştırıp n8n webhook’una göndermek.

#!/bin/bash
# /usr/local/bin/server-metrics-reporter.sh
# Her 5 dakikada cron ile çalışır

N8N_WEBHOOK="https://izleme.sirketiniz.com/webhook/server-metrics"
HOSTNAME=$(hostname)

# Disk kullanımı (root partition)
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')

# CPU yükü (1 dakikalık ortalama)
CPU_LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d',' -f1 | tr -d ' ')

# RAM kullanımı (yüzde)
TOTAL_MEM=$(free | grep Mem | awk '{print $2}')
USED_MEM=$(free | grep Mem | awk '{print $3}')
MEM_USAGE=$(echo "scale=0; $USED_MEM * 100 / $TOTAL_MEM" | bc)

# Payload oluştur ve gönder
curl -s -X POST "$N8N_WEBHOOK" 
  -H "Content-Type: application/json" 
  -d "{
    "hostname": "$HOSTNAME",
    "disk_usage": $DISK_USAGE,
    "cpu_load": $CPU_LOAD,
    "mem_usage": $MEM_USAGE,
    "timestamp": "$(date -Iseconds)"
  }"
# Cron'a ekle
echo "*/5 * * * * root /usr/local/bin/server-metrics-reporter.sh" >> /etc/cron.d/n8n-metrics

n8n tarafında bu webhook’u karşılayan workflow şöyle çalışır: Webhook node’u veriyi alır, Switch node’u hostname’e göre farklı eşik değerleri uygular (database sunucunuz ile web sunucunuzun disk alarm eşiği farklı olabilir), ardından IF node’ları metrikler için kontrol yapar.

// Switch Node - Database sunucusu için disk eşiği farklı
// Condition: hostname === "db-server-01"
// True Branch: disk_usage > 70 (veritabanı sunucusunda erken alarm)
// False Branch: disk_usage > 85 (diğer sunucular)
{{ $json["disk_usage"] > 70 && $json["hostname"].includes("db") }}

Alarm Yorgunluğunu Önlemek: Throttling Mekanizması

Bu noktada bir itiraf yapayım: ilk kurduğumuzda her 5 dakikada bir alarm geldi ve ekip iki günde Telegram kanalını susturdu. Alarm yorgunluğu (alert fatigue) gerçek bir problemdir ve çözümü throttling mekanizması kurmaktır.

n8n’de bunu yapmanın pratik yolu, bir SQLite veya PostgreSQL veritabanında son alarm zamanını tutmak ve aynı alarm için belirli süre geçmeden tekrar bildirim göndermemektir.

// Function Node - Alarm throttling kontrolü
const alarmKey = `alarm_${$json["hostname"]}_${$json["alarm_type"]}`;
const lastAlarmTime = $node["Database"].json[0]?.last_alarm_time;
const now = new Date().getTime();
const throttleMs = 30 * 60 * 1000; // 30 dakika

if (lastAlarmTime && (now - new Date(lastAlarmTime).getTime()) < throttleMs) {
  // 30 dakika geçmemiş, alarm gönderme
  return [{ json: { should_notify: false, reason: "throttled" } }];
}

return [{ json: { should_notify: true, alarm_key: alarmKey } }];

Bu mantıkla aynı sunucu için aynı alarm tipini 30 dakikada en fazla bir kez gönderirsiniz. Durum düzelirse (recovery) ise farklı bir bildirim yollanır, throttle uygulanmaz.

Log Dosyası Analizi ile Akıllı Alarm

Sunucu metriklerinin ötesinde, log dosyalarını analiz edip pattern bazlı alarm üretmek sistem yöneticiliğinde çok değer katar. Örneğin, nginx access log’unda 5 dakika içinde 100’den fazla 500 hatası görüldüğünde alarm vermek isteyebilirsiniz.

#!/bin/bash
# /usr/local/bin/log-analyzer.sh
# Her dakika çalışır

N8N_WEBHOOK="https://izleme.sirketiniz.com/webhook/log-analysis"
LOG_FILE="/var/log/nginx/access.log"
MINUTES_BACK=5

# Son 5 dakikadaki 500 hatalarını say
ERROR_COUNT=$(awk -v d="$(date -d "$MINUTES_BACK minutes ago" '+%d/%b/%Y:%H:%M')" 
  '$0 ~ d {count++} END {print count+0}' "$LOG_FILE")

# Son 5 dakikadaki benzersiz IP sayısı (DDoS tespiti için)
UNIQUE_IPS=$(awk -v d="$(date -d "$MINUTES_BACK minutes ago" '+%d/%b/%Y:%H:%M')" 
  '$0 ~ d {print $1}' "$LOG_FILE" | sort -u | wc -l)

# Failed login denemelerini kontrol et (auth.log)
FAILED_LOGINS=$(grep "Failed password" /var/log/auth.log | 
  grep "$(date '+%b %e %H:%M' -d '5 minutes ago')" | wc -l)

curl -s -X POST "$N8N_WEBHOOK" 
  -H "Content-Type: application/json" 
  -d "{
    "hostname": "$(hostname)",
    "nginx_500_errors": $ERROR_COUNT,
    "unique_ips": $UNIQUE_IPS,
    "failed_ssh_logins": $FAILED_LOGINS,
    "window_minutes": $MINUTES_BACK
  }"

n8n workflow’unda bu verileri aldıktan sonra birden fazla IF node’u paralel çalıştırabilirsiniz: biri 500 hataları için, biri DDoS benzeri trafik paterni için, biri brute force tespiti için. Her biri farklı öncelikte farklı kanallara bildirim gönderir.

// DDoS şüphesi tespiti için Function Node
const uniqueIps = $json["unique_ips"];
const errorCount = $json["nginx_500_errors"];

// 5 dakikada 500'den fazla benzersiz IP ve yüksek hata oranı
if (uniqueIps > 500 && errorCount > 200) {
  return [{
    json: {
      severity: "critical",
      alert_type: "possible_ddos",
      message: `DDoS şüphesi! ${uniqueIps} benzersiz IP, ${errorCount} hata - 5 dakika içinde`,
      action_required: "IP engelleme ve CDN korumasını devreye al"
    }
  }];
}

return [{ json: { severity: "none" } }];

Çoklu Kanal Bildirim Stratejisi

Farklı kritiklik seviyesi için farklı bildirim kanalı kullanmak, alarm yönetimini ciddi oranda iyileştirir. Bizim uyguladığımız strateji şu şekilde:

  • Info seviyesi: Yalnızca Slack kanalına yazılır, kimse uyandırılmaz
  • Warning seviyesi: Slack + Telegram grup mesajı
  • Critical seviyesi: Slack + Telegram + SMS (Twilio üzerinden) + nöbetçi telefon araması
  • Recovery bildirimleri: Yalnızca Slack, yeşil emoji ile

n8n’de bu stratejiyi Switch node’u ile uygulayabilirsiniz. Switch node’u severity alanına göre farklı branch’lara yönlendirir, her branch kendi bildirim node’larını içerir.

Twilio SMS entegrasyonu için n8n’in yerleşik Twilio node’u var. Ama dikkat: kritik alarm başına SMS maliyeti oluşur. Throttling olmadan bu entegrasyonu açmayın.

// Twilio node için mesaj şablonu
// "To" alanı: nöbetçi kişinin telefon numarası
// Bu bilgiyi ayrı bir Google Sheet'ten veya veritabanından çekin
// Böylece nöbetçi rotasyonunu n8n dışında yönetebilirsiniz

`ACIL: ${$json["hostname"]} sunucusunda kritik alarm!
Tür: ${$json["alarm_type"]}
Detay: ${$json["message"]}
n8n Dashboard: https://izleme.sirketiniz.com`

Otomatik İyileştirme Aksiyonları

İzlemenin ötesine geçip bazı sorunları otomatik olarak çözmek de mümkün. Dikkatli olmak gerekiyor, her sorun için otomatik müdahale doğru değil. Ama bazı tekrarlayan, iyi anlaşılmış sorunlar için faydalı.

Örnek: Disk doluluk alarmı geldiğinde önce log temizliği yapmak.

#!/bin/bash
# n8n'den SSH ile tetiklenen script
# /usr/local/bin/disk-cleanup.sh

LOG_DIR="/var/log"
APP_LOG_DIR="/opt/uygulama/logs"

# 30 günden eski logları sil
find "$LOG_DIR" -name "*.log.*" -mtime +30 -delete
find "$APP_LOG_DIR" -name "*.log" -mtime +30 -delete

# journald log boyutunu sınırla
journalctl --vacuum-size=500M

# Docker kullanılıyorsa kullanılmayan imajları temizle
if command -v docker &> /dev/null; then
  docker image prune -f --filter "until=720h"
  docker volume prune -f
fi

# Yeni disk kullanımını rapor et
DISK_AFTER=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
echo "{"disk_after_cleanup": $DISK_AFTER, "hostname": "$(hostname)"}"

n8n’de bu scripti SSH node’u ile çalıştırabilirsiniz. SSH node’una sunucu IP’si, kullanıcı adı ve private key bilgilerini girin. Script çıktısını alıp temizlik öncesi ve sonrası disk kullanımını karşılaştırın, sonucu Slack’e bildirin.

Önemli kural: Otomatik aksiyonları yalnızca idempotent ve geri alınabilir işlemler için uygulayın. Otomatik sunucu yeniden başlatma, uygulama durdurma gibi işlemleri asla otomasyona bırakmayın.

Prometheus Entegrasyonu

Ortamınızda Prometheus varsa n8n onu doğrudan sorgulayabilir. Prometheus HTTP API’si üzerinden PromQL sorguları çalıştırabilirsiniz.

// HTTP Request Node - Prometheus PromQL sorgusu
// URL: http://prometheus:9090/api/v1/query
// Method: GET
// Query Parameters:
//   query: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100 < 15

// Response'u parse eden Function Node
const result = $json["data"]["result"];

if (result.length === 0) {
  return [{ json: { alert: false } }];
}

const alerts = result.map(item => ({
  instance: item.metric.instance,
  available_percent: parseFloat(item.value[1]).toFixed(2),
  alert: true,
  severity: parseFloat(item.value[1]) < 5 ? "critical" : "warning"
}));

return alerts.map(a => ({ json: a }));

Bu yaklaşımla Prometheus’un ürettiği metrikleri n8n workflow’larında kullanabilir, Grafana alarm kurallarıyla çakışmadan ek otomasyon katmanı oluşturabilirsiniz.

Nöbetçi Rotasyonu Otomasyonu

Ekibiniz büyüdüğünde kimin alarm alacağını yönetmek ayrı bir sorun haline gelir. n8n’de bunu Google Sheets veya Notion ile entegre ederek çözebilirsiniz.

Her haftanın başında Google Sheets’ten o haftaki nöbetçi bilgisini çekip bir n8n değişkenine yazın. Critical alarm geldiğinde sistem otomatik olarak o kişinin iletişim bilgisine bildirim gönderir. Nöbetçi değişikliği için hiçbir workflow konfigürasyonu güncellenmez, sadece Google Sheets güncellenir.

// Google Sheets'ten nöbetçi bilgisi çeken Function Node
const rows = $json["values"];
const today = new Date();
const weekNumber = Math.ceil((today - new Date(today.getFullYear(), 0, 1)) / 604800000);

// Her satır bir hafta, sütunlar: hafta_no, isim, telefon, telegram_id
const oncallRow = rows.find(row => parseInt(row[0]) === weekNumber);

if (!oncallRow) {
  return [{ json: { error: "Bu hafta için nöbetçi tanımlanmamış!" } }];
}

return [{
  json: {
    oncall_name: oncallRow[1],
    oncall_phone: oncallRow[2],
    oncall_telegram: oncallRow[3],
    week: weekNumber
  }
}];

Workflow Test ve Hata Ayıklama

n8n’in en güçlü özelliklerinden biri, workflow’ları test etme kolaylığı. Her node’u ayrı ayrı çalıştırabilir, çıktısını inceleyebilirsiniz. Production’a almadan önce şu kontrolleri yapın:

  • Manuel tetikleme ile tüm dalları test edin, özellikle alarm ve recovery path’lerini
  • Hatalı JSON geldiğinde (sunucu ulaşılamaz, script hata verdi) workflow nasıl davranıyor kontrol edin
  • Error workflow tanımlayın: ana workflow’da beklenmedik hata olursa bu devreye girer ve sizi bilgilendirir
  • n8n arayüzünde Executions sekmesinden geçmiş çalışmaları inceleyebilirsiniz
# Webhook endpoint'ini test etmek için
curl -X POST "https://izleme.sirketiniz.com/webhook-test/server-metrics" 
  -H "Content-Type: application/json" 
  -d '{
    "hostname": "test-server",
    "disk_usage": 92,
    "cpu_load": 0.5,
    "mem_usage": 45,
    "timestamp": "2024-01-15T14:30:00+03:00"
  }'

Webhook URL’deki /webhook-test/ path’ini dikkat edin. n8n production’da /webhook/ kullanır ama test modunda /webhook-test/ endpoint’i aktif olur ve workflow tetiklemeden önce test etmenize izin verir.

Sonuç

n8n ile sunucu izleme otomasyonu kurmak, klasik monitoring araçlarının yerini almaz ama onların üstüne akıllı otomasyon ve orkestrasyon katmanı ekler. Yazıda ele aldığımız yapıyla şunları elde edersiniz:

  • HTTP servis sağlık kontrolü ile uptime takibi
  • Sunucu metrikleri (disk, CPU, RAM) için webhook tabanlı veri toplama
  • Log analizi ile pattern bazlı alarm üretimi
  • Throttling mekanizması sayesinde alarm yorgunluğunun önlenmesi
  • Kritiklik seviyesine göre çok kanallı bildirim stratejisi
  • Basit sorunlar için otomatik iyileştirme aksiyonları
  • Nöbetçi rotasyonunun otomatik yönetimi

Başlangıç için öneri: ilk workflow’u basit tutun. Bir servisin HTTP kontrolünü yapın, Telegram’a mesaj atın, çalıştırın. Sistem kendini kanıtladıkça karmaşıklığı artırın. En büyük hata, sıfırdan çok kapsamlı bir sistem kurmaya çalışmak ve yarıda bırakmaktır.

n8n community forumunda Türkçe içerik hâlâ az, bu yüzden yaşadığınız sorunları ve çözümleri paylaşmaktan çekinmeyin. Herkesin kendi altyapısı için birbirinden öğrendiği bir ekosistem bu işi çok daha kolaylaştırıyor.

Bir yanıt yazın

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