Micrometer Metrics
Giriş
Monitoring (izleme) dünyasında metrikler, uygulamanızın nabzını ölçen sayısal değerlerdir. "Son 5 dakikada kaç sipariş alındı?", "Ortalama yanıt süresi ne?", "Bellekte ne kadar alan kullanılıyor?" — tüm bu sorular metriklerle cevaplanır. Micrometer, Spring Boot'un varsayılan metrik toplama kütüphanesidir ve SLF4J'nin logging için yaptığını metrikler için yapar: bir facade (cephe) katmanı sunarak farklı monitoring sistemleriyle (Prometheus, Datadog, New Relic, InfluxDB vb.) entegrasyonu tek bir API üzerinden sağlar.
Micrometer Facade Yapısı
Micrometer'ın gücü soyutlama katmanında yatar. Uygulamanızda metrik toplama kodunu bir kez yazarsınız; Micrometer, hangi backend kullanıyorsanız ona uygun formatta aktarır:
┌─────────────────────────┐
│ Uygulama Kodu │
│ (Counter, Timer, Gauge) │
└───────────┬─────────────┘
│ Micrometer API
┌───────────▼─────────────┐
│ MeterRegistry │
│ (composite registry) │
└─┬──────┬──────┬────────┘
│ │ │
▼ ▼ ▼
Prom DD Influx ... (backend'ler)MeterRegistry, tüm metrik kayıtlarını yöneten merkezi bileşendir. Spring Boot, classpath'teki bağımlılığa göre otomatik olarak uygun registry'yi yapılandırır.
Metrik Türleri
1. Counter — Sayaç
Yalnızca artan bir değerdir. Sıfırlanamaz (uygulama yeniden başlatıldığında sıfırlanır). Kullanım alanları: toplam istek sayısı, hata sayısı, işlenen mesaj sayısı.
@Service
public class OrderService {
private final Counter orderCounter;
private final Counter orderFailureCounter;
public OrderService(MeterRegistry registry) {
this.orderCounter = Counter.builder("orders.created")
.description("Total number of orders created")
.tag("type", "all")
.register(registry);
this.orderFailureCounter = Counter.builder("orders.failed")
.description("Total number of failed order attempts")
.register(registry);
}
public Order createOrder(OrderRequest request) {
try {
Order order = processOrder(request);
orderCounter.increment();
return order;
} catch (Exception e) {
orderFailureCounter.increment();
throw e;
}
}
}2. Timer — Zamanlayıcı
Bir işlemin süresini ve çağrılma sayısını ölçer. Hem count hem de toplam süreyi takip eder; böylece ortalama, percentile (yüzdelik dilim) gibi istatistikler hesaplanabilir.
@Service
public class PaymentService {
private final Timer paymentTimer;
public PaymentService(MeterRegistry registry) {
this.paymentTimer = Timer.builder("payment.processing")
.description("Time taken to process payments")
.tag("gateway", "stripe")
.publishPercentiles(0.5, 0.95, 0.99) // p50, p95, p99
.publishPercentileHistogram()
.sla(Duration.ofMillis(200), Duration.ofMillis(500), Duration.ofSeconds(1))
.register(registry);
}
public PaymentResult processPayment(PaymentRequest request) {
return paymentTimer.record(() -> {
// Ödeme işlemi burada yapılır
return gateway.charge(request);
});
}
}@Timed anotasyonu ile daha deklaratif bir yaklaşım mümkündür. Bunun için TimedAspect bean'i gerekir:
@Configuration
public class MetricsConfig {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
@Service
public class ProductService {
@Timed(value = "product.search", description = "Product search time",
percentiles = {0.5, 0.95, 0.99})
public List<Product> search(String query) {
return productRepository.findByNameContaining(query);
}
}3. Gauge — Gösterge
Anlık bir değeri temsil eder. Artabilir veya azalabilir. Kullanım: aktif bağlantı sayısı, kuyruk büyüklüğü, cache boyutu, bellekteki nesne sayısı.
@Component
public class QueueMetrics {
private final BlockingQueue<Task> taskQueue;
public QueueMetrics(BlockingQueue<Task> taskQueue, MeterRegistry registry) {
this.taskQueue = taskQueue;
// Gauge, lambda ile anlık değer okur
Gauge.builder("task.queue.size", taskQueue, BlockingQueue::size)
.description("Current number of tasks in the queue")
.register(registry);
Gauge.builder("task.queue.remaining", taskQueue,
q -> q.remainingCapacity())
.description("Remaining capacity in the task queue")
.register(registry);
}
}Counter vs Gauge farkı: Counter her zaman artar (monotonic), Gauge ise anlık snapshot verir. "Toplam sipariş sayısı" → Counter. "Şu anda işlenen sipariş sayısı" → Gauge.
4. DistributionSummary — Dağılım Özeti
Timer'a benzer ancak süre yerine herhangi bir dağılımı ölçer (ör. sipariş tutarları, dosya boyutları, istek boyutları).
@Service
public class OrderAnalyticsService {
private final DistributionSummary orderAmountSummary;
public OrderAnalyticsService(MeterRegistry registry) {
this.orderAmountSummary = DistributionSummary
.builder("order.amount")
.description("Distribution of order amounts in USD")
.baseUnit("usd")
.publishPercentiles(0.5, 0.75, 0.95)
.minimumExpectedValue(1.0)
.maximumExpectedValue(10000.0)
.register(registry);
}
public void recordOrder(Order order) {
orderAmountSummary.record(order.getTotalAmount());
}
}Tag'ler (Etiketler)
Tag'ler, metrikleri boyutlandırmanızı sağlar. Aynı metrik adını farklı etiketlerle kaydettiğinizde, sorgulama sırasında filtreleme ve gruplama yapabilirsiniz:
Counter.builder("http.requests")
.tag("method", "GET")
.tag("endpoint", "/api/users")
.tag("status", "200")
.register(registry)
.increment();Tag best practice'leri:
Tag değerlerinde düşük kardinalite kullanın (status: 200, 404, 500 ✓ — userId: her kullanıcı için farklı ✗)
Tag isimleri tutarlı olsun (camelCase veya dot.notation)
Yüksek kardinalite tag'ler memory sorunlarına yol açar
Common Tags — Global Etiketler
Tüm metriklere otomatik eklenen ortak tag'ler tanımlayabilirsiniz:
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> commonTags() {
return registry -> registry.config()
.commonTags(
"application", "order-service",
"environment", "production",
"region", "eu-west-1"
);
}
}Otomatik Metrikler
Spring Boot Actuator, Micrometer üzerinden birçok metriği otomatik toplar:
JVM:
jvm.memory.used,jvm.gc.pause,jvm.threads.liveHTTP:
http.server.requests(metot, URI, status, exception bilgisiyle)DataSource:
hikaricp.connections.active,hikaricp.connections.idleCache:
cache.gets,cache.puts,cache.evictionsTomcat:
tomcat.sessions.active.current,tomcat.threads.busy
Bu otomatik metrikler, uygulamanızın genel sağlığını izlemek için yeterli bir başlangıç noktası sunar.
AI Asistan
Sorularını yanıtlamaya hazır