Gereksinimler ve Ön Hazırlık
Başarılı bir loglama sistemi kurmak için öncelikle geliştirme ortamınızın hazır olması gerekir. Windows uygulamalarında hata yönetimi için standart kütüphaneler dışında, endüstri standardı olan "Serilog" gibi güçlü kütüphaneleri kullanmanızı öneririm. Ancak, temel mantığı anlamak için önce kendi basit loglama sınıfımızı oluşturacağız.
- Visual Studio 2022 veya 2025 sürümü.
- .NET 8 veya .NET 9 SDK yüklü olmalıdır.
- Temel düzeyde C# nesne yönelimli programlama (OOP) bilgisi.
- Dosya sistemi (IO) erişim izinleri.
Adım 1: Temel Hata Loglama Sınıfını Oluşturma
Loglama sistemimizin merkezinde, hataları metin dosyasına yazan bir yardımcı sınıf (helper class) yer alacaktır. Bu sınıfın "Singleton" tasarım desenine uygun olması, uygulamanın her yerinden tek bir noktaya log yazılmasını sağlar.
public class Logger
{
private static readonly string LogFilePath = "logs.txt";
public static void LogError(string message, Exception ex)
{
string logEntry = $"{DateTime.Now}: HATA - {message} | Detay: {ex.Message} {Environment.NewLine}";
System.IO.File.AppendAllText(LogFilePath, logEntry);
}
}
Yukarıdaki kod, System.IO kütüphanesini kullanarak her hatayı zaman damgasıyla birlikte logs.txt dosyasına ekler. AppendAllText metodu, dosya yoksa oluşturur, varsa sonuna ekleme yapar.
Adım 2: Global Hata Yakalama Mekanizması
Windows uygulamalarında her bir buton tıklaması için ayrı try-catch blokları yazmak yerine, uygulamanın genelinde gerçekleşen ve yakalanamayan hataları tek bir merkezden yönetmelisiniz. Bunun için App.xaml.cs veya Program.cs içerisinde "UnhandledException" olayını dinlememiz gerekir.
static void Main()
{
Application.ThreadException += (s, e) => Logger.LogError("Thread Hatası", e.Exception);
AppDomain.CurrentDomain.UnhandledException += (s, e) => Logger.LogError("Beklenmedik Hata", (Exception)e.ExceptionObject);
Application.Run(new MainForm());
}
Bu yapı, uygulamanızın herhangi bir yerinde unutulan bir hata bile olsa, uygulamanın sessizce kapanmasını engeller ve hatayı log dosyasına yazar. ThreadException arayüz (UI) thread'indeki hataları, UnhandledException ise arka plan thread'lerindeki hataları yakalar.
Adım 3: Logları Kategorize Etme ve Seviyelendirme
Her hata aynı önem derecesine sahip değildir. Bazıları sadece bir uyarıyken, bazıları uygulamanın çalışmasını durduran kritik hatalardır. Loglama sisteminizi geliştirerek "Bilgi", "Uyarı" ve "Hata" seviyeleri eklemelisiniz.
public enum LogLevel { Info, Warning, Error }
public static void WriteLog(string message, LogLevel level)
{
string logEntry = $"[{DateTime.Now}] [{level}] - {message}{Environment.NewLine}";
System.IO.File.AppendAllText("app_log.txt", logEntry);
}
Bu yöntemle, log dosyanızda arama yaparken sadece [Error] etiketine sahip satırları filtreleyerek hata analizinizi hızlandırabilirsiniz.
Karşılaştırma: Loglama Yöntemleri
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Metin Dosyası (txt) | Basit, hızlı, ek kütüphane gerektirmez. | Büyük dosyalarda okuması zor, performans düşebilir. |
| Serilog (Kütüphane) | Yapılandırılmış loglama (JSON), gelişmiş filtreleme. | Öğrenme eğrisi ve ek bağımlılık. |
| Windows Event Viewer | Sistemle entegre, merkezi yönetim. | Yönetici yetkisi gerektirir, karmaşık yapı. |
Adım 4: Güvenli Loglama ve Dosya Kilitleme Sorunları
Dosya tabanlı loglamada en sık karşılaşılan sorun, uygulamanın log dosyasını aynı anda iki farklı yerden yazmaya çalışmasıdır. Bunu önlemek için "lock" anahtar kelimesini kullanmalısınız.
private static readonly object _fileLock = new object();
public static void SafeLog(string message)
{
lock (_fileLock)
{
System.IO.File.AppendAllText("logs.txt", message + Environment.NewLine);
}
}
Kritik Uyarı: Log dosyalarına asla kullanıcı şifreleri, kredi kartı bilgileri veya kişisel verileri (PII) yazmayın. Bu, ciddi bir güvenlik açığına ve KVKK ihlaline yol açabilir. Log dosyalarını düzenli olarak temizleyen bir "Log Rotation" mekanizması kurmayı unutmayın.
Adım 5: Hata Loglarını Test Etme
Sistemin çalışıp çalışmadığını test etmek için kasten bir hata tetiklemelisiniz. Örneğin, sıfıra bölme hatası veya var olmayan bir dosyayı açmaya çalışma gibi durumlar ideal test senaryolarıdır.
try
{
int x = 10;
int y = 0;
int sonuc = x / y;
}
catch (Exception ex)
{
Logger.LogError("Matematiksel işlem hatası", ex);
}
Bu kod bloğu çalıştırıldığında, logs.txt dosyasını açıp hatanın detaylı bir şekilde kaydedildiğini doğrulamalısınız. Eğer dosya oluşmuyorsa, uygulamanın bulunduğu dizine yazma izninizin olup olmadığını kontrol edin.
Sıkça Sorulan Sorular
Log dosyası çok büyürse ne yapmalıyım?
Log dosyalarınızın boyutunu kontrol eden bir mekanizma kurun. Örneğin, dosya boyutu 5MB'ı geçtiğinde mevcut dosyayı arşivleyip yeni bir dosya oluşturun.
Neden Serilog veya NLog gibi kütüphaneler kullanmalıyım?
Bu kütüphaneler, asenkron yazma, veritabanına log gönderme ve logları bulut servislerine (Elasticsearch, Seq vb.) aktarma gibi gelişmiş özellikleri hazır olarak sunar.
Loglama performansı etkiler mi?
Evet, her log kaydı disk I/O işlemi gerektirir. Bu nedenle "asenkron loglama" yöntemlerini tercih etmelisiniz.
Kullanıcıya hata mesajı göstermeli miyim?
Teknik detayları (stack trace) kullanıcıya göstermek güvenlik zafiyetidir. Kullanıcıya "Bir hata oluştu, lütfen destek ekibiyle iletişime geçin" gibi genel bir mesaj gösterin, teknik detayı ise log dosyasına yazın.
Log dosyası şifrelenmeli mi?
Eğer log dosyası hassas veriler içerebilecek bir ortamdaysa, dosyayı şifrelemek veya erişim izinlerini kısıtlamak iyi bir güvenlik pratiğidir.
İleri Seviye: Log Verilerini JSON Formatında Yapılandırma
Geleneksel metin tabanlı loglama (plain text), log analizi yapan araçlar (ELK Stack, Splunk veya Graylog gibi) için işlenmesi zor bir formattır. Log verilerinizi JSON formatında tutmak, bu verilerin yapılandırılmış (structured) olmasını sağlar ve sorgulanabilirliğini artırır. Aşağıdaki örnek, bir hata nesnesini JSON formatına dönüştürerek dosyaya yazan bir yardımcı metot yapısını göstermektedir.
using System.Text.Json;
using System.IO;
public static class JsonLogger
{
public static void LogAsJson(string message, string level, Exception ex = null)
{
var logEntry = new
{
Timestamp = DateTime.Now,
Level = level,
Message = message,
Exception = ex?.Message,
StackTrace = ex?.StackTrace,
MachineName = Environment.MachineName
};
string jsonLog = JsonSerializer.Serialize(logEntry);
File.AppendAllText("app_logs.json", jsonLog + Environment.NewLine);
}
}
Bu yapı sayesinde, log dosyalarınızı bir veritabanına aktarırken veya bir dashboard üzerinde görselleştirirken çok daha hızlı sonuç alırsınız. Özellikle MachineName gibi meta verileri eklemek, dağıtık sistemlerde hatanın hangi istemciden kaynaklandığını bulmanızı kolaylaştırır.
Loglama Performansını Optimize Etme: Asenkron Yazma
Uygulamanızın ana iş parçacığı (UI thread) üzerinde dosya yazma işlemi yapmak, özellikle yoğun loglama yapılan durumlarda "donma" hissine yol açabilir. Bu sorunu aşmak için Task.Run veya Channel yapısını kullanarak loglama işlemlerini arka plana atmalısınız.
Aşağıdaki örnekte, logları bir kuyruğa (queue) atan ve arka planda işleyen asenkron bir yaklaşım sergilenmiştir:
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class AsyncLogger
{
private static readonly BlockingCollection logQueue = new BlockingCollection();
static AsyncLogger()
{
Task.Run(() =>
{
foreach (var log in logQueue.GetConsumingEnumerable())
{
File.AppendAllText("async_logs.txt", log + Environment.NewLine);
}
});
}
public static void EnqueueLog(string message)
{
logQueue.Add(message);
}
}
Performans İpuçları ve En İyi Uygulamalar
- Tampon Bellek Kullanımı: Çok sık log yazıyorsanız, her satırda diske erişmek yerine logları bir tampon bellekte (buffer) biriktirip belirli aralıklarla dosyaya yazın.
- Log Seviyesi Filtreleme: Üretim ortamında
DebugveyaTraceseviyesindeki logları devre dışı bırakarak disk ve CPU kullanımını minimize edin. - Dosya Boyutu Sınırı: Log dosyalarınızın boyutunu takip edin ve belirli bir MB değerine ulaştığında dosyayı arşivleyerek yeni bir dosya oluşturun (Rolling File stratejisi).
- Veri Hassasiyeti: Log dosyalarına asla kullanıcı şifreleri, kredi kartı bilgileri veya kişisel verileri (KVKK kapsamında) açık metin olarak yazmayın.
Profesyonel Not: Uygulamanız büyüdükçe, kendi loglama altyapınızı yazmak yerine endüstri standardı olan Serilog veya NLog gibi kütüphanelere geçiş yapmanız önerilir. Bu kütüphaneler, yukarıda bahsettiğimiz asenkron yazma, JSON formatlama ve dosya rotasyonu gibi işlemleri zaten optimize edilmiş bir şekilde sunar.
Sonuç
C# ile Windows uygulaması için hata loglama sistemi kurmak, uygulamanızın profesyonellik seviyesini belirleyen en önemli adımdır. Bu rehberde öğrendiğiniz temel yöntemlerle, hataları takip edebilir ve kullanıcılarınızın yaşadığı sorunları hızlıca çözebilirsiniz. Bir sonraki adım olarak, loglarınızı merkezi bir sunucuya gönderen veya log dosyalarını JSON formatında tutarak analiz araçlarıyla görselleştiren daha gelişmiş bir yapıya geçiş yapabilirsiniz. Kodlarınızı her zaman temiz tutun ve hata yönetimini bir alışkanlık haline getirin.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce, hata yönetim mekanizmalarını güvenlik duvarı ve veri gizliliği standartlarına uygun şekilde yapılandırmanız ve gerekli testleri yapmanız sorumluluğunuzdadır.


Yorumlar (0)
Yorum Yaz