C# İle Windows Servis Loglama Sistemi Nasıl Yapılır?

C# İle Windows Servis Loglama Sistemi Nasıl Yapılır?
C# İle Windows Servis Loglama Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. Windows servisleri için .NET 8 veya .NET 9 SDK kullanmanız önerilir. Ayrıca loglama işlemleri için endüstri standardı olan Serilog kütüphanesini kullanacağız.

  • Visual Studio 2022 (Sürüm 17.12 veya üzeri)
  • .NET 9 SDK
  • Serilog ve Serilog.Sinks.File NuGet paketleri

Projenize gerekli paketleri eklemek için Terminal veya Package Manager Console üzerinden şu komutu çalıştırabilirsiniz:

dotnet add package Serilog.Extensions.Hosting
dotnet add package Serilog.Sinks.File

Adım 1: Serilog Yapılandırmasını Oluşturma

Windows servislerinde varsayılan EventLog yerine dosya tabanlı bir loglama sistemi kullanmak, verilerin daha hızlı sorgulanmasını sağlar. İlk adım olarak, programın giriş noktasında loglama konfigürasyonunu tanımlamalıyız.

using Serilog;

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.File("logs/servis-log-.txt", rollingInterval: RollingInterval.Day)
            .CreateLogger();

        try
        {
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Servis başlatılırken kritik hata oluştu.");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

Burada rollingInterval: RollingInterval.Day parametresi, log dosyalarının her gün otomatik olarak yeni bir isimle (tarih bazlı) oluşturulmasını sağlar. Bu, dosya boyutlarının yönetilebilir kalması için kritiktir.

Adım 2: Windows Servisine Loglama Entegrasyonu

Servis sınıfınızın içerisinde loglama mekanizmasını kullanmak için Dependency Injection (Bağımlılık Enjeksiyonu) yöntemini kullanmalısınız. Bu sayede loglama arayüzünü her sınıfa kolayca aktarabilirsiniz.

public class Worker : BackgroundService
{
    private readonly ILogger _logger;

    public Worker(ILogger logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Servis başarıyla başlatıldı: {time}", DateTimeOffset.Now);
        
        while (!stoppingToken.IsCancellationRequested)
        {
            // İş mantığı buraya gelecek
            await Task.Delay(1000, stoppingToken);
        }
    }
}

ILogger arayüzü, .NET'in yerleşik loglama altyapısı ile Serilog'u birleştirir. LogInformation gibi metodlar, uygulamanın normal akışını izlemek için kullanılır.

Loglama Yöntemlerinin Karşılaştırılması

Windows servislerinde loglama yaparken tercih edebileceğiniz yöntemlerin avantaj ve dezavantajlarını aşağıda inceleyebilirsiniz.

Yöntem Avantaj Dezavantaj
Dosya (Flat File) Hızlı, basit, taşınabilir Büyük veride arama zor
Windows Event Log Sistemle entegre Kısıtlı format desteği
Merkezi (Seq/ELK) Gelişmiş analiz ve dashboard Kurulum maliyeti

Adım 3: Hata Yönetimi ve İstisna Loglama

Servis içerisinde beklenmedik hataları yakalamak için try-catch bloklarında mutlaka loglama yapmalısınız. Hataları loglarken sadece mesajı değil, hatanın tipini ve stack trace bilgisini de kaydetmek hata ayıklama sürecini hızlandırır.

try
{
    // Riskli işlem
    var result = 10 / int.Parse("0");
}
catch (DivideByZeroException ex)
{
    _logger.LogError(ex, "Matematiksel hata oluştu: {Message}", ex.Message);
}
catch (Exception ex)
{
    _logger.LogCritical(ex, "Beklenmedik bir sistem hatası!");
}

LogCritical seviyesi, servisin durmasına neden olabilecek veya acil müdahale gerektiren durumlar için ayrılmalıdır. LogError ise iş mantığındaki hatalar için kullanılır.

Adım 4: Performans İçin Asenkron Loglama

Windows servisleri arka planda sürekli çalıştığı için loglama işleminin servisin ana iş akışını yavaşlatmaması gerekir. Serilog'un asenkron (async) modunu aktif ederek loglama işlemlerini ayrı bir thread üzerinde çalıştırabilirsiniz.

Log.Logger = new LoggerConfiguration()
    .WriteTo.Async(a => a.File("logs/servis-log-.txt"))
    .CreateLogger();

WriteTo.Async kullanımı, dosya yazma işlemlerinin I/O (Girdi/Çıktı) darboğazı yaratmasını engeller. Bu, özellikle yüksek trafikli servislerde kritik bir performans iyileştirmesidir.

Adım 5: Log Dosyası Güvenliği ve İzinler

Kritik Uyarı: Log dosyalarınızda asla kullanıcı şifreleri, kredi kartı bilgileri veya kişisel verileri (KVKK kapsamındaki veriler) düz metin olarak saklamayın. Log dosyalarının bulunduğu klasörün izinlerini, sadece "SYSTEM" ve "Administrators" grubunun erişebileceği şekilde sınırlandırın.

Uygulama klasörüne erişim yetkilerini kod içerisinden kontrol etmek yerine, servis kurulum aşamasında Windows ACL (Access Control List) ayarlarını yapılandırmanız önerilir.

Sıkça Sorulan Sorular

Log dosyalarım çok büyüyor, ne yapmalıyım?

Serilog'un rollingInterval ayarını kullanarak dosyaları günlük veya saatlik olarak bölebilir ve retainedFileCountLimit parametresi ile eski logların otomatik silinmesini sağlayabilirsiniz.

Logları anlık olarak nasıl izleyebilirim?

Dosyaları manuel açmak yerine "Tail" komutları veya "BareTail" gibi araçlar kullanabilir ya da logları bir veritabanına (Seq veya SQL Server) yönlendirerek arayüz üzerinden izleyebilirsiniz.

Servis durduğunda loglar kaybolur mu?

Log.CloseAndFlush() metodunu finally bloğunda çağırdığınız sürece, tamponda bekleyen tüm loglar dosyaya yazılır ve veri kaybı yaşanmaz.

Log seviyeleri (Information, Warning, Error) neden önemli?

Log seviyeleri, üretim ortamında sadece kritik hataları görmek veya geliştirme ortamında tüm detayları incelemek için filtreleme yapmanıza olanak tanır.

Windows Event Log'a neden yazmıyoruz?

Event Log, sistem olayları için tasarlanmıştır. Uygulama bazlı yoğun loglama yapmak Event Log'un dolmasına ve sistemin yavaşlamasına neden olabilir; bu yüzden dosya tabanlı loglama daha güvenlidir.

Logların Merkezi Yönetimi: Seq ile Entegrasyon

Dosya tabanlı loglama küçük ve orta ölçekli projeler için yeterli olsa da, birden fazla servis çalıştıran sistemlerde logları tek tek dosyalar üzerinden incelemek zaman kaybına yol açar. Seq gibi merkezi log sunucuları, yapılandırılmış log verilerini (structured logging) sorgulanabilir bir arayüzde görmenizi sağlar.

Serilog kullanarak loglarınızı Seq'e göndermek için Serilog.Sinks.Seq paketini projenize eklemeniz yeterlidir. Aşağıdaki yapılandırma, hem dosyaya hem de merkezi sunucuya eş zamanlı loglama yapmanızı sağlar:

// Program.cs veya Servis başlatma bloğu
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .WriteTo.File("logs/servis-log-.txt", rollingInterval: RollingInterval.Day)
    .WriteTo.Seq("http://localhost:5341") // Seq sunucu adresi
    .CreateLogger();

Servis Loglama Süreçlerinde İleri İpuçları ve Best Practices

Windows servislerinde loglama yaparken sistem kaynaklarını tüketmemek ve verilerin anlamlı kalmasını sağlamak için şu stratejileri uygulamanız önerilir:

  • Bağlamsal Bilgi (Enrichment): Loglarınıza Enrich.FromLogContext() özelliğini ekleyerek, her log satırına Thread ID, Machine Name veya User ID gibi bilgileri otomatik olarak dahil edin.
  • Log Seviyesi Dinamik Değişimi: Servisiniz çalışırken log seviyesini (örneğin Debug'dan Information'a) değiştirmek için bir LoggingLevelSwitch kullanın. Bu sayede canlı ortamda hata ayıklarken servisi yeniden başlatmadan detaylı log alabilirsiniz.
// Dinamik log seviyesi kontrolü
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information);

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.ControlledBy(levelSwitch)
    .WriteTo.File("logs/servis.txt")
    .CreateLogger();

