Uygulama Log Seviyeleri ve Önemi
Bir uygulamayı geliştirirken veya mevcut bir sistemi yönetirken karşılaştığımız en temel konulardan biri, uygulamanın çalışma durumunu anlamamızı sağlayan loglama mekanizmalarıdır. Loglar, hataları ayıklama, performans sorunlarını tespit etme ve sistemin genel sağlığını izleme açısından hayati öneme sahiptir. Ancak, logların ne kadar detaylı olacağı ve hangi bilgilerin kaydedileceği konusunda doğru kararları vermek, sistemin verimliliğini doğrudan etkiler.
Özellikle DEBUG ve INFO gibi sık kullanılan log seviyeleri, geliştiricilerin en çok karşılaştığı ve bazen de karıştırdığı seviyelerdir. DEBUG seviyesi, uygulamanın en detaylı iç işleyişini gösterirken, INFO seviyesi daha çok genel operasyonel bilgileri içerir. Bu iki seviyenin doğru şekilde kullanılması, hem geliştirme sürecinde hız kazandırır hem de üretim ortamında gereksiz log yükünü engelleyerek performans kaybını önler. Bu yazıda, DEBUG ve INFO log seviyelerini ne zaman ve nasıl kullanmamız gerektiğini, somut örneklerle ve gerçek saha tecrübelerimden yola çıkarak açıklayacağım.
DEBUG Log Seviyesi: Detayın Dibine İnmek
DEBUG log seviyesi, bir uygulamanın en ince ayrıntılarını, değişkenlerin değerlerini, fonksiyon çağrılarını ve kodun akışını adım adım takip etmek için kullanılır. Bu seviye, genellikle geliştirme ve hata ayıklama (debugging) aşamasında aktif olarak kullanılır. Üretim ortamında DEBUG seviyesinin sürekli açık kalması, muazzam miktarda log verisi üreterek disk alanını hızla tüketebilir ve I/O performansını ciddi şekilde düşürebilir.
Örneğin, bir kullanıcı kaydı işlemi sırasında, DEBUG seviyesi şu bilgileri kaydedebilir: Kullanıcının girdiği e-posta adresi, şifrenin hash’lenmeden önceki hali (bu asla kaydedilmemeli!), veritabanına gönderilen SQL sorgusunun tam metni, veritabanından dönen yanıtın detayları, kullanılan fonksiyonların çalışma süreleri ve hatta bellek kullanımındaki anlık değişimler. Bu tür detaylı bilgiler, bir hatanın tam olarak nerede ve nasıl meydana geldiğini anlamak için paha biçilmezdir. Bir DEBUG log örneği şu şekilde görünebilir:
2026-05-16 03:15:22.123 DEBUG [com.example.user.service.UserService:registerUser] - Entering registerUser method with email: [email protected]
2026-05-16 03:15:22.125 DEBUG [com.example.user.service.UserService:hashPassword] - Hashing password for user: [email protected]
2026-05-16 03:15:22.130 DEBUG [com.example.user.repository.UserRepository:saveUser] - Executing SQL: INSERT INTO users (email, password_hash, created_at) VALUES (?, ?, ?) with params: ['[email protected]', 'hashed_password_string', '2026-05-16 03:15:22.130']
2026-05-16 03:15:22.150 DEBUG [com.example.user.repository.UserRepository:saveUser] - User saved successfully. User ID: 12345
2026-05-16 03:15:22.155 DEBUG [com.example.user.service.UserService:registerUser] - Exiting registerUser method. User ID: 12345
Bu detay seviyesi, özellikle karmaşık iş mantığına sahip uygulamalarda, bir hatanın kök nedenini bulmak için gereklidir. Örneğin, bir e-ticaret sitesinde sepete ekleme işlemi sırasında karşılaşılan bir hatada, DEBUG logları sayesinde hangi ürün ID’sinin, hangi kullanıcının sepetine eklenmeye çalışıldığı, stok kontrolünün hangi aşamada başarısız olduğu gibi bilgilere ulaşabiliriz. Bu, sorunun kaynağını manuel olarak kod satırları arasında aramak yerine, loglardan doğrudan tespit etmemizi sağlar.
INFO Log Seviyesi: Operasyonel Günlükler
INFO log seviyesi, uygulamanın normal operasyonel durumu hakkında anlamlı bilgiler sunar. Bu seviye, uygulamanın beklenen şekilde çalıştığını gösteren olayları kaydetmek için kullanılır. DEBUG seviyesinin aksine, INFO logları genellikle üretim ortamında açık bırakılır çünkü sistemin genel sağlığı ve iş akışları hakkında değerli bilgiler sağlarlar ve genellikle makul miktarda veri üretirler.
Bir INFO log örneği, bir kullanıcının başarıyla giriş yapması, bir işlemin tamamlanması veya bir servisin yeniden başlatılması gibi olayları içerebilir. Bu bilgiler, uygulamanın genel durumunu anlamak, belirli bir iş akışının başarıyla tamamlanıp tamamlanmadığını doğrulamak ve sistemdeki anormallikleri erken tespit etmek için kullanılır.
Örneğin, bir finansal işlem uygulamasında INFO logları şu şekilde görünebilir:
2026-05-16 03:17:05.500 INFO [com.example.transaction.service.TransactionService:processPayment] - Payment processed successfully for transaction ID: TXN789012. Amount: 150.75 USD. Customer: John Doe.
2026-05-16 03:17:06.100 INFO [com.example.user.auth.AuthenticationService:login] - User 'admin' logged in successfully from IP address: 192.168.1.100.
2026-05-16 03:18:30.000 INFO [com.example.scheduler.JobScheduler:startJob] - Scheduled job 'daily_report_generator' started at 03:18:30.
Bu tür loglar, bir raporun başarıyla oluşturulduğunu, bir kullanıcının sisteme erişim sağladığını veya bir işlemin tamamlandığını gösterir. Bir üretim ERP sisteminde, INFO logları bir siparişin onaylandığını, bir sevkiyatın yapıldığını veya bir faturanın kesildiğini belirtebilir. Bu bilgiler, iş süreçlerinin takibi ve denetimi için kritik öneme sahiptir. INFO seviyesi, hata ayıklama için yeterince detaylı olmasa da, uygulamanın genel işleyişini anlamak için temel bir veri seti sunar.
Trade-off’lar: DETAY vs. PERFORMANS
DEBUG ve INFO log seviyeleri arasındaki seçim, temel olarak bir trade-off meselesidir: daha fazla detay, daha fazla performans maliyeti anlamına gelir. DEBUG seviyesi, bir olayın her adımını kaydederek inanılmaz bir detay sunar, ancak bu detaylı kayıtlar yüksek miktarda veri üretir. Bu durum, disk G/Ç (I/O) işlemlerini artırır, işlemciyi daha fazla meşgul eder ve sonuç olarak uygulamanın genel performansını düşürebilir.
Örneğin, bir web uygulamasında her isteğin işlenmesi sırasında onlarca hatta yüzlerce DEBUG log satırı üretilebilir. Eğer bu uygulama günde milyonlarca istek alıyorsa, log dosyalarının boyutu hızla terabaytları bulabilir. Bu durum, logları analiz etmeyi zorlaştırır, depolama maliyetlerini artırır ve log toplama/işleme altyapısını (örn. ELK Stack, Grafana Loki) zorlayabilir. DEBUG loglarının üretimde sürekli açık bırakıldığı yoğun trafikli servislerde, INFO seviyesine kıyasla belirgin bir performans düşüşü görmek olağandır.
Buna karşılık, INFO seviyesi daha sınırlı bilgi içerir. Bu, daha az veri üretilmesi anlamına gelir ve dolayısıyla daha az performans maliyeti getirir. INFO logları, uygulamanın genel işleyişini anlamak için yeterli bilgiyi sağlarken, sistem üzerinde kabul edilebilir bir yük oluşturur. Bu nedenle, üretim ortamlarında genellikle INFO, WARN ve ERROR gibi daha üst seviyeler kullanılırken, DEBUG seviyesi yalnızca belirli bir hata ayıklama senaryosu için geçici olarak etkinleştirilir.
Hangi Durumda Hangi Seviye? Gerçek Hayat Senaryoları
Log seviyesi seçimi, uygulamanın türüne, geliştirme aşamasına ve mevcut operasyonel gereksinimlere göre değişiklik gösterir. İşte birkaç gerçek hayat senaryosu:
Senaryo 1: Yeni Bir Özellik Geliştirme
Yeni bir ödeme gateway entegrasyonu geliştiriyorum. Bu özellik karmaşık ve hassas. Geliştirme sırasında, entegrasyonun her adımını, gönderilen ve alınan verileri, timeout durumlarını ve hata kodlarını detaylı olarak görmek istiyorum. Bu aşamada DEBUG seviyesini aktif tutmak, sorunun kaynağını hızla bulmamı sağlar.
// Varsayımsal DEBUG log örneği:
2026-05-16 04:05:10.100 DEBUG [com.example.payment.gateway.StripeAdapter:processPayment] - Sending payment request to Stripe: { "amount": 10000, "currency": "USD", "card_token": "tok_..." }
2026-05-16 04:05:11.500 DEBUG [com.example.payment.gateway.StripeAdapter:processPayment] - Received response from Stripe: { "status": "succeeded", "transaction_id": "pi_..." }
Ancak, bu özelliğin üretim ortamına ilk çıkışında, DEBUG seviyesini kapatıp INFO seviyesine çekeceğim. Sadece ödemenin başarıyla işlendiğini veya bir hata oluştuğunu görmek benim için yeterli olacaktır.
Senaryo 2: Üretimdeki Bir Serviste Anlık Hata
Birkaç gündür, müşteri hizmetleri için kullandığımız bir uygulamanın ara sıra yanıt vermediğini fark ettim. WARN ve ERROR loglarında belirgin bir hata görünmüyor. Bu durumda, sorunun kaynağını anlamak için geçici olarak DEBUG seviyesini açıp, sorunun yaşandığı anı yakalamaya çalışacağım. Belki bir veritabanı sorgusu beklenenden uzun sürüyor, belki bir dış API’ye yapılan çağrı takılıyor. DEBUG logları bu tür gizli sorunları ortaya çıkarabilir.
// Varsayımsal DEBUG log örneği:
2026-05-16 04:10:00.000 DEBUG [com.example.crm.service.TicketService:getTicketDetails] - Fetching ticket details for ticket ID: 98765
2026-05-16 04:10:15.500 DEBUG [com.example.crm.service.TicketService:getTicketDetails] - Database query for ticket 98765 completed.
Sorgunun başlangıç ve bitiş zaman damgaları arasındaki fark, beklenenden çok daha uzun bir gecikmeyi ortaya koyuyorsa bu kabul edilemez bir durumdur. Bu bilgiyi elde ettikten sonra, veritabanı optimizasyonuna veya sorgunun yeniden yazılmasına odaklanabilirim. Sorun çözüldüğünde, DEBUG seviyesini tekrar kapatacağım.
Senaryo 3: Operasyonel Durum Takibi
Bir üretim ERP sisteminin günlük raporlama modülünü izliyorum. Bu modülün her gün saat 05:00’te başarıyla çalışıp çalışmadığını bilmem gerekiyor. Bu bilgi için INFO seviyesi yeterlidir.
// Varsayımsal INFO log örneği:
2026-05-16 05:00:01.200 INFO [com.example.erp.reporting.ReportGenerator:generateDailySales] - Daily sales report generation started.
2026-05-16 05:05:30.800 INFO [com.example.erp.reporting.ReportGenerator:generateDailySales] - Daily sales report generated successfully. File path: /var/log/erp/reports/daily_sales_20260516.pdf
Eğer bu rapor oluşturulmazsa veya bir hata oluşursa, WARN veya ERROR seviyeleri devreye girecektir. DEBUG seviyesine bu senaryoda ihtiyacım yok.
Loglama Yapılandırması ve Araçları
Log seviyelerini yönetmek için kullanılan araçlar ve yapılandırmalar, kullanılan programlama dili ve framework’e göre değişiklik gösterir. Örneğin, Java’da Logback veya Log4j, Python’da ise logging modülü yaygın olarak kullanılır. Bu araçlar genellikle bir yapılandırma dosyası (örn. logback.xml, logging.conf) aracılığıyla log seviyelerinin ayarlanmasına olanak tanır.
Bu yapılandırma dosyalarında, hangi loglayıcıların (logger) hangi seviyede log üreteceği belirlenir. Örneğin, tüm uygulama için varsayılan seviye INFO olarak ayarlanabilirken, belirli paketler veya sınıflar için DEBUG seviyesi etkinleştirilebilir. Bu, log seviyesini daha granüler bir şekilde kontrol etmemizi sağlar.
# Örnek logback.xml yapılandırması
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example.payment" level="DEBUG"/> <!-- Ödeme modülü için DEBUG seviyesi -->
<logger name="com.example.user" level="INFO"/> <!-- Kullanıcı modülü için INFO seviyesi -->
<root level="INFO"> <!-- Genel seviye INFO -->
<appender-ref ref="STDOUT" />
</root>
</configuration>
Bu tür yapılandırmalar sayesinde, üretim ortamında bile belirli modüller için geçici olarak daha detaylı loglama etkinleştirmek mümkün hale gelir. Bu, hem sistemin genel performansını korur hem de gerektiğinde derinlemesine hata ayıklama imkanı sunar.
İleri Loglama Teknikleri ve En İyi Uygulamalar
Loglama sadece neyi kaydettiğimizle ilgili değildir; aynı zamanda bilgiyi nasıl yapılandırdığımız, topladığımız ve analiz ettiğimizle de ilgilidir. DEBUG ve INFO seviyelerinin doğru kullanımı, daha geniş bir loglama stratejisinin parçası olmalıdır.
Bir diğer önemli nokta, log mesajlarının içeriğidir. DEBUG mesajları bile, neyin kaydedildiği hakkında yeterli bağlamı sağlamalıdır. Örneğin, sadece “Veritabanı hatası” demek yerine, “Kullanıcı tablosuna veri eklenirken PRIMARY KEY ihlali: email ‘[email protected]’ zaten mevcut.” gibi daha açıklayıcı mesajlar yazılmalıdır. Bu, özellikle DEBUG seviyesindeki bilgileri incelerken hatanın nedenini anlamayı kolaylaştırır.
Ayrıca, logları merkezi bir sistemde toplamak (örn. Elasticsearch, Splunk, Loki) ve bu logları analiz etmek için araçlar kullanmak, sorunları daha hızlı tespit etmemize yardımcı olur. Bu sistemler, log seviyelerine göre filtreleme, zaman serisi analizi ve anomali tespiti gibi özellikler sunar. Bu sayede, bir ERROR seviyesindeki logu kaçırmak yerine, sistem genelindeki eğilimleri ve olası sorunları proaktif olarak görebiliriz.
Son olarak, loglama stratejisi uygulamanın yaşam döngüsü boyunca evrimleşmelidir. Başlangıçta DEBUG seviyesinde yoğun geliştirme yapılırken, üretim ortamına geçildikçe bu seviye düşürülmeli, ancak kritik modüller için belirli DEBUG loglarının belirli koşullar altında etkinleştirilebilmesi için mekanizmalar korunmalıdır. Daha önce de bahsettiğim gibi, my-observability-journey yazımda bu konuya daha derinlemesine değindim. Bu dengeli yaklaşım, hem geliştirme verimliliğini hem de üretim ortamının stabilitesini sağlamanın anahtarıdır.
Sonuç: Akıllıca Loglama Yapmak
DEBUG ve INFO log seviyeleri, bir uygulamanın yaşamsal belirtileridir. DEBUG, sorunun kök nedenini bulmak için bir mikroskop görevi görürken, INFO, sistemin genel sağlığını ve normal işleyişini gösteren bir nabızdır. Bu iki seviyenin doğru ve stratejik kullanımı, geliştirme sürecini hızlandırır, üretim ortamındaki sorunları daha kolay tespit etmemizi sağlar ve sistem performansını optimize etmemize yardımcı olur.
Unutulmamalıdır ki, aşırı detaylı loglama (özellikle DEBUG seviyesinin üretimde sürekli açık olması) sistem performansını olumsuz etkileyebilir ve maliyetleri artırabilir. Bu nedenle, her zaman bir denge kurmak esastır: geliştirme aşamasında detaya inmekten çekinmeyin, ancak üretim ortamında yalnızca gerçekten gerekli olan bilgileri kaydedin. Log seviyelerini akıllıca yapılandırarak ve en iyi uygulamaları takip ederek, daha sağlam, daha performanslı ve daha yönetilebilir uygulamalar geliştirebiliriz.