ELK Stack Logging
Giriş
Tek bir sunucudaki log dosyasını tail -f ile izlemek basittir. Ancak 50 container'dan, 10 farklı microservice'ten akan logları takip etmeye çalıştığınızda bu yaklaşım çöker. ELK Stack — Elasticsearch, Logstash ve Kibana — log verilerini merkezi bir yerde toplayan, indeksleyen, aranabilir kılan ve görselleştiren endüstri standardı bir çözümdür. Bu derste ELK Stack'in bileşenlerini, Spring Boot entegrasyonunu ve Kibana dashboard'larını inceleyeceğiz.
ELK Stack Bileşenleri
┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌─────────┐
│ Spring │───▶│ Filebeat │───▶│ Logstash │───▶│ Elastic │
│ Boot App │ │ (shipper)│ │ (processor) │ │ search │
│ JSON logs│ └──────────┘ └──────────────┘ └────┬────┘
└──────────┘ │
┌────▼────┐
│ Kibana │
│ (UI) │
└─────────┘Elasticsearch
Elasticsearch, Apache Lucene üzerine kurulmuş dağıtık bir arama ve analiz motorudur. Log verilerini index adı verilen yapılarda saklar. Her log satırı bir document olur ve tam metin araması, filtreleme, aggregation gibi güçlü sorgulama yetenekleri sunar.
Temel kavramlar:
Index: Benzer yapıdaki belgelerin toplandığı mantıksal birim (ör.
app-logs-2024.01.15)Document: Tek bir log kaydı (JSON formatında)
Shard: Index'in parçalanmış birimi (dağıtık depolama için)
Replica: Shard'ların kopyası (yüksek erişilebilirlik için)
Logstash
Logstash, verileri farklı kaynaklardan alan (input), dönüştüren (filter) ve hedef sisteme gönderen (output) bir veri işleme pipeline'ıdır.
Input (Beats, TCP, file) → Filter (grok, mutate, date) → Output (Elasticsearch, file)Kibana
Kibana, Elasticsearch verilerini görselleştiren web tabanlı bir arayüzdür. Log araması, dashboard oluşturma, alerting ve raporlama gibi yetenekler sunar.
Filebeat
Filebeat, hafif bir log shipper'dır. Sunuculardaki log dosyalarını izler ve Logstash'e (veya doğrudan Elasticsearch'e) gönderir. Logstash'ten çok daha az kaynak tüketir.
Docker Compose ile ELK Kurulumu
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- es-data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:8.12.0
ports:
- "5044:5044" # Beats input
- "5000:5000" # TCP input
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:8.12.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:8.12.0
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/log/myapp:/var/log/myapp:ro
depends_on:
- logstash
volumes:
es-data:Logstash Pipeline Yapılandırması
# logstash/pipeline/logstash.conf
input {
# Filebeat'ten gelen veriler
beats {
port => 5044
}
# Doğrudan TCP bağlantısı (Logstash appender için)
tcp {
port => 5000
codec => json_lines
}
}
filter {
# JSON formatındaki log'u parse et
if [message] =~ /^\{/ {
json {
source => "message"
}
}
# Timestamp'ı düzelt
date {
match => ["@timestamp", "ISO8601"]
target => "@timestamp"
}
# Spring Boot log seviyelerini normalize et
mutate {
rename => { "level" => "log_level" }
rename => { "logger_name" => "logger" }
remove_field => ["host", "agent", "ecs"]
}
# Hata loglarından stack trace'i ayıkla
if [log_level] == "ERROR" {
mutate {
add_tag => ["error"]
}
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "app-logs-%{+YYYY.MM.dd}"
}
# Debug amaçlı konsola da yaz
# stdout { codec => rubydebug }
}Spring Boot — Logstash Appender Entegrasyonu
Log'ları doğrudan Logstash'e TCP üzerinden gönderebilirsiniz:
<!-- pom.xml -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency><!-- logback-spring.xml -->
<springProfile name="production">
<!-- Logstash'e doğrudan TCP gönderimi -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash-host:5000</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"service":"order-service","env":"production"}</customFields>
<includeMdcKeyName>requestId</includeMdcKeyName>
<includeMdcKeyName>userId</includeMdcKeyName>
<includeMdcKeyName>traceId</includeMdcKeyName>
</encoder>
<!-- Bağlantı koptuğunda yeniden deneme -->
<reconnectionDelay>5 seconds</reconnectionDelay>
<!-- Asenkron gönderim (ana thread'i bloklamaz) -->
<queueSize>8192</queueSize>
</appender>
<!-- Konsol (container logları için) + Logstash -->
<root level="INFO">
<appender-ref ref="JSON_CONSOLE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</springProfile>Filebeat Yapılandırması
Alternatif olarak, JSON log dosyalarını Filebeat ile toplayabilirsiniz:
# filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/myapp/*.log
json.keys_under_root: true
json.overwrite_keys: true
json.add_error_key: true
fields:
service: order-service
environment: production
fields_under_root: true
output.logstash:
hosts: ["logstash:5044"]
# Veya doğrudan Elasticsearch'e
# output.elasticsearch:
# hosts: ["elasticsearch:9200"]
# index: "app-logs-%{+yyyy.MM.dd}"Kibana'da Log Araştırma
Data View (Index Pattern) Oluşturma
Kibana'da Management → Data Views bölümüne gidin
Create data view tıklayın
Index pattern:
app-logs-*yazınTimestamp field:
@timestampseçin
Discover — Log Araması
Kibana Discover sayfasında güçlü sorgulama yapabilirsiniz:
# KQL (Kibana Query Language) örnekleri:
log_level: "ERROR"
service: "order-service" and log_level: "ERROR"
message: "timeout" or message: "connection refused"
requestId: "a1b2c3d4"
userId: "user42" and log_level: "WARN"Dashboard Oluşturma
Tipik bir log dashboard'u şu panelleri içerir:
Log Volume: Zaman bazlı log sayısı (bar chart) — ani artışlar anomali göstergesi
Error Rate: Hata loglarının oranı (line chart)
Top Errors: En sık karşılaşılan hata mesajları (data table)
Service Breakdown: Servis bazında log dağılımı (pie chart)
Response Time Heatmap: Yanıt süresi dağılımı
Recent Errors: Son hata logları listesi (saved search)
Log Aggregation Best Practices
JSON formatı kullanın: Yapılandırılmış loglar Elasticsearch'te doğru parse edilir
Index lifecycle management (ILM) uygulayın: Eski logları otomatik silin veya arşivleyin
Field mapping'leri doğru tanımlayın:
keywordvstextfield tipi seçimi sorgulama performansını etkilerShard sayısını optimize edin: Çok fazla shard Elasticsearch'ü yavaşlatır
Sampling uygulayın: Yüksek trafik ortamlarında her logu saklamak yerine örnekleme yapın
Alert kuralları tanımlayın: Kibana alerting ile hata spike'larını otomatik bildirin
# ILM ile 30 günden eski logları sil
# Elasticsearch ILM policy
PUT _ilm/policy/log-retention
{
"policy": {
"phases": {
"hot": { "actions": { "rollover": { "max_size": "50GB", "max_age": "1d" } } },
"warm": { "min_age": "7d", "actions": { "shrink": { "number_of_shards": 1 } } },
"delete": { "min_age": "30d", "actions": { "delete": {} } }
}
}
}
AI Asistan
Sorularını yanıtlamaya hazır