ELK Stack Sorun Giderme: Yaygın Hatalar ve Çözümler
Üretim ortamında ELK stack çalıştırmak, bir noktada mutlaka “neden çalışmıyor ki bu?” sorusunu sormak anlamına geliyor. Elasticsearch dizin kilitlenmesinden Logstash pipeline donmalarına, Kibana görselleştirme hatalarından Beats bağlantı sorunlarına kadar her şey beklenmedik anlarda patlıyor. Bu yazıda gerçek üretim ortamlarında karşılaştığım ve çözümlerini bulmak için saatler harcadığım sorunları ele alacağım.
Elasticsearch: En Sık Karşılaşılan Kritik Hatalar
Cluster Durumu Red veya Yellow Olduğunda
Sabah geliyorsun, Kibana açmıyorsun, Elasticsearch cluster health kontrolü yapıyorsun ve karşında kırmızı bir durum var. Paniğe gerek yok, önce durumu tam olarak anla.
# Cluster health detaylı kontrol
curl -X GET "localhost:9200/_cluster/health?pretty&level=indices"
# Hangi shardlar sorunlu?
curl -X GET "localhost:9200/_cluster/allocation/explain?pretty"
# Tüm node bilgilerini gör
curl -X GET "localhost:9200/_cat/nodes?v&h=name,node.role,heap.percent,disk.used_percent,cpu"
Red durum genellikle şu anlama gelir: primary shardlardan biri atanamamış. Yellow ise replica shardlar atanamamış demek. Yellow durum tek node’lu bir kurulumda normaldir çünkü replica’yı yerleştirecek başka node yok.
Eğer disk doluluk oranı yüzde 85’i geçmişse Elasticsearch otomatik olarak yeni index yazımını engeller. Buna flood stage watermark deniyor.
# Disk watermark sorununu geçici olarak bypass et (dikkatli kullan)
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "97%"
}
}'
# Eski indexleri temizledikten sonra watermark'ı sıfırla
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": null,
"cluster.routing.allocation.disk.watermark.high": null,
"cluster.routing.allocation.disk.watermark.flood_stage": null
}
}'
Heap Memory Sorunları ve OutOfMemoryError
Elasticsearch’ün en sevmediğim yanı bu: yeterince bellek vermezsen çöküyor, çok fazla bellek verirsen GC pause’ları yüzünden yine çöküyor. Altın kural, heap boyutunu sistem RAM’inin yarısına ayarlamak ve 31GB’ı asla geçmemek. 31GB sınırının üzerinde JVM’nin compressed ordinary object pointers (compressed OOPs) özelliği devre dışı kalıyor ve performans dramatik şekilde düşüyor.
# /etc/elasticsearch/jvm.options dosyasını düzenle
# 16GB RAM'li sunucu için:
-Xms8g
-Xmx8g
# Mevcut heap kullanımını kontrol et
curl -X GET "localhost:9200/_cat/nodes?v&h=name,heap.current,heap.percent,heap.max"
# GC istatistiklerini izle
curl -X GET "localhost:9200/_nodes/stats/jvm?pretty" | grep -A5 "gc"
Sürekli heap sorunu yaşıyorsan field data cache’i kontrol et. Kibana’da çok fazla aggregation yapılıyorsa field data cache şişiyor olabilir.
# Field data cache kullanımını gör
curl -X GET "localhost:9200/_stats/fielddata?pretty&fields=*"
# Field data cache'i temizle (dikkat: bu operasyon yük yaratır)
curl -X POST "localhost:9200/_cache/clear?fielddata=true"
Index Yönetimi ve Mapping Sorunları
Üretimde sık yaşanan bir senaryo: geliştiriciler yeni bir log formatı ekliyor, Elasticsearch field type’ları otomatik algılıyor ve bir field’ı önce string, sonra integer olarak map etmeye çalışıyor. Bu durumda mapping conflict hatası alırsın ve yeni belgeler indexlenemez.
# Mevcut mapping'i kontrol et
curl -X GET "localhost:9200/logstash-*/_mapping?pretty"
# Sorunlu field'ı bul
curl -X GET "localhost:9200/logstash-2024.01.15/_mapping/field/status_code?pretty"
# Yeni index için doğru mapping tanımla
curl -X PUT "localhost:9200/_index_template/logstash-template" -H 'Content-Type: application/json' -d'
{
"index_patterns": ["logstash-*"],
"template": {
"mappings": {
"properties": {
"status_code": {
"type": "integer"
},
"@timestamp": {
"type": "date"
}
}
}
}
}'
Logstash: Pipeline Sorunları ve Debug Teknikleri
Pipeline Başlamıyor veya Takılı Kalıyor
Logstash pipeline hatalarının büyük çoğunluğu konfigürasyon dosyasındaki syntax hatalarından kaynaklanıyor. Logstash’i production’da restart etmeden önce her zaman config test et.
# Konfigürasyon dosyasını test et
/usr/share/logstash/bin/logstash --config.test_and_exit -f /etc/logstash/conf.d/
# Logstash'i debug modunda başlat
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/ --log.level=debug
# Logstash API ile pipeline durumunu kontrol et
curl -X GET "localhost:9600/_node/pipelines?pretty"
# Pipeline istatistiklerini izle
curl -X GET "localhost:9600/_node/stats/pipelines?pretty"
Logstash’in en sinir bozucu özelliklerinden biri: bir pipeline takılıp kalırsa event’lar queue’da birikmeye başlar ve bir süre sonra disk dolar. Dead letter queue etkinleştirerek parse edilemeyen event’ların kaybolmasını önleyebilirsin.
# /etc/logstash/logstash.yml
dead_letter_queue.enable: true
dead_letter_queue.max_bytes: 1024mb
path.dead_letter_queue: /var/lib/logstash/dead_letter_queue
Grok Pattern Sorunları
Grok, Logstash’in en güçlü özelliği ama aynı zamanda en çok hata üretiyor. Yanlış pattern yazdığında event’lar _grokparsefailure tag’i alarak geçiyor ve arama sırasında hiçbir field bulamıyorsun.
# /etc/logstash/conf.d/nginx.conf - Nginx log örneği
filter {
grok {
match => {
"message" => "%{IPORHOST:client_ip} - %{USER:ident} [%{HTTPDATE:timestamp}] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}" %{NUMBER:response_code} %{NUMBER:bytes_sent}"
}
tag_on_failure => ["_grokparsefailure_nginx"]
}
# Parse başarısız olan event'ları logla
if "_grokparsefailure_nginx" in [tags] {
mutate {
add_field => { "parse_error" => "true" }
}
}
}
Grok pattern’ını production’a almadan önce [Grok Debugger](https://grokdebugger.com/) ile test et. Ama daha pratik yol, Kibana’nın içindeki Grok Debugger aracını kullanmak.
# Parse failure oranını izle
curl -X GET "localhost:9600/_node/stats/pipelines?pretty" | grep -A3 "filter"
# Belirli bir tag ile gelen event sayısını Elasticsearch'te sorgula
curl -X GET "localhost:9200/logstash-*/_count" -H 'Content-Type: application/json' -d'
{
"query": {
"term": {
"tags": "_grokparsefailure_nginx"
}
}
}'
Logstash Performans Sorunları
Logstash yavaşlıyorsa ilk bakacağın yer pipeline worker ve batch size ayarları olmalı. Varsayılan değerler çoğu durumda yetersiz kalıyor.
# /etc/logstash/logstash.yml
pipeline.workers: 4 # CPU core sayısına göre ayarla
pipeline.batch.size: 500 # Varsayılan 125, yüksek throughput için artır
pipeline.batch.delay: 50 # Milisaniye
queue.type: persisted # Memory yerine disk queue kullan
queue.max_bytes: 4gb
Filebeat ve Beats Ailesi: Bağlantı ve Gönderim Sorunları
Elasticsearch’e Bağlanamıyor
Filebeat kuruyorsun, başlatıyorsun, log dosyası büyüyor ama Elasticsearch’te hiç event görünmüyor. Bu durumda ilk yapman gereken Filebeat’in bağlantı durumunu kontrol etmek.
# Filebeat bağlantı testini çalıştır
filebeat test output
# Filebeat config doğrulama
filebeat test config -c /etc/filebeat/filebeat.yml
# Filebeat log'larını izle
journalctl -u filebeat -f
# Registry dosyasını kontrol et (hangi satıra kadar okundu)
cat /var/lib/filebeat/registry/filebeat/log.json | python3 -m json.tool
Yaygın bir sorun: Filebeat TLS ile bağlanmaya çalışıyor ama sertifika verify başarısız. Geliştirme ortamında hızlı çözüm olarak verification’ı devre dışı bırakabilirsin ama production’da bunu yapma.
# /etc/filebeat/filebeat.yml
output.elasticsearch:
hosts: ["https://elasticsearch:9200"]
username: "elastic"
password: "sifre"
ssl:
enabled: true
certificate_authorities: ["/etc/filebeat/certs/ca.crt"]
# Sadece test ortamı için:
# verification_mode: none
Filebeat Registry Bozulması
Sunucu aniden kapandığında Filebeat registry dosyası bozulabiliyor. Bu durumda Filebeat ya hiç başlamıyor ya da tüm log dosyalarını baştan okuyor ve Elasticsearch’e duplicate event’lar gönderiyor.
# Registry dosyasının durumunu kontrol et
filebeat -e -d "*" 2>&1 | head -50
# Registry'yi sıfırla (dikkat: tüm log'lar yeniden gönderilecek)
systemctl stop filebeat
rm -rf /var/lib/filebeat/registry
systemctl start filebeat
# Registry dosyasını backup al (önlem olarak)
cp -r /var/lib/filebeat/registry /var/lib/filebeat/registry.backup
Kibana: Görselleştirme ve Erişim Sorunları
Kibana Başlamıyor veya Çok Yavaş Açılıyor
Kibana açılmıyor diye şikayet geldiğinde genellikle iki sebep var: Elasticsearch’e ulaşamıyor ya da Kibana’nın kendi sistem kaynakları yetersiz.
# Kibana servis durumu
systemctl status kibana
# Kibana log'larını incele
journalctl -u kibana -n 100 --no-pager
# Kibana'nın Elasticsearch bağlantısını test et
curl -X GET "localhost:5601/api/status" | python3 -m json.tool
# Kibana .kibana index'ini kontrol et
curl -X GET "localhost:9200/.kibana/_cat/indices?v"
.kibana index’i bozulduysa veya eski versiyona ait veriler içeriyorsa Kibana migration sırasında takılıp kalabiliyor. Bu durumda index’i yedekleyip yeniden oluşturmak gerekebilir.
# .kibana index'ini yedekle
curl -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' -d'
{
"source": {
"index": ".kibana"
},
"dest": {
"index": ".kibana_backup_20240115"
}
}'
# Kibana index'ini sil ve yeniden oluştur
curl -X DELETE "localhost:9200/.kibana"
systemctl restart kibana
Index Pattern Bulunamıyor
Kibana’da “No indices match your pattern” hatası aldığında önce Elasticsearch’te gerçekten o index’lerin var olup olmadığını kontrol et.
# Mevcut tüm index'leri listele
curl -X GET "localhost:9200/_cat/indices?v&s=index"
# Belirli bir pattern'a uyan index'leri bul
curl -X GET "localhost:9200/_cat/indices/logstash-*?v"
# Index pattern'ı Kibana API üzerinden oluştur
curl -X POST "localhost:5601/api/saved_objects/index-pattern"
-H "kbn-xsrf: true"
-H "Content-Type: application/json"
-d'{"attributes":{"title":"logstash-*","timeFieldName":"@timestamp"}}'
ILM (Index Lifecycle Management) Sorunları
Üretim ortamında ILM kullanmıyorsan disk yönetimi kabusu yaşıyorsundur. ILM kullanıyorsan ama doğru çalışmıyorsa o da ayrı bir kabus.
# ILM policy durumunu kontrol et
curl -X GET "localhost:9200/_ilm/policy/logstash-policy?pretty"
# Belirli bir index'in ILM durumunu gör
curl -X GET "localhost:9200/logstash-2024.01.15/_ilm/explain?pretty"
# ILM'i manuel olarak tetikle (phase geçişini zorla)
curl -X POST "localhost:9200/_ilm/move/logstash-2024.01.15" -H 'Content-Type: application/json' -d'
{
"current_step": {
"phase": "warm",
"action": "complete",
"name": "complete"
},
"next_step": {
"phase": "cold",
"action": "freeze",
"name": "freeze"
}
}'
# Tüm index'lerin ILM durumunu toplu gör
curl -X GET "localhost:9200/logstash-*/_ilm/explain?pretty" |
python3 -c "import sys,json; data=json.load(sys.stdin);
[print(k, v.get('phase','N/A'), v.get('action','N/A'))
for k,v in data['indices'].items()]"
Performans Optimizasyonu için İzleme
Elasticsearch Thread Pool Tıkanıkları
Yüksek yük altında Elasticsearch’te “rejected” hataları alıyorsan thread pool dolu demektir. Bu genellikle indexing veya search thread pool’unda olur.
# Thread pool durumunu izle
curl -X GET "localhost:9200/_cat/thread_pool?v&h=name,type,active,rejected,completed"
# Node istatistiklerini düzenli olarak topla
watch -n 5 'curl -s "localhost:9200/_cat/nodes?v&h=name,heap.percent,cpu,load_1m,disk.used_percent"'
# Indexing performansını ölç
curl -X GET "localhost:9200/_stats/indexing?pretty" | grep -A10 "indexing"
Eğer rejection sayısı artıyorsa thread pool boyutunu artırabilirsin ama bu genellikle altta yatan bir sorunun belirtisidir. Önce neden bu kadar yük oluştuğunu anla.
# Elasticsearch ayarlarını dinamik olarak değiştir
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent": {
"thread_pool.write.queue_size": 1000
}
}'
Genel Sorun Giderme Yaklaşımı
Yıllar içinde ELK stack sorunlarını çözerken edindiğim en değerli alışkanlık şu: bir şey çalışmıyorsa log’lara bak, ama doğru log’lara bak. Elasticsearch log’ları /var/log/elasticsearch/, Logstash log’ları /var/log/logstash/, Kibana log’ları /var/log/kibana/ altında.
# Elasticsearch hata log'larını filtrele
grep -i "error|warn|exception" /var/log/elasticsearch/elasticsearch.log | tail -50
# Logstash pipeline hatalarını izle
tail -f /var/log/logstash/logstash-plain.log | grep -i "error|warn"
# Sistem kaynak kullanımını genel olarak izle
#!/bin/bash
# elk_health_check.sh
echo "=== Elasticsearch ==="
curl -s "localhost:9200/_cluster/health?pretty" | grep -E "status|number_of_nodes|active_shards"
echo "=== Node Stats ==="
curl -s "localhost:9200/_cat/nodes?v&h=name,heap.percent,cpu,disk.used_percent"
echo "=== Pending Tasks ==="
curl -s "localhost:9200/_cluster/pending_tasks?pretty" | head -20
echo "=== Logstash Pipeline ==="
curl -s "localhost:9600/_node/stats/pipelines?pretty" | grep -E "in|out|filtered"
echo "=== Kibana Status ==="
curl -s "localhost:5601/api/status" | python3 -c "import sys,json; s=json.load(sys.stdin); print(s['status']['overall']['level'])"
Bu scripti crontab’a ekleyerek düzenli health check yapabilirsin. Basit ama etkili bir izleme mekanizması.
Ayrıca şunu kesinlikle yapmanı öneririm: Elasticsearch cluster’ını hiçbir zaman tek node olarak üretimde çalıştırma. Minimum 3 master-eligible node ile çalış. Tek node’da bir sorun yaşandığında tüm verin gidebilir. Bu bir konfigürasyon önerisi değil, bir deneyim dersi.
Son olarak, ELK stack versiyonları arasındaki uyumluluk sorunları çok zaman çalıyor. Elasticsearch, Logstash, Kibana ve Beats’in her birini aynı major versiyonda tutmak zorundasın. 7.x Elasticsearch üzerinde 8.x Logstash çalıştırmaya çalışırsan beklenmedik davranışlarla karşılaşırsın.
Sonuç
ELK stack sorunları öngörülemeyen zamanlarda ortaya çıkar ve genellikle birbiriyle bağlantılı birden fazla sorunu aynı anda çözmen gerekir. Yukarıda anlattığım sorunların büyük çoğunluğu disk doluluğu, yanlış bellek ayarları veya konfigürasyon hataları kaynaklı. Disk izlemesi, heap kullanımı ve cluster health için Prometheus ve Grafana ile birlikte elasticsearch-exporter kullanmanı şiddetle tavsiye ederim. Sorun olduktan sonra değil, olmadan önce fark etmek sistemin sağlıklı kalmasını sağlar.
Stack’in hangi katmanında sorun olursa olsun, sistematik bir yaklaşımla ilerle: önce cluster health, sonra node durumu, sonra index durumu, sonra pipeline istatistikleri. Paniğe kapılmadan adım adım ilerlemek, saat 3’te gelen alarmı çok daha az stresli hale getirir.
