← Kursa Dön
📄 Text · 25 min

Actuator Endpoints

Giriş

Bir aracın gösterge panelini düşünün: hız, yakıt durumu, motor sıcaklığı, yağ basıncı — tüm bu bilgiler sürücüye aracın durumunu anlık olarak gösterir. Motor kapağını açmadan, mekanik çağırmadan "araç sağlıklı mı?" sorusuna yanıt alırsınız. Spring Boot Actuator tam olarak uygulamanızın gösterge paneli'dir — uygulamanızın sağlık durumunu, kaynak kullanımını, konfigürasyonunu ve çalışma zamanı bilgilerini HTTP endpoint'leri üzerinden dışarıya açar.

Production ortamında çalışan bir uygulama hakkında "sağlıklı mı?", "ne kadar bellek kullanıyor?", "hangi bean'ler yüklü?", "hangi konfigürasyon değerleri aktif?" gibi soruları yanıtlayabilmek kritik önem taşır. Geliştirme ortamında IDE, konsol ve debug araçları varken, production'da bu lüks yoktur — sunucudaki bir JVM'in içinde neler olduğunu Actuator ile öğrenirsiniz.

Bu derste Actuator'ın projeye eklenmesini, temel endpoint'leri (/health, /info, /metrics, /env), endpoint exposure yapılandırmasını, güvenlik stratejilerini, özel endpoint yazmayı ve production best practice'lerini derinlemesine öğreneceğiz.


Projeye Ekleme

<!-- Maven -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
// Gradle
implementation 'org.springframework.boot:spring-boot-starter-actuator'

Bu bağımlılığı eklediğiniz anda, uygulama ayağa kalktığında otomatik olarak bir dizi HTTP endpoint aktif olur. Varsayılan olarak bu endpoint'ler /actuator base path'i altında sunulur.


/actuator/health — Sağlık Kontrolü

En kritik endpoint budur. Kubernetes liveness/readiness probe'ları, load balancer'lar ve monitoring araçları bu endpoint'i sürekli kontrol eder.

GET /actuator/health

// Basit yanıt (varsayılan)
{
    "status": "UP"
}

Detaylı yanıt için yapılandırma:

management.endpoint.health.show-details=always
# Seçenekler: never (varsayılan), when-authorized, always
{
    "status": "UP",
    "components": {
        "db": {
            "status": "UP",
            "details": {
                "database": "PostgreSQL",
                "validationQuery": "isValid()"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 499963174912,
                "free": 379846746112,
                "threshold": 10485760,
                "path": "/app/.",
                "exists": true
            }
        },
        "redis": {
            "status": "UP",
            "details": {
                "version": "7.2.4"
            }
        },
        "ping": {
            "status": "UP"
        }
    }
}

Spring Boot, classpath'teki bağımlılıklara göre otomatik olarak health indicator'lar kaydeder:

BağımlılıkIndicatorKontrol
DataSourceDataSourceHealthIndicatorVeritabanı bağlantısı
RedisRedisHealthIndicatorRedis sunucu erişimi
ElasticsearchElasticsearchRestHealthIndicatorES cluster durumu
RabbitMQRabbitHealthIndicatorRabbitMQ bağlantısı
KafkaKafkaHealthIndicatorKafka broker erişimi
DiskSpaceHealthIndicatorDisk alanı
MailMailHealthIndicatorSMTP sunucu erişimi

Health status değerleri:

  • UP: Bileşen sağlıklı — yeşil ışık

  • DOWN: Bileşen çalışmıyor — kırmızı ışık

  • OUT_OF_SERVICE: Geçici olarak hizmet dışı (bakım) — sarı ışık

  • UNKNOWN: Durum belirlenemiyor — gri


/actuator/info — Uygulama Bilgisi

Uygulamanızın versiyon, build ve ortam bilgilerini döndürür:

management.info.env.enabled=true

info.app.name=Order Management System
info.app.version=2.1.0
info.app.description=E-Commerce Order Processing API
info.app.java.version=${java.version}
info.app.encoding=@project.build.sourceEncoding@
GET /actuator/info
{
    "app": {
        "name": "Order Management System",
        "version": "2.1.0",
        "description": "E-Commerce Order Processing API",
        "java": { "version": "21.0.2" }
    }
}

Build Info Otomatik Ekleme

<!-- Maven - pom.xml -->
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>build-info</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Bu plugin META-INF/build-info.properties dosyası oluşturur. Actuator bunu otomatik okur ve /info çıktısına ekler:

