ELK Stack Nedir: Elasticsearch, Logstash ve Kibana Mimarisi
Yüzlerce sunucudan akan log verisini tek bir terminalden tail -f ile takip etmeye çalıştığınızda ne hissediyorsunuz? Ben size söyleyeyim: kaos. Özellikle gece 2’de production ortamında bir şeyler patlıyorsa ve siz 15 farklı sunucuda grep koşturuyorsanız, o anın verdiği çaresizlik hissi sizi ELK Stack’e iter. Ben de tam olarak bu yüzden bu ekosisteme geçtim ve bugün geriye bakıp “keşke daha önce yapmış olsaydım” diyorum.
ELK Stack Nedir
ELK, üç açık kaynaklı aracın baş harflerinden oluşur: Elasticsearch, Logstash ve Kibana. Bu üçlü birlikte, dağıtık sistemlerdeki log verilerini toplama, işleme, depolama ve görselleştirme amacıyla kullanılır. Elastic firması bu üç ürünü tek çatı altında sunmaktadır. Sonraki yıllarda Beats ailesi de bu ekosisteme eklendi ve kimi çevrelerde bu yüzden “Elastic Stack” adı da kullanılmaktadır. Ama sektörde ELK adı hâlâ daha yaygın.
Temel fikir şu: loglarınız nerede olursa olsun, hangi formatta gelirse gelsin, bunları merkezi bir yerde toplayacaksınız, anlamlı hale getireceksiniz ve üzerinde sorgulama yapabileceksiniz. Bu kulağa basit geliyor ama production’da onlarca servis, yüzlerce sunucu ve günde milyarlarca log satırıyla uğraştığınızda, bu işi düzgün yapan bir altyapının değeri inanılmaz büyüyor.
Mimariye Genel Bakış
Klasik ELK mimarisinde veri akışı şöyle işler:
- Log kaynakları (uygulama sunucuları, veritabanları, ağ cihazları) log üretir
- Beats veya Logstash bu logları toplar ve merkeze iletir
- Logstash gelen veriyi parse eder, filtreler ve zenginleştirir
- Elasticsearch işlenmiş veriyi indeksler ve saklar
- Kibana üzerinden bu veriyi sorgular ve görselleştirirsiniz
Küçük ortamlarda Beats doğrudan Elasticsearch’e de yazabilir. Ama orta ve büyük ölçekli sistemlerde araya bir Logstash veya en azından bir mesaj kuyruğu (Kafka, Redis) koymak şiddetle tavsiye edilir. Elasticsearch’i ham log bombardımanından korumanız gerekir.
Elasticsearch: Kalbin Attığı Yer
Elasticsearch, Apache Lucene üzerine inşa edilmiş dağıtık bir arama ve analitik motorudur. REST API üzerinden JSON belgeleri saklar ve bu belgeleri indeksleyerek milisaniyeler içinde arama yapmanıza olanak tanır.
Birkaç temel kavramı netleştirelim:
- Index: Benzer belgelerin toplandığı yapı. MySQL’deki tablo gibi düşünebilirsiniz ama çok daha esnek
- Document: Elasticsearch’te saklanan her bir kayıt. JSON formatında
- Shard: Index’in bölündüğü parçalar. Dağıtık yapının temeli
- Replica: Shard’ların yedek kopyaları. Hem yüksek erişilebilirlik hem de okuma performansı için
- Node: Elasticsearch cluster’ındaki her bir sunucu
- Cluster: Birden fazla node’un oluşturduğu yapı
Elasticsearch’in güzelliği şu: tek node’dan başlayabilir, sisteminiz büyüdükçe yatay olarak scale edebilirsiniz. Yeni bir node cluster’a join olduğunda, Elasticsearch shardları otomatik olarak dengeler.
Basit bir Elasticsearch sorgusu nasıl görünür:
# Belirli bir index'te arama yapma
curl -X GET "localhost:9200/logs-2024.01.15/_search?pretty"
-H 'Content-Type: application/json'
-d '{
"query": {
"match": {
"message": "ERROR"
}
},
"size": 10,
"sort": [{"@timestamp": {"order": "desc"}}]
}'
# Cluster sağlığını kontrol etme
curl -X GET "localhost:9200/_cluster/health?pretty"
# Index listesini görme
curl -X GET "localhost:9200/_cat/indices?v"
# Node bilgilerini görme
curl -X GET "localhost:9200/_cat/nodes?v"
Elasticsearch’i kurarken dikkat etmeniz gereken en kritik şey heap memory ayarıdır. Genel kural: sunucunuzdaki toplam RAM’in yarısını Elasticsearch’e verin ama 32GB’ı geçmeyin. 32GB’ın üzerinde JVM’in pointer optimizasyonları çalışmaz ve performans düşer.
# /etc/elasticsearch/jvm.options dosyasında
# 16GB RAM'li bir sunucu için
-Xms8g
-Xmx8g
Logstash: Veriyi Şekillendiren Motor
Logstash, Elasticsearch’e gönderilmeden önce log verisini işlediğiniz yerdir. Pipeline yapısıyla çalışır ve her pipeline üç aşamadan oluşur: input, filter ve output.
Input kısmında veriyi nereden aldığınızı tanımlarsınız. Beats’ten gelebilir, syslog üzerinden gelebilir, bir Kafka topic’inden gelebilir, hatta bir veritabanından JDBC ile çekebilirsiniz.
Filter kısmı en kritik bölümdür. Ham log satırını yapısal veriye dönüştürdüğünüz yerdir. Grok patternleri bu iş için Logstash’in en güçlü silahıdır. Bir Nginx access log satırını düşünün:
192.168.1.100 - - [15/Jan/2024:10:23:45 +0300] "GET /api/users HTTP/1.1" 200 1234
Bu satırı Grok ile ayrıştıralım:
# /etc/logstash/conf.d/nginx.conf
input {
beats {
port => 5044
}
}
filter {
if [fields][log_type] == "nginx_access" {
grok {
match => {
"message" => '%{IPORHOST:client_ip} - %{DATA:auth_user} [%{HTTPDATE:timestamp}] "%{WORD:http_method} %{DATA:request_path} HTTP/%{NUMBER:http_version}" %{NUMBER:response_code:int} %{NUMBER:bytes_sent:int}'
}
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
mutate {
remove_field => ["timestamp", "message"]
add_field => {
"environment" => "production"
"service" => "web-frontend"
}
}
if [response_code] >= 500 {
mutate {
add_tag => ["server_error"]
}
}
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
user => "logstash_writer"
password => "${LOGSTASH_ES_PASSWORD}"
}
}
Bu pipeline çalıştığında, o düz metin log satırı ayrıştırılmış, zaman damgası UTC’ye normalize edilmiş ve her kayıda environment ile service alanları eklenmiş olarak Elasticsearch’e gider. Artık Kibana’da “response_code: 500 AND service: web-frontend” gibi sorgular yapabilirsiniz.
Logstash pipeline’larında sık yapılan bir hata: her şeyi tek bir pipeline’a koymak. Büyük ortamlarda farklı servisler için farklı pipeline’lar oluşturun. Hem yönetimi kolaylaşır hem de bir pipeline’da sorun çıktığında diğerleri etkilenmez.
# Logstash pipeline'ı test etme (syntax kontrolü)
/usr/share/logstash/bin/logstash --config.test_and_exit -f /etc/logstash/conf.d/nginx.conf
# Logstash'i debug modda başlatma
/usr/share/logstash/bin/logstash --log.level=debug -f /etc/logstash/conf.d/nginx.conf
Beats: Hafif Veri Toplayıcılar
Logstash güçlü ama ağır. Her sunucuya Logstash kurmak hem kaynak israfı hem de yönetim kabusu. İşte bu noktada Beats devreye girer.
Beats ailesi içinde en yaygın kullanılanlar:
- Filebeat: Log dosyalarını izler ve gönderir. Web sunucu logları için ideal
- Metricbeat: CPU, RAM, disk gibi sistem metriklerini toplar
- Packetbeat: Ağ trafiğini analiz eder
- Auditbeat: Linux audit framework’üyle güvenlik olaylarını izler
- Heartbeat: Servis ve URL’lerin erişilebilirliğini kontrol eder
Filebeat kurulumu ve konfigürasyonu çok basit:
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
log_type: nginx_access
server_name: web-01
fields_under_root: true
multiline.pattern: '^d{4}-d{2}-d{2}'
multiline.negate: true
multiline.match: after
output.logstash:
hosts: ["logstash.internal:5044"]
loadbalance: true
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_docker_metadata: ~
logging.level: warning
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
Buradaki multiline konfigürasyonu önemli. Java stack trace’leri birden fazla satıra yayılır. Bu ayar olmadan her satır ayrı bir log eventi olarak işlenir. multiline.pattern ile “tarihle başlayan satır yeni bir event” diyoruz, önceki satırlar birleştiriliyor.
Kibana: Görselleştirme ve Analiz
Kibana, Elasticsearch üzerindeki verileri görselleştirmenizi sağlayan web arayüzüdür. İlk kurulumda yapmanız gereken birkaç adım var:
Index Pattern Oluşturma: Kibana’ya hangi index’leri kullanacağınızı söylemeniz gerekir. nginx-access-* gibi wildcard pattern kullanarak günlük index’leri tek seferinde tanımlayabilirsiniz.
Discover: Raw log verilerini arama ve filtreleme ekranı. KQL (Kibana Query Language) veya Lucene syntax kullanabilirsiniz.
Visualize: Grafik, pasta dilimi, harita gibi görselleştirmeler oluşturursunuz.
Dashboard: Birden fazla visualization’ı bir araya getirdiğiniz ekranlar. Operations ekibinizin sabah geldiğinde ilk baktığı ekran burasıdır.
Gerçek dünyada çok işe yarayan birkaç visualization:
- 5xx hata oranlarının zaman serisi grafiği (her servis için ayrı)
- Ülkelere göre istek haritası (Geo-IP zenginleştirmesiyle)
- En yavaş endpoint’lerin tablosu (response time’a göre)
- Hata mesajlarının kelime bulutu
Gerçek Dünya Senaryosu: E-ticaret Platformu
Bir e-ticaret firmasında çalışırken şu problemi yaşadık: ödeme sayfasında aralıklı hatalar raporlanıyordu, müşteriler şikayet ediyordu ama geliştirici ekip “ben logda bir şey göremiyorum” diyordu. Çünkü 6 farklı sunucuda dağılmış loglar vardı ve kimse hepsine tek tek bakmıyordu.
ELK stack kurulumundan sonra Kibana’da şu sorguyu çalıştırdık:
# Kibana Dev Tools'da Elasticsearch sorgusu
POST /app-logs-*/_search
{
"query": {
"bool": {
"must": [
{"match": {"service": "payment-service"}},
{"range": {"@timestamp": {"gte": "now-2h"}}},
{"match": {"level": "ERROR"}}
]
}
},
"aggs": {
"errors_over_time": {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "5m"
}
}
}
}
5 dakikalık bucket’larla baktığımızda belirli aralıklarda spike gördük. Spike zamanlarını alıp database slow query loglarıyla ilişkilendirdik. Sorun, bir veritabanı index’inin eksik olmasından kaynaklanıyordu ve belirli saatlerde yoğunlukla o tabloyu kullanan bir batch job tetikliyordu. ELK olmadan bu problemi bulmak saatler alırdı, ELK ile 20 dakikada teşhis ettik.
Index Lifecycle Management ile Storage Yönetimi
ELK stack’in production’da ayakta tutulmasındaki en büyük zorluklardan biri disk kullanımıdır. Loglar sürekli birikir, Elasticsearch şişer. Index Lifecycle Management (ILM) bu sorunu çözer.
# ILM Policy oluşturma
curl -X PUT "localhost:9200/_ilm/policy/logs-policy"
-H 'Content-Type: application/json'
-d '{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}'
Bu policy şunu yapar: aktif yazma (hot) aşamasında index günlük veya 50GB’a ulaştığında rotate eder. 7 gün sonra warm aşamasına geçer, shard sayısı azaltılır ve segmentler birleştirilir (okuma performansı artar, yazma durur). 30 gün sonra cold aşamasına geçer, freeze edilir (RAM kullanımı minimize edilir). 90 gün sonra silinir.
Yasal saklama zorunluluğunuz varsa cold yerine bir S3 veya NFS snapshot’ı alıp sonra silebilirsiniz.
Performans ve Güvenlik Notları
ELK stack production ortamında çalıştırırken birkaç kritik noktaya dikkat edin:
- Elasticsearch güvenliği: Elastic 8.x sürümünden itibaren güvenlik varsayılan olarak açık geliyor. 7.x ve öncesinde mutlaka X-Pack security’yi aktif edin ya da önüne Nginx reverse proxy koyun. İnternette açık Elasticsearch instance’larının veri sızdırdığına dair sayısız vaka var
- JVM heap’i RAM’in yarısından fazla yapma: Kalan RAM işletim sistemi file cache için kullanılır, Elasticsearch bu cache’den de faydalanır
- Shard sayısını abartma: Her shard bir Lucene index’idir ve bellek tüketir. Küçük index’ler için tek shard yeterlidir
_allfield’ını devre dışı bırak: Eski Elasticsearch versiyonlarında tüm alanları tek bir field’a kopyalar, gereksiz depolama ve indexleme yükü yaratır- Logstash worker thread sayısını ayarla:
-wparametresi veyapipeline.workersayarı. CPU core sayısıyla eşit başlayın
# Elasticsearch cluster istatistikleri
curl -X GET "localhost:9200/_stats?pretty" | grep -E '"count"|"size_in_bytes"'
# Yavaş sorguları tespit etmek için slow log aktif etme
curl -X PUT "localhost:9200/nginx-access-*/_settings"
-H 'Content-Type: application/json'
-d '{
"index.search.slowlog.threshold.query.warn": "5s",
"index.search.slowlog.threshold.query.info": "2s"
}'
Sonuç
ELK Stack bir araç değil, bir zihinsel dönüşüm. “Bir şey mi patladı, logları kontrol edelim” modundan “veriye dayalı karar veren, proaktif izleme yapan” bir ops kültürüne geçişin altyapısı.
Başlangıç için tavsiyem şu: tek node Elasticsearch, tek Logstash instance ve birkaç Filebeat ile küçük başlayın. Kibana’da ilk dashboardunuzu oluştururken “aslında bu kadar basitmiş” diyeceksiniz. Ölçeklendirme sonra gelir; önce veriyi görmeye alışın, sorular sormaya başlayın, anomalileri fark etmeye başlayın.
Birkaç ay sonra bakıyorsunuz: incident response süreniz düşmüş, postmortem’leriniz daha somut, geliştirici ekibiniz “logda bir şey göremiyorum” demek yerine sizi arayıp “şu serviste şu hata spike’ı var, bak” diyor. Bu kültürel değişim, ELK’nin teknik faydalarından çok daha değerlidir.
Son bir not: Elastic’in cloud servisi olan Elastic Cloud’u denemeyi de düşünebilirsiniz. Yönetim yükü azalır ama maliyet artar. Kendi altyapınızda kuruyorsanız OpenSearch (AWS’nin Elasticsearch fork’u) da bir alternatif, özellikle lisanslama konusunda endişeleriniz varsa.
