Sunucu izleme (monitoring), sunucunuzun kaynak kullanımını ve servislerinin durumunu sürekli kaydedip eşikler aşıldığında sizi uyaran sistemdir. Amacı grafik biriktirmek değil, iki soruya hızlı cevap verebilmektir: “Şu an bir sorun var mı?” ve “Bu sorun ne zaman başladı?”
Bu rehberde önce anlık teşhis komutlarını gerçek çıktılarıyla ele alıyoruz, sonra sürekli izleme için Netdata, Prometheus + Grafana ve Uptime Kuma kurulumlarını adım adım kuruyoruz. Sonunda hangi metriğe hangi eşiği koymanız gerektiğini ve alarm kurmanın püf noktalarını bulacaksınız.
İzlenmesi Gereken Metrikler#
| Metrik | Neden önemli | Uyarı eşiği |
|---|---|---|
| CPU kullanımı | Sürekli tepe değer, kapasite sınırına yaklaşıldığını gösterir | %85 üzeri, 10 dakika sürekli |
| Yük ortalaması | CPU bekleyen süreç kuyruğunu gösterir | Çekirdek sayısının üzeri |
| Kullanılabilir bellek | Takas kullanımı başlarsa performans çöker | %15’in altına düşerse |
| Disk doluluğu | Dolu disk her şeyi durdurur | %80 uyarı, %90 kritik |
| Disk I/O bekleme (iowait) | Disk darboğazının en net göstergesi | %20 üzeri sürekli |
| Ağ trafiği | Ani sıçrama saldırı ya da sızıntı işareti olabilir | Normalin 3 katı |
| Servis durumu | Servis düştüğünde saniyeler içinde bilinmeli | Herhangi bir failed |
| Dışarıdan erişilebilirlik | Sunucu ayakta ama site açılmıyor olabilir | 2 ardışık başarısız kontrol |
| SSL sertifika süresi | Süresi dolan sertifika siteyi tamamen kapatır | 14 günden az kalınca |
Anlık Teşhis: Sunucuya Bağlanıp Bakmak#
Bir sorun bildirimi aldığınızda ilk yapacağınız iş sunucuya bağlanıp durumu görmektir. Aşağıdaki altı komut, sorunların büyük bölümünü teşhis eder.
htop — genel görünüm#
sudo apt install -y htop
htop
htop ekranının üst kısmındaki çekirdek çubukları renk kodludur: yeşil kullanıcı süreçleri, kırmızı çekirdek süreçleri, mavi düşük öncelikli işler. Kırmızının baskın olması genellikle I/O ya da ağ yoğunluğuna işaret eder. F6 ile sıralama ölçütünü, F9 ile süreç sonlandırmayı kullanabilirsiniz.
vmstat — sistem geneli özet#
vmstat 2 5
# Örnek çıktı:
# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
# r b swpd free buff cache si so bi bo in cs us sy id wa st
# 2 0 12288 1148236 412008 6182144 0 0 18 94 842 1503 14 3 82 1 0
# 1 1 12288 1141024 412008 6183992 0 0 0 612 980 1721 11 2 79 8 0
Bu çıktıda dikkat edilecek üç sütun var: r (çalışmayı bekleyen süreç sayısı), wa (CPU’nun disk beklemekle geçirdiği süre yüzdesi) ve si/so (takas alanına yazma/okuma). wa değeri sürekli çift haneliyse darboğaz CPU değil disktir. so sıfırdan büyükse RAM yetmiyordur.
iotop — hangi süreç diski meşgul ediyor?#
sudo apt install -y iotop
sudo iotop -o -a
# Örnek çıktı:
# Total DISK READ: 1.42 M/s | Total DISK WRITE: 18.94 M/s
# TID PRIO USER DISK READ DISK WRITE COMMAND
# 2041 be/4 minecraft 842.0 K 14.21 M java -Xms6G -Xmx6G -jar paper.jar
# 1108 be/4 mysql 612.0 K 4.02 M mariadbd
ss — ağ bağlantıları#
# Dinlenen portlar ve süreçler
sudo ss -tlnp
# Bağlantı durumu özeti
ss -s
# Total: 412
# TCP: 386 (estab 214, closed 128, orphaned 0, timewait 121)
# En çok bağlantı kuran IP'ler
ss -ntu state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
df ve du — disk#
df -h
# Filesystem Size Used Avail Use% Mounted on
# /dev/nvme0n1p2 196G 168G 19G 90% /
# %90 görüyorsanız kaynağı bulun
sudo du -h --max-depth=1 / | sort -hr | head -8
# 168G /
# 96G /var
# 41G /opt
# 18G /home
dmesg — çekirdek mesajları#
# Bellek yetersizliğinden öldürülen süreçler
sudo dmesg -T | grep -i "out of memory"
# Örnek çıktı:
# [Tue Aug 11 21:14:07 2026] Out of memory: Killed process 2041 (java)
# total-vm:12841024kB, anon-rss:8412208kB
# Disk hataları
sudo dmesg -T | grep -iE "i/o error|ata.*failed"
Bu komutların temel kullanımı ve daha fazlası için Linux temel komutları sayfasına bakabilirsiniz.
Netdata: Tek Sunucu İçin En Hızlı Çözüm#
Netdata, kurulumdan saniyeler sonra saniyelik çözünürlükte yüzlerce metriği web arayüzünde gösterir. Yapılandırma dosyası düzenlemenize gerek kalmadan CPU, bellek, disk, ağ, systemd servisleri ve varsa MySQL, Nginx, Redis gibi servisleri otomatik tespit eder.
# Resmî kurulum betiği
curl -fsSL https://get.netdata.cloud/kickstart.sh -o /tmp/netdata-kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel
# Servis durumu
sudo systemctl status netdata
# Varsayılan port 19999'da dinler
sudo ss -tlnp | grep 19999
# LISTEN 0 4096 0.0.0.0:19999 users:(("netdata",pid=5211,fd=6))
# Yalnızca yerel arayüzde dinlesin
sudo nano /etc/netdata/netdata.conf
# [web] bölümüne:
# bind to = 127.0.0.1
sudo systemctl restart netdata
# Sonra SSH tüneliyle güvenle erişin (kendi bilgisayarınızdan):
ssh -L 19999:localhost:19999 yonetici@203.0.113.45
# Tarayıcıda: http://localhost:19999
Alternatif olarak Nginx ters vekil arkasına alıp temel kimlik doğrulama ekleyebilir, güvenlik duvarında portu yalnızca kendi IP’nize açabilirsiniz. Kural yazımı için firewall yapılandırması sayfasına bakın.
Netdata alarmlarını Discord’a bağlama#
sudo nano /etc/netdata/health_alarm_notify.conf
# İlgili satırları düzenleyin:
# SEND_DISCORD="YES"
# DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
# DEFAULT_RECIPIENT_DISCORD="alarmlar"
# Test bildirimi gönder
sudo -u netdata /usr/libexec/netdata/plugins.d/alarm-notify.sh test
Uptime Kuma: Dışarıdan Erişilebilirlik Kontrolü#
Sunucu içi izleme bir şeyi gösteremez: sunucu tamamen erişilemez olduğunda kimse haber veremez. Bu yüzden dışarıdan kontrol yapan ayrı bir sistem gerekir. Uptime Kuma tam olarak bunu yapar ve ideal olarak izlediği sunucudan farklı bir yerde çalıştırılmalıdır.
# Docker ile kurulum (en pratik yol)
sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo docker run -d --restart=always \
-p 3001:3001 \
-v uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma:1
# Durumu kontrol et
sudo docker ps
# CONTAINER ID IMAGE STATUS PORTS
# 8c14a2f9d331 louislam/uptime-kuma:1 Up 2 minutes 0.0.0.0:3001->3001/tcp
Tarayıcıdan http://sunucu-ip:3001 adresine gidip yönetici hesabı oluşturun. Ardından ekleyeceğiniz kontroller:
| Kontrol tipi | Hedef | Aralık | Amaç |
|---|---|---|---|
| HTTP(s) | https://alanadiniz.com | 60 sn | Site açılıyor mu, durum kodu 200 mü |
| HTTP(s) — anahtar kelime | Ana sayfada belirli metin | 120 sn | Sayfa açılıyor ama boş dönüyorsa yakalar |
| TCP portu | sunucu:25565 | 60 sn | Minecraft sunucusu bağlantı kabul ediyor mu |
| TCP portu | mail.alanadiniz.com:993 | 300 sn | Posta servisi ayakta mı |
| Ping | Sunucu IP’si | 60 sn | Ağ erişilebilirliği ve gecikme |
| DNS | Alan adı A kaydı | 600 sn | DNS çözümlenmesi bozulduysa yakalar |
Prometheus ve Grafana: Çoklu Sunucu İzleme#
Birden fazla sunucu yönetiyorsanız her birine ayrı panel kurmak yerine metrikleri merkezî bir yerde toplamak gerekir. Prometheus metrikleri toplar ve saklar, Grafana bunları görselleştirir.
Node Exporter kurulumu (izlenecek her sunucuya)#
# Kullanıcı oluştur
sudo useradd --no-create-home --shell /bin/false node_exporter
# İkiliyi indirip yerleştirin (sürüm numarasını resmî sayfadan doğrulayın)
cd /tmp
tar xzf node_exporter-*.linux-amd64.tar.gz
sudo cp node_exporter-*/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
# /etc/systemd/system/node_exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network-online.target
Wants=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --web.listen-address=127.0.0.1:9100
Restart=always
RestartSec=5
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter
# Metriklerin üretildiğini doğrula
curl -s localhost:9100/metrics | head -5
# HELP go_gc_duration_seconds A summary of the wall-time pause duration
# TYPE go_gc_duration_seconds summary
# go_gc_duration_seconds{quantile="0"} 4.1204e-05
Prometheus yapılandırması (merkezî sunucuda)#
# /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "/etc/prometheus/kurallar/*.yml"
scrape_configs:
- job_name: 'sunucular'
static_configs:
- targets:
- '10.0.0.11:9100'
- '10.0.0.12:9100'
- '10.0.0.13:9100'
labels:
ortam: 'uretim'
- job_name: 'nginx'
static_configs:
- targets: ['10.0.0.11:9113']
Alarm kuralları#
# /etc/prometheus/kurallar/sunucu.yml
groups:
- name: sunucu-alarmlari
rules:
- alert: DiskDoluyor
expr: (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 85
for: 10m
labels:
severity: kritik
annotations:
summary: "{{ $labels.instance }} disk %85 üzerinde"
- alert: BellekAzaldi
expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 < 15
for: 5m
labels:
severity: uyari
annotations:
summary: "{{ $labels.instance }} kullanılabilir bellek %15 altında"
- alert: SunucuErisilemiyor
expr: up == 0
for: 2m
labels:
severity: kritik
annotations:
summary: "{{ $labels.instance }} 2 dakikadır yanıt vermiyor"
- alert: YuksekIOWait
expr: avg by (instance) (rate(node_cpu_seconds_total{mode="iowait"}[5m])) * 100 > 20
for: 10m
labels:
severity: uyari
annotations:
summary: "{{ $labels.instance }} disk beklemesi yüksek"
# Yapılandırmayı doğrula ve yeniden yükle
promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/kurallar/sunucu.yml
sudo systemctl reload prometheus
Dördü de ücretsiz ve açık kaynaktır. Kurulum betiklerini yalnızca resmî adreslerden alın; kaynağını doğrulamadığınız bir betiği sudo ile çalıştırmayın.
Log İzleme#
Metrikler “bir şey ters gitti” der, loglar “ne ters gitti” der. İkisi birlikte kullanılmalıdır.
# Servis loglarını canlı izle
sudo journalctl -u nginx -f
# Yalnızca hataları, son bir saatte
sudo journalctl -p err --since "1 hour ago" --no-pager
# Birden çok servisi birlikte izle
sudo journalctl -u nginx -u php8.3-fpm -u mariadb -f
# Belirli bir zaman aralığı (olay sonrası inceleme)
sudo journalctl --since "2026-08-11 21:00" --until "2026-08-11 22:00"
# Web sunucusunda 5xx hatalarını say
awk '$9 ~ /^5/ {print $9}' /var/log/nginx/access.log | sort | uniq -c
# 142 500
# 18 502
# 6 504
Log dosyalarının diski doldurmaması için döndürme (rotation) kurulu olmalıdır:
# /etc/logrotate.d/uygulama
/var/log/uygulama/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
systemctl reload uygulama > /dev/null 2>&1 || true
endscript
}
# Yapılandırmayı test et (gerçekten döndürmeden)
sudo logrotate -d /etc/logrotate.d/uygulama
# Zorla çalıştır
sudo logrotate -f /etc/logrotate.d/uygulama
Basit Kendi Kontrol Betiğiniz#
Tam bir izleme yığını kurmak istemiyorsanız, cron ile çalışan küçük bir betik bile büyük fark yaratır:
#!/bin/bash
# /usr/local/bin/kontrol.sh
set -uo pipefail
WEBHOOK="https://discord.com/api/webhooks/..."
ESIK_DISK=85
ESIK_BELLEK=15
bildir() {
curl -s -H "Content-Type: application/json" \
-d "{\"content\":\"$(hostname): $1\"}" "$WEBHOOK" > /dev/null
}
# Disk kontrolü
DISK=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK" -ge "$ESIK_DISK" ]; then
bildir "UYARI - kök disk %$DISK dolu"
fi
# Bellek kontrolü
BELLEK=$(free | awk '/Mem:/ {printf("%.0f", $7/$2 * 100)}')
if [ "$BELLEK" -le "$ESIK_BELLEK" ]; then
bildir "UYARI - kullanılabilir bellek %$BELLEK"
fi
# Kritik servisler
for servis in nginx mariadb; do
if ! systemctl is-active --quiet "$servis"; then
bildir "KRİTİK - $servis servisi çalışmıyor"
fi
done
# Yük ortalaması
CEKIRDEK=$(nproc)
YUK=$(awk '{print int($1)}' /proc/loadavg)
if [ "$YUK" -gt "$CEKIRDEK" ]; then
bildir "UYARI - yük ortalaması $YUK (çekirdek: $CEKIRDEK)"
fi
sudo chmod +x /usr/local/bin/kontrol.sh
# Her 5 dakikada bir çalıştır
sudo crontab -e
*/5 * * * * /usr/local/bin/kontrol.sh
Uygulamaya Özel İzleme#
Sistem metrikleri her şeyi anlatmaz. Sunucunuzun CPU’su rahat olabilir ama uygulamanız yine de kötü çalışıyor olabilir.
- Web: yanıt süresi (TTFB), 5xx hata oranı, PHP-FPM aktif süreç sayısı, veritabanı yavaş sorgu sayısı. Ölçüm yöntemleri site hızlandırma rehberinde.
- Minecraft: TPS değeri, kayıtlı oyuncu sayısı, chunk yükleme süresi, JVM heap kullanımı. Ayrıntılı analiz için spark ve timings raporu sayfası.
- Veritabanı: bağlantı sayısı, yavaş sorgu günlüğü, InnoDB tampon havuzu isabet oranı.
- Discord bot: yeniden başlatma sayacı, bellek eğrisi, API hız sınırı uyarıları. Servis kurulumu bot hosting rehberinde.
- Yedekleme: son yedeğin tarihi ve boyutu. Sessizce duran bir yedek görevi en tehlikeli arızadır: yedekleme stratejileri.
Alarm Kurmanın Kuralları#
-
Yalnızca müdahale gerektiren durumlara alarm koyun#
“CPU %60’a çıktı” bilgi notudur, alarm değil. Gereksiz uyarılar kanalı gürültüye boğar ve gerçek alarm gözden kaçar.
-
Süre koşulu ekleyin#
Anlık bir sıçrama sorun değildir.
for: 10mgibi bir koşul, geçici dalgalanmaların alarm üretmesini engeller. -
Seviyelendirin#
Uyarı ve kritik ayrımı yapın; ikisini farklı kanallara gönderin. Gece uyandıracak alarm yalnızca kritik olanlar olsun.
-
Alarmın nasıl çözüleceğini yazın#
Alarm mesajına kısa bir eylem notu ekleyin: “disk dolu —
/var/logkontrol et”. Gece yarısı bunu okuyan kişi (muhtemelen siz) teşekkür edecektir. -
Alarmları düzenli gözden geçirin#
Hiç tetiklenmeyen alarm belki yanlış yazılmıştır; sürekli tetiklenen alarm ya eşiği yanlıştır ya da çözülmesi gereken gerçek bir sorun vardır.
Özetle#
İzleme kurmanın en pratik yolu iki katmandır: sunucu içinde Netdata ile ayrıntılı metrik toplayın, dışarıda farklı bir makinede Uptime Kuma ile erişilebilirlik kontrolü yapın. Bu ikili, tek sunuculu kurulumların neredeyse tüm ihtiyacını karşılar. Birden çok sunucu yönetiyorsanız Prometheus + Grafana kombinasyonuna geçin.
Hangi aracı seçerseniz seçin üç şeyi atlamayın: Netdata panelini internete açık bırakmayın, alarmları gerçekten göreceğiniz bir kanala gönderin ve dış kontrolü izlediğiniz sunucudan bağımsız bir yerde çalıştırın. Bir sorunu kullanıcılarınızdan önce fark etmek, müdahale süresini saatlerden dakikalara indirir — izlemenin tek amacı da budur.