{
    "build": {
        "artifact": "order-service",
        "name": "Order Service",
        "time": "2024-01-15T10:30:00.000Z",
        "version": "2.1.0",
        "group": "com.example"
    }
}

Git Bilgisi

<!-- Maven - Git bilgisi için -->
<plugin>
    <groupId>io.github.git-commit-id</groupId>
    <artifactId>git-commit-id-maven-plugin</artifactId>
</plugin>
management.info.git.mode=full
{
    "git": {
        "branch": "main",
        "commit": {
            "id": "a1b2c3d",
            "time": "2024-01-15T09:00:00Z",
            "message": { "short": "Fix order validation" }
        }
    }
}

/actuator/metrics — Metrikler

Uygulamanın çeşitli metriklerini listeler:

GET /actuator/metrics
{
    "names": [
        "jvm.memory.used",
        "jvm.memory.max",
        "jvm.gc.pause",
        "http.server.requests",
        "system.cpu.usage",
        "process.uptime",
        "tomcat.sessions.active.current",
        "hikaricp.connections.active"
    ]
}

Belirli bir metriğin detayları:

GET /actuator/metrics/jvm.memory.used
{
    "name": "jvm.memory.used",
    "measurements": [
        { "statistic": "VALUE", "value": 256901120 }
    ],
    "availableTags": [
        { "tag": "area", "values": ["heap", "nonheap"] },
        { "tag": "id", "values": ["G1 Eden Space", "G1 Old Gen", "Metaspace"] }
    ]
}

// Tag ile filtreleme
GET /actuator/metrics/jvm.memory.used?tag=area:heap
GET /actuator/metrics/http.server.requests?tag=uri:/api/orders&tag=status:200

/actuator/env — Ortam Değişkenleri

Tüm property source'ları ve değerlerini gösterir:

GET /actuator/env
{
    "activeProfiles": ["production"],
    "propertySources": [
        {
            "name": "systemEnvironment",
            "properties": {
                "JAVA_HOME": { "value": "/usr/lib/jvm/java-21" },
                "DATABASE_URL": { "value": "******" }
            }
        },
        {
            "name": "applicationConfig: [classpath:/application-production.yml]",
            "properties": {
                "server.port": { "value": "8080" },
                "spring.datasource.url": { "value": "******" }
            }
        }
    ]
}

⚠️ Dikkat: Hassas bilgiler (şifreler, API anahtarları) ****** olarak maskelenir. Yine de production'da bu endpoint'i dikkatli yönetin.


/actuator/loggers — Çalışma Zamanında Log Seviyesi Değiştirme

Bu endpoint özellikle güçlüdür — yeniden deploy etmeden log seviyesini değiştirebilirsiniz:

# Mevcut seviyeyi görüntüle
curl http://localhost:8080/actuator/loggers/com.example.myapp
# {"configuredLevel": "INFO", "effectiveLevel": "INFO"}

# Seviyeyi DEBUG'a çek (POST)
curl -X POST http://localhost:8080/actuator/loggers/com.example.myapp \
  -H "Content-Type: application/json" \
  -d '{"configuredLevel": "DEBUG"}'

# Seviyeyi geri al
curl -X POST http://localhost:8080/actuator/loggers/com.example.myapp \
  -H "Content-Type: application/json" \
  -d '{"configuredLevel": "INFO"}'

Bu özellik production'da bir sorunu araştırırken hayat kurtarır: uygulamayı durdurmadan DEBUG loglarını açar, sorunu tespit eder, sonra kapatırsınız.


Endpoint Exposure Yapılandırması

Varsayılan olarak yalnızca health endpoint'i HTTP üzerinden açıktır:

# Tüm endpoint'leri HTTP üzerinden aç
management.endpoints.web.exposure.include=*

# Sadece belirli endpoint'leri aç (önerilen)
management.endpoints.web.exposure.include=health,info,metrics,prometheus,loggers

# Belirli endpoint'leri hariç tut
management.endpoints.web.exposure.exclude=env,beans,configprops,heapdump

# Endpoint'i tamamen devre dışı bırak
management.endpoint.shutdown.enabled=false

# Base path değiştir (varsayılan: /actuator)
management.endpoints.web.base-path=/manage

# Actuator portunu ayrı tut (güvenlik için) 
management.server.port=9090
management.server.address=127.0.0.1

💡 Best Practice: Production'da management.server.port=9090 ile Actuator'ı ayrı portta çalıştırın. Bu portu sadece internal ağdan erişilebilir yapın. Public internet'ten Actuator'a erişimi engelleyin.


Diğer Önemli Endpoint'ler

