Eğitim Portalı/Spring Boot/Spring Boot Logging (Günlükleme)
Spring Boot03-spring-boot/15-logging

Spring Boot Logging (Günlükleme)

System.out.println hata ayıklamak için yeterli görünür ama üretimde işe yaramaz: seviye yok, zaman damgası yok, kapatılamaz, dosyaya yazılamaz, performansı bozar. Profesyonel uygulamalar logging kullanır. Spring Boot,…

Spring Boot Logging (Günlükleme)

System.out.println hata ayıklamak için yeterli görünür ama üretimde işe yaramaz: seviye yok, zaman damgası yok, kapatılamaz, dosyaya yazılamaz, performansı bozar. Profesyonel uygulamalar logging kullanır. Spring Boot, SLF4J (cephe API) + Logback (uygulama) ile hazır, yapılandırılmış bir günlükleme altyapısı sunar — hiçbir bağımlılık eklemene gerek kalmadan.

SLF4J ile logger almak

Her sınıf kendi logger'ını alır (genelde sınıf adıyla):

private static final Logger log = LoggerFactory.getLogger(Ornek1.class);

SLF4J bir cephe (facade) API'sidir; arkasındaki uygulama (Logback) değişse de kodun değişmez. (Lombok kullanıyorsan @Slf4j anotasyonu bu satırı otomatik üretir.)

Log seviyeleri

En ayrıntılıdan en kritiğe doğru bir hiyerarşi vardır; ayarlanan seviye ve üstü görünür:

TRACE  <  DEBUG  <  INFO  <  WARN  <  ERROR
SeviyeNe zaman
TRACEÇok ayrıntılı iz (nadiren)
DEBUGGeliştirme/teşhis ayrıntısı
INFONormal akış olayları (varsayılan görünür seviye)
WARNBeklenmedik ama kurtarılabilir durum
ERRORHata; işlem başarısız

Örnek 1 (./Ornek1.java) tüm seviyeleri, parametreli loglamayı ve istisna loglamayı gösterir.

Parametreli loglama: {}

String birleştirme yerine yer tutucu kullan:

log.info("Kullanıcı {} {}. kez giriş yaptı", kullanici, deneme);   // İYİ
log.info("Kullanıcı " + kullanici + " giriş yaptı");                // KÖTÜ

Neden? {} tembeldir: log seviyesi kapalıysa string hiç oluşturulmaz (performans). Ayrıca daha okunaklı ve güvenlidir. İstisnayı son argüman olarak verirsen stack trace otomatik basılır: log.error("Başarısız", e).

Yapılandırma

application.properties ile seviyeleri ve çıktıyı ayarlarsın:

logging.level.root=INFO                         # genel seviye
logging.level.com.egitim=DEBUG                  # belirli paket için DEBUG
logging.level.org.springframework.web=WARN
logging.file.name=uygulama.log                  # dosyaya yaz
logging.pattern.console=%d{HH:mm:ss} %-5level %logger - %msg%n

Örnek 1, logging.level.com.egitim.springboot.logging=DEBUG ile DEBUG mesajlarını görünür kılar.

Üretimde günlükleme

  • Yapılandırılmış (JSON) loglama: Log toplama sistemleri (ELK, Loki, Datadog) için JSON formatı; sorgulama/filtreleme kolaylaşır.
  • Korelasyon (trace) kimliği: Her isteğe bir id ekle (MDC / filter — topic 12) → dağıtık sistemde bir isteğin tüm loglarını birbirine bağla.
  • Seviye yönetimi: Üretimde INFO/WARN; sorun anında belirli paketi DEBUG'a çek (Actuator ile çalışırken bile değiştirilebilir — topic 06).
  • Hassas veri loglama! Parola, token, kişisel veri loglanmaz.

Özet

Spring Boot'un SLF4J + Logback ile hazır günlükleme altyapısını öğrendik: logger alma, log seviyeleri (TRACE→ERROR), tembel parametreli loglama ({}) ve istisna loglama (Örnek 1); application.properties ile yapılandırma ve üretim pratiklerini (JSON, trace id, hassas veri) gördük. println yerine her zaman logger kullan. Sırada, başka servislerin API'lerini çağırmak: REST tüketimi (RestClient/RestTemplate).

Kod Örnekleri(1)

Ornek1

ortam gerekir
Ornek1.java
1// Ornek1: Logging — SLF4J + Logback (Spring Boot'un yerleşik günlükleme altyapısı).
2// Çalıştırma: portal gömülü Tomcat ile başlatır, log çıktıları görünür.
3package com.egitim.springboot.logging;
4
5import org.slf4j.Logger;
6import org.slf4j.LoggerFactory;
7import org.springframework.boot.CommandLineRunner;
8import org.springframework.boot.autoconfigure.SpringBootApplication;
9import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
10import org.springframework.boot.builder.SpringApplicationBuilder;
11import org.springframework.context.annotation.Bean;
12
13@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
14public class Ornek1 {
15
16    // Her sınıf kendi logger'ını alır (sınıf adıyla). System.out.println YERİNE bunu kullan.
17    private static final Logger log = LoggerFactory.getLogger(Ornek1.class);
18
19    public static void main(String[] args) {
20        // Log seviyesini programatik ayarla (gerçekte: logging.level.com.egitim=DEBUG application.properties'te).
21        new SpringApplicationBuilder(Ornek1.class)
22                .properties("logging.level.com.egitim.springboot.logging=DEBUG")
23                .run(args);
24    }
25
26    @Bean
27    CommandLineRunner selfTest() {
28        return args -> {
29            System.out.println("\n========= LOGGING SELF-TEST =========");
30
31            // Log SEVİYELERİ (en ayrıntılıdan en kritiğe): TRACE < DEBUG < INFO < WARN < ERROR
32            log.trace("TRACE: çok ayrıntılı (varsayılan gizli)");
33            log.debug("DEBUG: geliştirme ayrıntısı (seviye DEBUG'a çekildi -> görünür)");
34            log.info("INFO: normal akış bilgisi — uygulama {} modunda başladı", "üretim");
35            log.warn("WARN: dikkat — disk %{} dolu", 85);
36            log.error("ERROR: hata — bağlantı kurulamadı: {}", "timeout");
37
38            // PARAMETRELİ loglama ({}): string birleştirmeden DAHA İYİ (tembel, hızlı, güvenli).
39            String kullanici = "ada"; int deneme = 3;
40            log.info("Kullanıcı {} {}. kez giriş yaptı", kullanici, deneme);
41
42            // İstisna loglama: mesaj + exception (stack trace otomatik basılır).
43            try { throw new IllegalStateException("örnek hata"); }
44            catch (Exception e) { log.error("İşlem başarısız oldu", e); }
45
46            System.out.println("=====================================");
47        };
48    }
49}
canlı çalıştırma için ortam gerekir

Bu örnek Spring / Spring Boot (Gradle) ortamı gerektirir; tek dosya olarak java Ornek1.java ile çalışmaz. Orijinal portal bunu gömülü Tomcat / Spring context ile koşuyordu. Beklenen davranış yukarıdaki anlatım ve kodda açıklanmıştır.