// Çalışma anında seviyeyi değiştirme
levelSwitch.MinimumLevel = LogEventLevel.Debug;

Log Performansını Optimize Etme

Yüksek trafikli servislerde loglama işlemi disk G/Ç (I/O) darboğazına neden olabilir. Bunu engellemek için logları bir kuyruk yapısında tutan PeriodicBatching yöntemini kullanın. Bu yöntem, logları anlık olarak diske yazmak yerine belirli aralıklarla paketler halinde yazar.

Yöntem Avantajı Dezavantajı
Senkron Yazma Anlık veri güvenliği Performans kaybı
Asenkron/Batching Yüksek performans Ani kapanmada son loglar kaybolabilir
İpucu: Kritik finansal işlemler veya güvenlik logları için her zaman senkron yazma tercih edilmeli; ancak genel uygulama akış logları için asenkron batching kullanılmalıdır.

Sonuç

C# ile Windows servislerinde profesyonel bir loglama sistemi kurmak, uygulamanın sürdürülebilirliği için vazgeçilmezdir. Bu rehberde Serilog kullanarak asenkron, güvenli ve düzenli bir loglama altyapısı oluşturmayı öğrendiniz. Bir sonraki adım olarak, loglarınızı merkezi bir sunucuya (örneğin bir ELK stack veya Seq sunucusu) göndererek, tüm servislerinizin loglarını tek bir panelden yönetmeyi deneyebilirsiniz. Unutmayın, iyi bir loglama sistemi, bir yazılımcının en iyi hata ayıklama aracıdır.

Bu yazıya tepkinizi paylaşın:
Mert Demir

Hobi projeleri, küçük tamirat işleri ve bahçe bakımı konusunda deneyimli bir editörüm. Adım adım rehberlerimle okuyucularımın özgüvenli bir şekilde yeni beceriler kazanmasını amaçlıyorum.

Yorumlar (0)

Yorum Yaz