EndpointAçıklama
/actuator/beansTüm Spring bean'lerini listeler
/actuator/configpropsTüm @ConfigurationProperties değerlerini gösterir
/actuator/mappingsTüm @RequestMapping URL eşlemelerini gösterir
/actuator/scheduledtasksZamanlanmış görevleri listeler
/actuator/cachesCache bilgilerini gösterir
/actuator/threaddumpThread dump alır (deadlock tespiti)
/actuator/heapdumpHeap dump dosyası indirir (bellek analizi)
/actuator/shutdownUygulamayı kapatır (varsayılan kapalı!)

Güvenlik

Actuator endpoint'leri hassas bilgiler içerir. Spring Security ile korunmalıdır:

@Configuration
public class ActuatorSecurityConfig {
    
    @Bean
    public SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
        return http
            .securityMatcher("/actuator/**")
            .authorizeHttpRequests(auth -> auth
                // Health ve info herkese açık (load balancer / K8s probe)
                .requestMatchers("/actuator/health").permitAll()
                .requestMatchers("/actuator/health/**").permitAll()
                .requestMatchers("/actuator/info").permitAll()
                // Prometheus metrik toplama (internal network)
                .requestMatchers("/actuator/prometheus").permitAll()
                // Diğer tüm endpoint'ler ADMIN rolü gerektirir
                .requestMatchers("/actuator/**").hasRole("ADMIN")
            )
            .httpBasic(Customizer.withDefaults())
            .build();
    }
}

Güvenlik Katmanları

1. Ağ seviyesi:
   → Actuator portu (9090) sadece internal VPC'den erişilebilir
   → Firewall kuralları ile public access engellenir

