1. Observability nedir ve monitoring'den farkı nedir?
Monitoring genelde "sistem ayakta mı, CPU kaç, memory kaç, hata var mı?" sorularına cevap verir. Observability ise daha ileri gider: sistemin iç durumunu dışarıdan üretilen sinyallerle anlamaya çalışır. Yani sadece alarm görmek değil, alarmın nedenini bulmak için iz bırakmaktır.
Spring Boot 4 tarafında bu yaklaşım Micrometer Observation, OpenTelemetry ve OTLP exporter akışıyla kurulabilir. Grafana tarafında ise bu sinyaller dashboard, trace waterfall, log araması ve alert panelleriyle okunur.
Metrics
Sayısal ölçümlerdir. Request süresi, hata oranı, JVM memory, thread sayısı gibi değerleri zaman içinde gösterir.
Traces
Bir isteğin servisler ve katmanlar arasında hangi adımlardan geçtiğini, her adımın kaç ms sürdüğünü gösterir.
Logs
Uygulamanın olay günlüğüdür. Hata detayı, iş akışı, parametre ve karar noktaları için bağlam sağlar.
2. Metrics, traces ve logs nasıl yorumlanır?
İyi bir teşhis akışı genelde metrics ile başlar, traces ile daralır, logs ile kanıtlanır. Örneğin Grafana'da P95 latency 300 ms'den 900 ms'ye çıktıysa önce hangi endpoint'in yavaşladığını görürsün. Sonra trace waterfall'da yavaş span'i bulursun. En son aynı `trace_id` ile loglara gidip sebebi okursun.
Latency değerlerini okuma
Ortalama latency tek başına yeterli değildir. P50 normal kalırken P95/P99 yükseliyorsa kullanıcıların küçük ama önemli bir kısmı ciddi yavaşlık yaşıyor olabilir. Grafikte ani spike varsa deploy, cache miss, database lock, thread pool saturation veya external API gecikmesi düşünülmelidir.
Metric okurken
- P95/P99 latency trendine bak.
- Error rate ile latency aynı anda yükseliyor mu kontrol et.
- CPU düşük ama latency yüksekse I/O veya lock beklemesi olabilir.
- Thread sayısı ve queue depth artıyorsa concurrency baskısı vardır.
Trace okurken
- En uzun span'i bul.
- DB, cache, HTTP client span'lerini ayrı ayrı incele.
- Parent-child ilişkisini takip et.
- Aynı trace içindeki error tag ve log correlation alanlarına bak.
3. Spring Boot 4 bazlı kurulum: dependency, OTLP endpoint ve Grafana stack
Spring Boot 4 ile temel yaklaşım şudur: uygulama telemetry sinyallerini OTLP formatında dışarı verir, OpenTelemetry Collector bu sinyalleri alır, Grafana ekosistemi ise metrics, traces ve logs tarafını görselleştirir. Basit lokal kurulumda Grafana, Tempo ve Loki yeterlidir; production'da collector mutlaka araya konulmalıdır.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>
</dependencies>
spring:
application:
name: finance-portal-api
management:
opentelemetry:
resource-attributes:
service.name: finance-portal-api
service.namespace: portfolio
deployment.environment: local
otlp:
tracing:
endpoint: http://localhost:4318/v1/traces
metrics:
export:
url: http://localhost:4318/v1/metrics
logging:
endpoint: http://localhost:4318/v1/logs
observations:
key-values:
region: eu-central-1
stack: local
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: true
loki:
endpoint: http://loki:3100/loki/api/v1/push
prometheus:
endpoint: 0.0.0.0:9464
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/tempo]
logs:
receivers: [otlp]
processors: [batch]
exporters: [loki]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
Spring Boot dokümantasyonu OpenTelemetry için farklı yollar olduğunu söyler: Java agent, OpenTelemetry Spring Boot starter veya Spring'in Micrometer/OTLP yaklaşımı. Spring Boot 4 örneğinde hedefimiz vendor-neutral telemetry üretmek ve Grafana tarafında yorumlamaktır.
4. Grafana'da süreç okuma: dashboard'dan trace'e, trace'den log'a
Grafana'da iyi bir inceleme akışı panikten uzak olmalıdır. Önce büyük resmi görürsün: request rate, error rate, latency histogramları, JVM memory, GC pause, active threads. Sonra problemli endpoint veya servis seçilir. Ardından trace detayına gidilir ve log korelasyonu yapılır.
1. Dashboard
Latency ve error rate spike'ını yakala. Hangi servis ve endpoint etkilenmiş bunu bul.
2. Trace
Request içindeki en uzun span'i bul. DB mi, external API mi, lock beklemesi mi ayır.
3. Log
Aynı trace id ile loglara git. Exception, retry, timeout veya business rule kararını oku.
Örnek yorum
Diyelim `/api/portfolio/summary` endpoint'i normalde P95 olarak 180 ms çalışıyor. Deploy sonrası P95 740 ms oldu. Trace waterfall'da controller 20 ms, service 45 ms ama PostgreSQL span'i 620 ms görünüyor. Bu durumda controller koduna değil, query plan, index, lock, connection pool ve N+1 sorgu ihtimaline odaklanırsın.
5. Multithreading ortamda izleme: context propagation neden kritik?
Observability verisi çoğu zaman `ThreadLocal` bağlamla taşınır: trace id, span id, baggage gibi bilgiler mevcut execution context içinde tutulur. Eğer iş başka thread'e atılırsa bu bağlam kaybolabilir. Sonuçta trace kopuk görünür, loglar trace id taşımayabilir ve Grafana'da request bütünlüğü bozulur.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.support.ContextPropagatingTaskDecorator;
@Configuration(proxyBeanMethods = false)
class ObservabilityContextConfiguration {
@Bean
ContextPropagatingTaskDecorator contextPropagatingTaskDecorator() {
return new ContextPropagatingTaskDecorator();
}
}
`@Async`, `AsyncTaskExecutor`, custom executor, scheduler veya virtual thread executor kullanırken request context başka çalışma hattına geçer. Context propagation yoksa aynı request'in parçaları Grafana'da ayrı olaylarmış gibi görünür.
İzlenecek metrikler
- Active threads ve queued tasks
- Executor queue wait time
- Task duration histogram
- Rejected task count
- Lock wait veya DB connection wait
Trace tarafında bakılacaklar
- Async span parent-child ilişkisi korunmuş mu?
- Thread geçişinden sonra trace id aynı mı?
- Long-running task ayrı span olarak görünüyor mu?
- Timeout/retry span event olarak işlenmiş mi?
6. Best practices: production'da okunabilir telemetry üretmek
Her şeyi loglamak observability değildir. Çok log üretmek maliyeti artırır ve problemi bulmayı zorlaştırır. İyi telemetry az ama anlamlı alanlarla, tutarlı isimlerle ve korelasyon id'leriyle üretilir.
Kaynakça
Bu yazıdaki Spring Boot 4 observability yaklaşımı, OpenTelemetry entegrasyon seçenekleri ve Grafana'da metrics/logs/traces yorumlama akışı aşağıdaki resmi dokümanlar temel alınarak hazırlandı.
- Spring Boot 4 Observability Documentation — Micrometer Observation, OpenTelemetry support, OTLP export ve context propagation notları.
- OpenTelemetry Spring Boot Starter Documentation — Spring Boot uygulamalarında OTel starter ve Java agent seçenekleri.
- Grafana Metrics, Logs and Traces Overview — metrics, logs, traces ve observability sinyallerinin Grafana tarafında yorumlanması.