Micrometer ile Modern Uygulamalarda Metrik Yönetimi

İçindekiler
- Giriş
- Micrometer Nedir ve Neden Kullanılır?
- Metrik Türleri ve Kullanım Alanları
- Spring Boot ile Micrometer Entegrasyonu
- Spring Boot Uygulamalarında Metrik Kullanımı
- Özelleştirilmiş Metrik Tanımlama
- Metrikleri Prometheus ve Grafana ile İzleme
- Eşik Değer (Threshold) ve Uyarı (Alert) Yönetimi
- En İyi Uygulamalar
- Anlamlı Metrik İsimlendirmesi ve Etiket (Tag) Kullanımı
- Gereksiz Metrik Toplamaktan Kaçınılması
- Hazır Spring Boot Metriklerinin Kullanımına Öncelik Verilmesi
- Metriklerin Gruplanarak Yönetilebilir Hale Getirilmesi
- Test Ortamlarında Metriklerin İzlenmesi
- Performans ve Güvenliğin Göz Önünde Bulundurulması
- Metriklerin Zamanla Gözden Geçirilmesi ve Optimize Edilmesi
- Sonuç
- Kaynakça
Giriş
Yazılım izlenebilirliği ve gözlemlenebilirliği, modern yazılım geliştirme süreçlerinin kritik bileşenleridir ve sistemlerin performansını, sağlığını ve davranışını anlamak için temel araçlardır. İzlenebilirlik, yazılım sisteminde gerçekleşen olayların kayıt altına alınmasını sağlarken; gözlemlenebilirlik, loglar ve metrikler aracılığıyla sistemin iç dinamiklerinin detaylı şekilde anlaşılmasına olanak tanır. Metrikler, CPU kullanımı, hafıza tüketimi, hata oranları, yanıt süreleri gibi somut verileri ölçerek sistemin sağlığının izlenmesine yardımcı olur. Mikroservisler gibi karmaşık mimari yapılarda hataların kaynağını saptamak ve sistem performansını optimize etmek için detaylı gözlemlenebilirlik gerekir. Bu yaklaşımlar geliştiricilere ve operasyon ekiplerine proaktif sorun tespiti, performans iyileştirmeleri, güvenlik analizleri ve kullanıcı deneyimini optimize etme imkanı sağlar. İyi tasarlanmış bir gözlemlenebilirlik stratejisi, sistem hatalarını hızlı bir şekilde teşhis etmeye ve müdahale etmeye olanak tanırken dinamik ve sürekli değişen yazılım ortamlarında sistemin sürekliliğini ve performansını korumak için kritik bir rol üstlenir. Etkili bir gözlemlenebilirlik altyapısı, sistemlerin yönetimini ve anlaşılmasını kolaylaştırır ve Micrometer gibi metrik toplama araçlarının entegrasyonu bu süreci daha da iyileştirir.
Micrometer Nedir ve Neden Kullanılır?
Micrometer, Java uygulamaları için bir ölçüm kütüphanesidir. Ana amacı, uygulamaların performansını ölçmek ve izlemek için kullanılacak metrikler sağlamaktır. Prometheus, Influx, Datadog gibi popüler zaman serisi veri tabanlarına ve izleme araçlarına kolay entegrasyon sunar. Micrometer, Spring Boot 2.0 ile birlikte varsayılan metrik toplama kütüphanesi olarak kullanılmaya başlanmıştır ve kendi API’si üzerinden uygulama metriklerini yönetmeyi ve göndermeyi kolaylaştırır.
Micrometer Kullanımının Avantajları
- Detaylı Gözlemlenebilirlik
- CPU kullanımı, bellek tüketimi, istek sayısı, yanıt süreleri gibi performansla ilgili metrikleri toplayarak uygulamanın durumu hakkında kapsamlı bilgi sağlar.
- Zaman serisi metrikleriyle, değişimler ve uygulamanın performansındaki gelişim veya dalgalanmalar takip edilebilir.
- Arka Uç Bağımsızlığı ve Esnek Entegrasyon
- Prometheus, InfluxDB, Datadog, Graphite, CloudWatch gibi birçok popüler izleme aracıyla uyumlu çalışır.
- Uygulamanın metrik toplama kodları, kullanılan izleme araçlarından bağımsızdır; bu sayede, izleme altyapısı değişse bile uygulama kodunda herhangi bir değişiklik yapmaya gerek kalmaz.
- Spring Boot ile Kolay Entegrasyon
- Spring Boot Actuator ile ekstra konfigürasyona gerek kalmadan standart metrikleri uygulamaya entegre eder. Böylece hazır metrikleri (JVM, HTTP istekleri, veri tabanı bağlantıları vb.) toplar.
- Tek Noktadan Yönetim
- Merkezi bir metrik toplama katmanı sunarak farklı servislerin veya uygulama bileşenlerinin metriklerini standartlaştırır. Hem mikroservis hem de monolitik mimariler için ideal bir çözüm sunar.
- Zaman Serisi Verileriyle Analiz Yeteneği
- Zamanla değişen metriklerin kaydedilmesini sağlar, bu da performans sorunlarının analiz edilmesi ve tahmin edilmesi için kullanılabilir.
- Kolay Geçiş ve Uyum
- Çeşitli izleme araçlarına adaptörler sunarak aynı uygulamadan farklı altyapılara veri göndermeyi mümkün kılar.
- İzleme altyapısının değiştirilmesi gerektiğinde uygulama kodunda değişiklik yapılmadan uyum sağlanır.
- Yüksek Geliştirici Verimliliği
- Anotasyon veya API’ler üzerinden metrik toplama imkanı sunar. Böylece uygulama geliştiriciler yalnızca iş mantığına odaklanabilir.
- İzleme ve performans yönetimi süreçlerini sadeleştirir.
Bu özellikler, Micrometer’ı özellikle dinamik ve sürekli değişen modern yazılım ortamlarında, uygulama sağlığı ve performansı hakkında anlık bilgi sağlamak için etkili bir araç haline getirir.
Micrometer’ın sunduğu temel metrik türleri ve bunların kullanım alanları, uygulama performansının farklı yönlerini izlemek ve anlamak için yardımcı olur.
Metrik Türleri ve Kullanım Alanları
Metrik Türü | Açıklama | Kullanım Örnekleri |
---|---|---|
Counter | Belli bir olayın kaç kez gerçekleştiğini sayar ve bu sayı sürekli artar. Geriye dönük azaltılmaz. | - Toplam işlemiş sipariş sayısı - Sistem hatalarının toplam sayısı - Kullanıcı kayıt işlemleri |
Gauge | Belli bir anlık değeri gösterir. Değer, bir kaynak nesneden okunur ve sürekli olarak güncellenir. | - Bağlantı havuzundaki aktif bağlantı sayısı - Bellek kullanımı - Kuyruk boyutu - Aktif thread sayısı |
Timer | Bir işlemin ne kadar sürdüğünü ölçer. | - Metot çağrı sürelerini ölçme - API uçlarının yanıt süreleri - Veri tabanı sorgu performansı - Dış servis çağrılarının süresi |
Distribution Summary | Sayısal veri dağılımlarını ölçer. | - Ödeme tutarları - İşlem boyutları - Dosya boyutları - Performans testlerinde değer dağılımları |
Long Task Timer | Uzun süreli işlemleri izlemek için kullanılır. Aktif ve tamamlanan görevlerin süresini ölçer. | - Toplu işlemler - Veri aktarımları - Uzun süren raporlama işlemleri - Büyük veri işleme görevleri |
Spring Boot ile Micrometer Entegrasyonu
1. Projeye Bağımlılık Ekleme
Spring Boot, Micrometer desteğini sağlamak için gerekli bağımlılıklar pom.xml veya build.gradle dosyasına eklenir:
Maven:
1
2
3
4
5
6
7
8
9
10
<dependencies>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
Gradle:
1
2
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
2. application.yml veya application.properties Ayarları
Micrometer’ın topladığı metriklere erişmek için Spring Boot Actuator ile entegre olunması gerekir. Prometheus kullanıldığında, /actuator/prometheus ucundan veri alabilmesi için gerekli konfigürasyonlar eklenir.
application.yaml konfigürasyonu şu şekildedir:
1
2
3
4
5
6
7
8
9
10
11
12
management:
endpoints:
web:
exposure:
include: "*"
prometheus:
metrics:
export:
enabled: true
endpoint:
prometheus:
access: read_only
application.properties konfigürasyonu şu şekildedir:
1
2
3
management.endpoints.web.exposure.include=*
management.prometheus.metrics.export.enabled=true
management.endpoint.prometheus.access=read_only
3. Ön tanımlı Metriklerin Kullanımı
Spring Boot, Micrometer entegrasyonu sayesinde, performans izleme ve yönetimi için bir dizi hazır metriği toplar. Bu metrikler, uygulamanın çeşitli yönlerini izlemek için kapsamlı bilgiler sağlar.
3.1 JVM Metrikleri
Java Sanal Makinesi’nin (JVM) sağlığını ve performansını anlamak için Spring Boot ve Micrometer bu alanda şu bilgileri sağlar:
- Bellek Kullanımı: Micrometer, Java Sanal Makinesi’nin bellek yönetimini kapsamlı şekilde izler ve raporlar. Bu süreçte dinamik nesne oluşturmak için kullanılan heap belleğini ve JVM’in çalışma süreçleri ile sınıf üst verilerini (metadata) barındıran non-heap belleğini detaylı olarak analiz eder ve bellek kullanımına dair derinlemesine görünürlük sağlar.
- Çöp Toplama (Garbage Collection) Süreleri ve Sayıları: Micrometer, çöp toplayıcının (garbage collector) etkinleşme sıklığını ve süresini sürekli olarak izleyerek bu metriklerin uygulama performansı üzerindeki etkilerini analiz etme ve optimizasyon fırsatlarını belirleme imkanı sunar.
- Thread Sayısı ve Durumları: Micrometer, uygulamanın işlem kapasitesi ve sağlığını değerlendirmek için aktif thread sayısını, bekleyen (waiting) veya takılıp kalmış (blocked) thread’lerin durumunu sürekli izleyerek metrikler sunar.
3.2 HTTP İstek Metrikleri
Micrometer, HTTP trafiğini kapsamlı şekilde izleyerek kritik performans metriklerini toplar. Bu izleme süreci, gelen isteklerin işlenme sürelerini ölçerek yanıt hızını değerlendirir, HTTP 5xx ve 4xx gibi hata yanıtlarının sayısını takip ederek uygulama sorunlarını tespit eder ve belirli zaman dilimlerindeki toplam istek sayısını analiz ederek sistem yoğunluğunu değerlendirir.
3.3. Veri Tabanı Metrikleri
- DataSource Kullanımı: Aktif bağlantı sayısı, bekleyen bağlantı sayısı ve bu bağlantıların kullanım süreleri gibi metriklerle veri tabanı kaynaklarının performansı gösterilir.
- Sorgu Süreleri: Veri tabanına yapılan sorguların yanıt süreleri de veri tabanı performansının bir göstergesidir. Uzun sorgu süreleri, optimizasyon ihtiyacını işaret eder.
- Transaction Süreleri ve Sayıları: Transaction’ın ne kadar sürede tamamlandığı ve toplam işlem sayısı izlenir. Böylece işlem verimliliği ve veri tabanı sağlığı değerlendirilir.
Bu metriklere erişmek için Actuator endpoint’i kullanılır:
http://localhost:8080/actuator/prometheus
Spring Boot Uygulamalarında Metrik Kullanımı
Timed
@Timed anotasyonu ile fonksiyonun çalışma süresi ölçülür ve kaydedilir. Böylece ödeme işlem süreleri analiz edilir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Timed(value = "odeme_istek_suresi", description = "Ödeme API istek süresini ölçer")
@PostMapping("/odeme")
fun odemeYap(
@RequestParam tutar: Double
): String {
// Rastgele bir gecikme ekleyerek gerçekçi bir işlem süresi simüle edelim
val gecikme = Random.nextLong(500, 2000)
Thread.sleep(gecikme)
val basariliMi = Random.nextBoolean()
return if (basariliMi) {
"Ödeme başarılı! Tutar: $tutar TL, Süre: ${gecikme}ms"
} else {
"Ödeme başarısız! Tutar: $tutar TL, Süre: ${gecikme}ms"
}
}
Oluşturulan bu uca istek atmak için:
curl "http://localhost:8080/odeme?tutar=150.0"
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/prometheus | grep odeme_istek_suresi
1
2
3
4
# HELP odeme_istek_suresi_seconds Ödeme API istek süresini ölçer
# TYPE odeme_istek_suresi_seconds summary
odeme_istek_suresi_seconds_count{class="com.micrometer.micrometer_demo.OdemeController",exception="none",method="odeme"} 1
odeme_istek_suresi_seconds_sum{class="com.micrometer.micrometer_demo.OdemeController",exception="none",method="odeme"} 1.437303625
Counted
@Counted anotasyonu ile her ödeme isteğinin sayımı yapılır.
1
2
3
4
5
6
7
8
9
10
@Counted(value = "odeme_istek_sayisi", description = "Ödeme API istek sayısını ölçer")
@PostMapping("/odeme")
fun odemeYap(@RequestParam tutar: Double): String {
val basariliMi = Math.random() > 0.2 -
return if (basariliMi) {
"Ödeme başarılı! Tutar: $tutar TL"
} else {
"Ödeme başarısız! Tutar: $tutar TL"
}
}
Oluşturulan bu uca istek atmak için:
curl -X POST "http://localhost:8080/odeme?tutar=150.0"
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/prometheus | grep odeme_istek_sayisi
1
2
3
# HELP odeme_istek_sayisi Ödeme API istek sayısını ölçer
# TYPE odeme_istek_sayisi counter
odeme_istek_sayisi_total{class="com.micrometer.micrometer_demo.OdemeController",exception="none",method="odemeYap",result="success"} 1.0
Micrometer anotasyonları ayrı ayrı kullanıldığı gibi aynı uç noktada bir arada da kullanılabilir. Bu anotasyonların birlikte kullanılması, mikroservisleri izlerken daha kapsamlı ve ayrıntılı metrikler elde etmeyi sağlar. Böylece sistem performansı daha etkin bir şekilde analiz edilebilir ve yönetilebilir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Timed(value = "odeme_istek_suresi", description = "Ödeme API istek süresini ölçer")
@Counted(value = "odeme_istek_sayisi", description = "Ödeme API istek sayısını ölçer")
@PostMapping("/odeme")
fun odemeYap(@RequestParam tutar: Double): String {
val gecikme = Random.nextLong(500, 2000)
Thread.sleep(gecikme)
val basariliMi = Random.nextBoolean()
return if (basariliMi) {
"Ödeme başarılı! Tutar: $tutar TL, Süre: ${gecikme}ms"
} else {
"Ödeme başarısız! Tutar: $tutar TL, Süre: ${gecikme}ms"
}
}
Gauge
Sistem CPU kullanımını yüzdelik olarak ölçen bir Gauge metriği oluşturulup ManagementFactory.getOperatingSystemMXBean() kullanılarak elde edilen sistem bilgileri üzerinden CPU yükü hesaplanır ve MeterRegistry’ye kaydedilir. Bu metrik, /api/sistem/cpu adresine yapılan GET istekleriyle sorgulanabilir ve sistem performansının izlenmesine yardımcı olur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
@RestController
class SistemMetrikleri(registry: MeterRegistry) {
private val osBean = ManagementFactory.getOperatingSystemMXBean() as com.sun.management.OperatingSystemMXBean
init {
Gauge.builder("sistem.cpu.kullanimi", osBean) { osBean.systemCpuLoad * 100 }
.description("Sistem CPU kullanımı")
.baseUnit("yüzde")
.register(registry)
}
@GetMapping("/api/sistem/cpu")
fun sistemCpuKullaniminiGetir(): Double {
return osBean.systemCpuLoad * 100
}
}
Oluşturulan bu uca istek atmak için:
curl http://localhost:8080/api/sistem/cpu
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/metrics/sistem.cpu.kullanimi
1
{"name":"sistem.cpu.kullanimi","description":"Sistem CPU kullanımı","baseUnit":"yüzde","measurements":[{"statistic":"VALUE","value":16.783764924053415}],"availableTags":[]}%
LongTaskTimer
DosyaIsleme sınıfı içinde tanımlanan zamanlayici, LongTaskTimer türünden bir metriktir ve dosya işleme süresini ölçer. Bu metrik, dosya işleme işleminin başlamasından tamamlanmasına kadar geçen süreyi milisaniye cinsinden kaydeder. Böylece işlem sürelerinin performans analizi ve süreç optimizasyonu yapılabilir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestController
class DosyaIsleme(private val registry: MeterRegistry) {
private val zamanlayici: LongTaskTimer = LongTaskTimer.builder("dosya.isleme.suresi")
.description("Bir dosyanın işlenme süresi")
.register(registry)
@GetMapping("/api/dosya-isle")
fun dosyaIsle(): String {
val gorev = zamanlayici.start()
thread {
try {
Thread.sleep(10000)
} finally {
gorev.stop()
}
}
return "Dosya işleme başlatıldı."
}
}
Oluşturulan bu uca istek atmak için:
curl http://localhost:8080/api/dosya-isle
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/metrics/dosya.isleme.suresi
1
{"name":"dosya.isleme.suresi","description":"Bir dosyanın işlenme süresi","baseUnit":"seconds","measurements":[{"statistic":"ACTIVE_TASKS","value":1.0},{"statistic":"DURATION","value":1.556005875}],"availableTags":[]}
DistributionSummary
Kullanıcıların sepetlerine eklediği ürün sayısını izlemek için DistributionSummary metriği kullanılabilir. Bu yapı, sepete eklenen ürün sayısının toplamını, ortalamasını, maksimum ve minimum değerleri gibi istatistiksel bilgileri toplar ve sunar. Bu veriler, kullanıcı davranışlarını anlamak ve e-ticaret platformunun performansını analiz etmek için değerlidir.
1
2
3
4
5
6
7
8
9
10
11
12
@RestController
class SepetIslemleri(registry: MeterRegistry) {
private val urunEklemeOzeti: DistributionSummary = DistributionSummary.builder("sepet.urun.ekleme")
.description("Sepete eklenen ürün sayısı")
.register(registry)
@PostMapping("/api/sepet/urunler")
fun sepeteUrunEkle(@RequestParam("urunSayisi") urunSayisi: Int): String {
urunEklemeOzeti.record(urunSayisi.toDouble())
return "Sepete ürünler eklendi: $urunSayisi"
}
}
Oluşturulan bu uca istek atmak için:
curl -X POST http://localhost:8080/api/sepet/urunler -d "urunSayisi=3"
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/metrics/sepet.urun.ekleme
1
{"name":"sepet.urun.ekleme","description":"Sepete eklenen ürün sayısı","measurements":[{"statistic":"COUNT","value":1.0},{"statistic":"TOTAL","value":3.0}],"availableTags":[]}
Özelleştirilmiş Metrik Tanımlama
Micrometer ile özel metrikler tanımlanabilir. Özel metrik tanımlama, uygulamaların iş süreçlerini detaylı bir şekilde izleme ve analiz etme imkanı sunar. Standart metrikler genel performans bilgisi sağlarken özel metrikler iş akışlarındaki dar boğazları tespit eder, kritik süreçleri analiz eder ve iş mantığına özel performans göstergeleriyle zengin iç görüler sunar. Örneğin, müşteri segmentasyonu, ürün kategorileri veya coğrafi bölgeler bazında performans karşılaştırmaları yapılabilir. Bu metrikler, iş süreçlerinin tam olarak anlaşılmasını, performans sorunlarının hızlıca tespit edilmesini ve sistem davranış desenlerinin ortaya çıkarılmasını sağlar. Ayrıca, yönetimsel raporlama ve veri odaklı karar alma süreçlerini destekleyen stratejik bilgiler sunar. Karmaşık iş süreçleri, detaylı performans analizi veya iş zekası ve raporlama gereksinimlerinde özel metrikler kullanılabilir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.DistributionSummary
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Timer
import org.springframework.stereotype.Service
@Service
class OdemeMetrikServisi(meterRegistry: MeterRegistry) {
private val basariliOdemeSayaci: Counter = meterRegistry.counter(
"odeme.basarili",
"odemeYontemi", "kredi-karti",
"musteriSegmenti", "premium"
)
private val basarisizOdemeSayaci: Counter = meterRegistry.counter(
"odeme.basarisiz",
"neden", "yetersiz-bakiye",
"odemeYontemi", "kredi-karti"
)
private val odemeIslemeZamanlayici: Timer = meterRegistry.timer(
"odeme.isleme.suresi",
"odemeYontemi", "kredi-karti"
)
private val odemeTutariOzetleyici: DistributionSummary = DistributionSummary.builder("odeme.tutari")
.description("Ödeme tutarlarının istatistiksel dağılımı")
.tags("paraBirimi", "USD")
.register(meterRegistry)
fun odemeIsle(payment: Odeme) {
try {
odemeIslemeZamanlayici.record {
if (payment.basariliMi) {
basariliOdemeSayaci.increment()
odemeTutariOzetleyici.record(payment.tutar)
} else {
basarisizOdemeSayaci.increment()
}
}
} catch (e: Exception) {
println("Hata oluştu: ${e.message}")
}
}
}
data class Odeme(
val tutar: Double,
val basariliMi: Boolean
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/odeme")
class OdemeController(private val odemeMetrikServisi: OdemeMetrikServisi) {
@PostMapping("/isle")
fun odemeIsle(@RequestBody odeme: Odeme): String {
odemeMetrikServisi.odemeIsle(odeme)
return if (odeme.basariliMi) "Ödeme başarılı!" else "Ödeme başarısız!"
}
}
Oluşturulan bu uca istek atmak için:
curl -X POST http://localhost:8080/odeme/isle \
-H "Content-Type: application/json" \
-d '{"tutar": 100.0, "basariliMi": true}'
curl -X POST http://localhost:8080/odeme/isle \
-H "Content-Type: application/json" \
-d '{"tutar": 50.0, "basariliMi": false}'
Oluşan metrikleri görmek için:
curl http://localhost:8080/actuator/prometheus
1
2
3
4
5
6
7
8
9
odeme_basarili_total{odemeYontemi="kredi-karti",musteriSegmenti="premium"} 1.0
odeme_basarisiz_total{neden="yetersiz-bakiye",odemeYontemi="kredi-karti"} 1.0
odeme_isleme_suresi_seconds_count{odemeYontemi="kredi-karti"} 1.0
odeme_isleme_suresi_seconds_sum{odemeYontemi="kredi-karti"} 0.002
odeme_tutari_sum{paraBirimi="USD"} 100.0
Bu örnekte, Micrometer’ın Counter, Timer ve DistributionSummary metrikleri kullanılarak ödeme işlemlerinin detaylı analizi gerçekleştirilir. Timer ile her ödeme işleminin süresi ölçülürken, DistributionSummary ile ödeme tutarlarının istatistiksel dağılımı kaydedilir. Counter metrikleri de başarılı ödemelerde başarı sayacını, başarısız ödemelerde ise hata sayacını artırarak işlem sonuçlarını takip eder.
Şu ana kadar Actuator endpoint’leri üzerinden metrikleri ham veri olarak gördük, ancak bu verileri daha anlamlı ve etkili bir şekilde görselleştirmek mümkündür.
Metrikleri Prometheus ve Grafana ile İzleme
Spring Boot, Micrometer sayesinde Prometheus ile kolayca entegre olabilir. Prometheus, prometheus.yml dosyasına Spring Boot uygulamasının adresi eklendiğinde metrikleri toplar. Prometheus ve Grafana, modern yazılım sistemlerinin performansını ve sağlık durumunu izlemek için birlikte çalışan güçlü araçlardır. Prometheus, zaman serisi veri tabanı olarak uygulama ve altyapılardan metrik toplar, bu verileri saklar ve belirli eşik değerlerini aşan durumlarda uyarılar oluşturur. CPU kullanımı, bellek tüketimi, yanıt süreleri ve hata oranları gibi metriklerin detaylı bir şekilde takip edilmesini sağlayarak sistemin performansını sürekli izler. Grafana ise bu metrikleri kullanıcı dostu bir şekilde görselleştiren bir platformdur. Özelleştirilebilir panelleri sayesinde karmaşık metrikler kolayca anlaşılır hale gelir ve farklı veri kaynaklarından gelen bilgiler tek bir yerden analiz edilebilir. Bu araçlar birlikte çalışarak gerçek zamanlı izleme, sorunların erken tespiti, veriye dayalı karar alma ve kapasite planlama süreçlerini kolaylaştırır. Özellikle mikroservis tabanlı sistemlerde her servisin ayrı ayrı izlenmesine olanak tanıyarak ölçeklenebilirliği artırır ve ekiplerin sorun çözme sürecini hızlandırır. Prometheus ve Grafana, sadece mevcut sorunların tespiti için değil, aynı zamanda gelecekteki potansiyel sorunların önceden tahmin edilmesi ve önlenmesi için de kritik bir altyapı sunar. Bu yapı, uygulamanın güvenilirliğini ve iş sürekliliğini sağlamada önemli bir rol oynar.
Prometheus ve Grafana, modern yazılım sistemlerinde en sık kullanılan izleme araçlarıdır ayrıca farklı ihtiyaçlara yönelik Datadog, New Relic, Zabbix, Kibana, ve Splunk gibi alternatif çözümler de mevcuttur. Bu araçlar, farklı kullanım senaryolarına ve ihtiyaçlarına yönelik güçlü özellikler sunar. Bu noktada, Micrometer’ın arka uç bağımsız yapısı sayesinde çeşitli izleme platformlarına kolayca uyum sağlayabilmesi önemli bir avantajdır.
Micrometer ve Arka Uç (Backend) Bağımsızlığı
Arka uç bağımsız metrik katmanı, uygulamanın iş mantığından ve kullandığı izleme/analiz araçlarından bağımsız olarak metriklerin toplanmasını, işlenmesini ve sunulmasını sağlayan bir yazılım katmanıdır. Bu katman, uygulamanın metrik toplama işlevlerini soyutlar ve herhangi bir arka uca veya izleme aracına özel bağımlılıklar olmaksızın çalışabilir.
Metriklerin toplanması ve izlenmesi için arka uç sistemlerden bağımsız bir katman oluşturmak, uygulama geliştirme ve bakım süreçlerinde birçok avantaj sağlar.
Metrik Toplama Katmanının Avantajları
Başlık | Açıklama | Avantaj |
---|---|---|
Taşınabilirlik | Uygulamanın kullanılan izleme veya analiz araçlarından bağımsız hale gelmesidir. | Prometheus, Datadog veya başka bir sistem arasında kolay geçiş yapılabilir. İzleme aracı değişse bile kod etkilenmez. |
Teknoloji Bağımsız | Uygulamanın dili, framework'ü veya teknolojisi ne olursa olsun aynı metrik katmanı kullanılabilir. | Farklı dillerde yazılmış mikroservislerde aynı metrik standartı uygulanabilir. |
Kod Yeniden Kullanımı | Metrik toplama katmanı, uygulamanın geri kalanından soyutlanır. | Aynı yapı hem yeni projelerde hem de mevcut sistemlerde tekrar kullanılabilir. |
Kolay Entegrasyon | Arka uç bağımsız bir metrik katmanı, uygulamanın minimum konfigürasyonla metrik toplamasına olanak tanır. | Yeni bir mikroservis eklendiğinde, izleme ve metrik toplama kolayca entegre edilebilir. |
Bakım Kolaylığı | Metrik toplama kodları merkezi bir katmanda yer aldığı için tek bir yerden yönetilir. | Sorun giderme ve değişiklik yapma süreci hızlanır, kodda tutarlılık sağlanır. |
Performans Optimizasyonu | Metrikler, toplandığı ve işlendiği merkezi bir yerde optimize edilebilir. | Gereksiz metrik toplama önlenir, izleme maliyetleri düşer. |
Güvenlik ve Uyumluluk | Metrik katmanı, hassas bilgilerin korunmasını sağlar ve hangi metriklerin dış dünyaya açılacağını kontrol eder. | Veri paylaşımı sırasında güvenlik riskleri azaltılır. |
Standardizasyon | Her uygulamanın farklı bir metrik toplama yaklaşımı kullanması yerine tek bir standart belirlenir. | Farklı ekipler ve projeler arasında ortak bir metrik dili kullanılır. |
Geliştirici Verimliliği | Geliştiriciler, metrik toplama için detaylarla uğraşmak zorunda kalmaz. | Geliştiriciler, asıl iş mantığına odaklanabilir ve izleme altyapısına düşünmez. |
Arka uç bağımsız bir metrik katmanı, taşınabilirlik, ölçeklenebilirlik ve izleme süreçlerinde esneklik sağlar. Ayrıca, hem geliştirici hem de operasyon ekiplerinin iş yükünü azaltarak sistemin genel güvenilirliğini artırır. Bu yapı, özellikle mikroservis mimarilerinde ve büyük ölçekli projelerde büyük bir avantaj sağlar.
Eşik Değer (Threshold) ve Uyarı (Alert) Yönetimi
Eşik değer ve uyarı yönetimi, metrik tabanlı izleme sistemlerinin en kritik parçalarından biridir. Uygulama performansını izlemek ve anormallikleri tespit etmek için belirli metriklere dayalı eşik değerler tanımlanır ve bu eşiklerin aşılması durumunda uyarılar tetiklenir.
Metrik bazlı uyarı oluşturma stratejileri, farklı ihtiyaçlara göre şekillendirilebilir.
1. Statik Eşik Değer Belirleme
- Belirli bir metrik için sabit bir eşik değeri tanımlanır.
- Örneğin, API yanıt süresi 2 saniyeyi geçerse veya CPU kullanımı %80’i aşarsa uyarı tetiklenir.
Örnek:
- Metric: api.response.time
- Threshold: > 2000ms
- Alert: “API yanıt süresi çok uzun.”
2. Dinamik Eşik Değer Belirleme
- Sabit değerler yerine geçmiş metrik verilerine veya trendlere dayalı olarak eşik belirlenir.
- Örneğin, son 5 dakikadaki ortalama işlem süresi normalin %20 üzerinde ise uyarı tetiklenir.
3. Kompleks Durum Tespiti
- Birden fazla metriğin kombinasyonu ile daha karmaşık uyarılar oluşturulur.
- Örneğin, hem CPU kullanımı %90’ı geçiyor hem de bellek kullanımı %75’in üzerindeyse uyarı tetiklenir.
4. Hata Oranlarına Dayalı Uyarılar
- Hata oranlarına dayalı uyarılar, sistemdeki anormallikleri hızlıca tespit etmek için belirli eşik değerlerinin aşılması durumunda tetiklenir. Örneğin, hata oranı %5’in üzerine çıkarsa veya toplam isteğin %10’u başarısız olursa uyarı tetiklenir.
Eşik Değerlerin Yönlendirilmesi
Eşik değerleri loglara veya izleme sistemlerine yönlendirmek uyarıların izlenmesi ve geçmişe yönelik analizinin yapılması açısından önemlidir.
Loglara Yönlendirme:
- Eşik değer aşımını loglamak, sistemdeki anormalliklerin nedenlerini analiz etmek için faydalıdır.
- Loglarda hem metrik bilgisi hem de eşik değer belirtilir.
Örnek Log:
[ALERT] API yanıt süresi eşik değeri aşıldı. Mevcut: 3000ms, Eşik: 2000ms.
İzleme Sistemlerine Yönlendirme:
- Eşik değer aşım bilgisi izleme araçlarına gönderilir.
- Bu araçlar eşik değer verilerini kullanarak uyarıların durumunu görselleştirir.
Örnek Prometheus Uyarı Kuralı (YAML):
1
2
3
4
5
6
7
8
9
10
groups:
- name: response_time_alerts
rules:
- alert: HighResponseTime
expr: api_response_time > 2000
for: 2m
labels:
severity: critical
annotations:
description: "API yanıt süresi eşik değeri aşıldı. Mevcut süre: ms"
Webhook veya E-posta İle Bildirim:
- Eşik değer aşımı tespit edildiğinde, izleme aracı bir webhook, e-posta veya mesajlaşma platformu (Slack, Teams vb.) üzerinden bildirim gönderir.
Eşik değer ve uyarı yönetimi, uygulama sağlığını proaktif bir şekilde izlemek için kritik öneme sahiptir. Eşik değer belirlerken gereksiz uyarılara neden olmamak için mantıklı aralıklar seçilmelidir. Ayrıca, eşik değer ve uyarılar gerçek sistem yükleri altında test edilmeli ve düzenli olarak gözden geçirilerek uygulama ihtiyaçlarına uyumlu hale getirilmelidir. Doğru eşik değerleri ve etkili yönlendirme stratejileri sayesinde, performans sorunları veya kesintiler kullanıcıları etkilemeden önce tespit edilebilir. Böylece daha güvenilir ve sürdürülebilir sistemler oluşturulabilir.
En İyi Uygulamalar
1. Anlamlı Metrik İsimlendirmesi ve Etiket (Tag) Kullanımı
Metrik isimleri, izleme araçlarında kolay anlaşılır ve erişilebilir olmalıdır.
Etiketler, metrikleri kategorilere ayırmak ve detaylı analiz yapmak için gereklidir. Ancak, aşırı etiket kullanımı metrik sistemini zorlayabilir.
Örnek:
Metrik ismi olarak odeme.isleme.suresi kullanılabilir. Etiketlerle metrik detaylandırılarak ödeme yöntemi ve müşteri tipi gibi ek bilgiler eklenebilir.
1
2
3
4
5
val odemeIslemeZamanlayici: Timer = meterRegistry.timer(
"odeme.isleme.suresi", // Metrik İsmi
"odemeYontemi", "kredi-karti", // Etiketler
"musteriTipi", "premium"
)
2. Gereksiz Metrik Toplamaktan Kaçınılması
Çok fazla metrik toplamak sistemin performansını etkileyebilir ve izleme araçlarının verimliliğini düşürebilir. Doğru metrik seçimine dikkat edilmelidir.
Örnek: Her kullanıcı için ayrı bir Counted kullanmak yerine toplam kullanıcı sayısı bir Gauge metriğiyle ölçülebilir.
3. Hazır Spring Boot Metriklerinin Kullanımına Öncelik Verilmesi
Spring Boot Actuator, JVM, HTTP istekleri ve veri tabanı bağlantıları gibi temel metrikleri otomatik olarak sağlar. Hazır metrikler, sıfırdan metrik oluşturma ve entegre etme ihtiyacını ortadan kaldırır. Actuator’ın otomatik olarak sunduğu metrikler sayesinde temel izleme altyapısı hemen kullanıma hazır hale gelir. Mümkün olduğunca ihtiyaçların hazır metriklerle halledilmesi daha kolay ve hızlı sonuç alınmasını sağlar.
4. Metriklerin Gruplanarak Yönetilebilir Hale Getirilmesi
Farklı metrik türlerini anlamlı gruplar halinde toplamak izlemeyi kolaylaştırır.
Örnek: odeme.basarili, odeme.basarisiz, odeme.islenme.suresi gibi ödeme süreçlerini bir araya getiren isimlendirme yapılabilir.
5. Test Ortamlarında Metriklerin İzlenmesi
Gerçek sistemlerde karşılaşılacak sorunları erken tespit etmek için metriklerin test aşamasında da toplanması gereklidir. Bu amaçla, Micrometer tarafından sağlanan simple registry, test ve geliştirme ortamlarında kullanılır ve metrikleri sadece bellekte saklayarak herhangi bir izleme aracına veri gönderme ihtiyacını ortadan kaldırır.
Bu yapılandırma, Micrometer tarafından sağlanan simple kayıt mekanizmasını etkinleştirir. Özellikle performans sorunlarını veya potansiyel darboğazları erken bir aşamada belirlemeye yardımcı olur.
1
2
3
4
5
management:
metrics:
export:
simple:
enabled: true
6. Performans ve Güvenliğin Göz Önünde Bulundurulması
Metrik toplama, sistem üzerinde ek yük oluşturabilir. Ayrıca, hassas bilgilerin loglanması veya izleme araçlarına gönderilmesi risk oluşturabilir. API anahtarları, kullanıcı adları, e-posta adresleri veya diğer hassas bilgiler, metrik etiketleri olarak izleme araçlarına gönderildiğinde bu bilgiler loglarda, dashboard’larda veya dışa aktarılan veri setlerinde açık bir şekilde görünebilir. Bu durum veri sızıntılarına yol açabilir.
Örnek: API anahtarları veya kullanıcı bilgilerini metriklerde etiket olarak kullanmaktan kaçınılmalıdır.
1
2
3
4
5
6
7
{
"name": "user.login.attempt",
"tags": {
"username": "john.doe@example.com",
"status": "failed"
}
}
Kullanıcı bilgileri veya API anahtarları gibi dinamik ve çok sayıda farklı değere sahip etiketler, metrik sistemlerinde aşırı miktarda benzersiz kombinasyon oluşturabilir. Buna etiket patlaması denir. Eğer her API anahtarı benzersizse izleme aracı bu metrikler için çok fazla benzersiz kayıt oluşturur ve sistemin verimli çalışmasını engeller. Bu durum da çeşitli sorunlara sebep olabilir:
- İzleme sisteminin belleği hızla tükenebilir.
- Metriklerin işlenmesi ve raporlanması yavaşlar.
- Daha yüksek maliyetlere yol açabilir (örneğin, izleme araçlarında daha fazla veri saklama maliyeti).
Örnek:
1
2
3
4
5
6
7
{
"name": "api.requests",
"tags": {
"apiKey": "abcd1234efgh5678",
"region": "US"
}
}
Ne Yapılmalı?
Etiketlerde Genel ve Anonim Bilgiler Kullanılmalı:
- Etiketler yalnızca genelleştirilmiş ve anonim bilgileri içermelidir.
Örnek:
1
2
region=US
errorType=authentication_failed
Hassas Bilgiler Metrik İsmi veya Etiketlerde Kullanılmamalı:
- API anahtarları yerine anonim bir kimlik veya kategorik etiketler kullanılmalı.
Örnek:
- Yanlış: apiKey=abcd1234
- Doğru: apiCategory=premium
Toplulaştırma (Aggregation) Kullanılmalı:
- Kullanıcı veya API anahtarı bazlı detaylar yerine bu bilgiler toplulaştırılmış olarak tutulabilir.
Örnek:
- Her kullanıcı için ayrı metrik tutmak yerine toplam kullanıcı hataları ölçülebilir:
1
2
3
4
5
6
7
8
{
"name": "kullanici.giris.hatalari",
"tags": {
"region": "US",
"errorType": "authentication_failed"
},
"value": 123
}
7. Metriklerin Zamanla Gözden Geçirilmesi ve Optimize Edilmesi
İş tanımı ve sistemin performans gereksinimleri zamanla değişebilir bu yüzden metrikleri düzenli olarak gözden geçirmek önemlidir. Artık kullanılmayan metrikler sistemden kaldırılmalıdır.
Sonuç
Bu yazıda, modern yazılım sistemlerinde metrik toplama ve izlemenin önemi detaylı bir şekilde ele alınmıştır. Micrometer’ın sunduğu altyapı, arka uç bağımsızlığı ve Spring Boot ile entegrasyonu gibi konular incelenmiştir. Ayrıca, temel ve özelleştirilmiş metrik türleri, Prometheus ve Grafana gibi araçlarla izleme imkânı ve eşik değerler ile uyarı mekanizmalarının nasıl yönetileceği üzerine bilgiler sunulmuştur. Anlamlı metrik isimlendirilmesi, etkin etiket kullanımı ve gereksiz metrik toplamaktan kaçınma gibi en iyi uygulamalar üzerinde durulmuştur. Metrik sistemlerinin uygulanması, uygulama performansının optimizasyonu, sistem güvenilirliğinin artırılması ve operasyonel verimliliğin maksimize edilmesi gibi değerli faydalar sağlamaktadır. Bu bütüncül yaklaşım, modern yazılım sistemlerinin sürdürülebilirliği ve ölçeklenebilirliği için temel bir güvence sunmaktadır.
Yazımızın teknik gözden geçirmesi için Elif Çavent’e, editör desteği için ise Tuğçe Yılmaz’a teşekkür ederiz.
Kaynakça