2. Uygulama seviyesi:
   → Spring Security ile endpoint bazında yetkilendirme
   → Health ve info herkese açık (probe'lar için)
   → Diğerleri ADMIN rolü gerektirir

3. Endpoint seviyesi:
   → Gereksiz endpoint'ler kapatılır (shutdown, heapdump)
   → show-details=when-authorized ile hassas bilgiler korunur

Custom Endpoint

Kendi Actuator endpoint'inizi yazabilirsiniz:

@Component
@Endpoint(id = "app-status")
public class AppStatusEndpoint {
    
    private final OrderRepository orderRepository;
    private final UserRepository userRepository;
    
    @ReadOperation
    public Map<String, Object> status() {
        return Map.of(
            "orders", Map.of(
                "total", orderRepository.count(),
                "today", orderRepository.countToday(),
                "pending", orderRepository.countByStatus(OrderStatus.PENDING)
            ),
            "users", Map.of(
                "total", userRepository.count(),
                "active", userRepository.countActive()
            ),
            "system", Map.of(
                "uptime", ManagementFactory.getRuntimeMXBean().getUptime(),
                "timestamp", Instant.now()
            )
        );
    }
    
    @WriteOperation
    public void clearCache(@Selector String cacheName) {
        cacheManager.getCache(cacheName).clear();
    }
}

// Erişim: GET /actuator/app-status
// Cache temizleme: POST /actuator/app-status/orders

Yaygın Hatalar

1. Tüm Endpoint'leri Public'e Açmak

# ❌ YANLIŞ — heapdump, env, configprops hassas bilgi içerir!
management.endpoints.web.exposure.include=*

# ✅ DOĞRU — sadece gerekli endpoint'leri açın
management.endpoints.web.exposure.include=health,info,metrics,prometheus

2. Health Detaylarını Herkese Göstermek

# ❌ YANLIŞ — veritabanı tipi, Redis versiyonu gibi bilgiler ifşa olur
management.endpoint.health.show-details=always

# ✅ DOĞRU — sadece yetkilendirme ile
management.endpoint.health.show-details=when-authorized

3. Aynı Portta Çalıştırmak

# ❌ YANLIŞ — Actuator public API ile aynı porttan erişilebilir
# (server.port=8080, actuator da 8080)

# ✅ DOĞRU — Ayrı port, sadece internal erişim
management.server.port=9090
management.server.address=127.0.0.1

Özet

  • Spring Boot Actuator, uygulamanızın iç durumunu HTTP endpoint'leri üzerinden expose eden production-ready bir izleme modülüdür. spring-boot-starter-actuator bağımlılığı ile aktif olur.

  • `/health` en kritik endpoint'tir — Kubernetes, load balancer ve monitoring araçları bunu kullanır. Spring Boot, classpath'teki bağımlılıklara göre otomatik health indicator kaydeder.

  • `/info` uygulama versiyon, build ve Git bilgilerini gösterir. Maven/Gradle plugin'leri ile otomatik doldurulur.

  • `/metrics` JVM, HTTP, DataSource ve uygulama metriklerini sunar. Tag ile filtreleme yapılabilir.

  • `/loggers` çalışma zamanında log seviyesini değiştirmenize izin verir — yeniden deploy gerektirmez.

  • Güvenlik kritiktir: Actuator'ı ayrı portta çalıştırın, Spring Security ile koruyun, gereksiz endpoint'leri kapatın. Health ve info herkese açık tutulabilir, diğerleri ADMIN rolü gerektirir.


Kubernetes Entegrasyonu

Actuator, Kubernetes ile mükemmel entegre olur. Liveness ve readiness probe'ları otomatik desteklenir:

# application.yml — K8s probe desteğini aktif et
management:
  endpoint:
    health:
      probes:
        enabled: true
      group:
        liveness:
          include: livenessState
          show-details: always
        readiness:
          include: readinessState,db,redis
          show-details: always
# Kubernetes deployment.yaml
spec:
  containers:
    - name: order-service
      image: order-service:latest
      ports:
        - containerPort: 8080
        - containerPort: 9090  # Actuator portu
      
      livenessProbe:
        httpGet:
          path: /actuator/health/liveness
          port: 9090
        initialDelaySeconds: 30
        periodSeconds: 10
        failureThreshold: 3
        # 3 kez başarısız olursa → Pod restart edilir
      
      readinessProbe:
        httpGet:
          path: /actuator/health/readiness
          port: 9090
        initialDelaySeconds: 10
        periodSeconds: 5
        failureThreshold: 3
        # 3 kez başarısız olursa → Pod trafik almayı durdurur
      
      startupProbe:
        httpGet:
          path: /actuator/health/liveness
          port: 9090
        initialDelaySeconds: 5
        periodSeconds: 5
        failureThreshold: 30
        # 30 × 5 = 150 saniye boyunca başlangıcı bekler

Liveness vs Readiness:

  • Liveness: "Uygulama çalışıyor mu?" → Başarısız olursa pod restart edilir

  • Readiness: "Uygulama trafik almaya hazır mı?" → Başarısız olursa pod servis'ten çıkarılır (restart yok)

Liveness basit tutulmalı (deadlock tespiti), readiness ise bağımlılıkları kontrol etmeli (DB, Redis erişilebilir mi?). Readiness'a ağır dış servis kontrolleri koyarsanız, dış servis çöktüğünde TÜM pod'lar trafik almayı durdurur — cascade failure.


Gerçek Dünya: Production Actuator Yapılandırması

# Production-ready Actuator yapılandırması
management:
  server:
    port: 9090                           # Ayrı port
    address: 0.0.0.0                      # Internal VPC erişimi
  
  endpoints:
    web:
      base-path: /actuator
      exposure:
        include: health,info,metrics,prometheus,loggers
        exclude: env,beans,configprops,heapdump,threaddump,shutdown
  
  endpoint:
    health:
      show-details: when-authorized       # Sadece yetkilendirilmiş kullanıcılara
      show-components: when-authorized
      probes:
        enabled: true
    info:
      enabled: true
    loggers:
      enabled: true
    prometheus:
      enabled: true
    shutdown:
      enabled: false                       # Asla production'da aktif etmeyin!
  
  info:
    env:
      enabled: true
    build:
      enabled: true
    git:
      enabled: true
      mode: simple
  
  health:
    defaults:
      enabled: true
    db:
      enabled: true
    redis:
      enabled: true
    diskspace:
      enabled: true
      threshold: 100MB                    # 100 MB altında DOWN

# Uygulama bilgileri
info:
  app:
    name: order-service
    version: '@project.version@'
    environment: ${SPRING_PROFILES_ACTIVE:default}
    description: E-Commerce Order Processing API

Bu yapılandırma ile:

  1. Actuator 9090 portunda çalışır (public 8080'den ayrı)

  2. Sadece gerekli endpoint'ler açık

  3. Health detayları yetkilendirilmiş kullanıcılara gösterilir

  4. Prometheus metrik toplama aktif

  5. Tehlikeli endpoint'ler (shutdown, heapdump) kapalı

  6. Build ve Git bilgileri otomatik eklenir

  7. Disk alanı threshold'u 100MB olarak ayarlanmıştır — bu değer uygulamanın disk kullanımına göre artırılabilir

  8. Custom health indicator'lar ile harici bağımlılıklar (Redis, Elasticsearch, 3rd party API'ler) da izlenebilir