CodeBlanks Logo Icon CodeBlanks

LoggerMessage

C# kursu · İleri seviye · Ders 75/83

LoggerMessage.Define ile yüksek performanslı log öğrenirsin.

LoggerMessage.Define

Her LogInformation("...") çağrısı çalışma zamanında bir dize ayırır (allocation). Sık çağrılan yerlerde bu maliyetlidir. LoggerMessage.Define, ileti şablonunu bir kez derleyen ve yeniden kullanılan bir temsilci (delegate) döndürür.

Örnek: private static readonly Action<ILogger, string> _greet = LoggerMessage.Define<string>(LogLevel.Information, 0, "Merhaba {User}");. Sonra _greet(logger, "Ayşe") çağrısı her seferinde şablonu yeniden ayrıştırmaz; hazır temsilciyi çalıştırır.

Uygulama LoggerMessage ile yüksek performanslı günlük

Genel olmayan bir ILogger arayüzü (void LogInformation(string message)) ve ILogger<T> : ILogger arayüzü tanımla. ConsoleLogger<T> sınıfı ILogger<T>'yi uygulayıp Console.WriteLine("[INF] " + message) yapsın. Statik LoggerMessage sınıfında DefineInformation(string message) metodu Action<ILogger, string> döndürsün; döndürülen temsilci ikinci argümanı {Arg} yer tutucusunun yerine koyup LogInformation çağrısı yapsın. Main'de bir ConsoleLogger<Program> yarat, DefineInformation("Merhaba {Arg}") ile temsilciyi al ve greet(logger, "Ayşe") çağrısı yap.

Örnek çözümü göster
interface ILogger { void LogInformation(string message); } ve interface ILogger<T> : ILogger { } tanımla. class ConsoleLogger<T> : ILogger<T> { public void LogInformation(string message) => Console.WriteLine("[INF] " + message); } yaz. static class LoggerMessage { public static Action<ILogger, string> DefineInformation(string message) => (logger, arg) => logger.LogInformation(message.Replace("{Arg}", arg)); } yaz. Main'de: var logger = new ConsoleLogger<Program>(); var greet = LoggerMessage.DefineInformation("Merhaba {Arg}"); greet(logger, "Ayşe");
Örnek çözüm:
using System;

public interface ILogger
{
    void LogInformation(string message);
}

public interface ILogger<T> : ILogger { }

public class ConsoleLogger<T> : ILogger<T>
{
    public void LogInformation(string message) =>
        Console.WriteLine("[INF] " + message);
}

public static class LoggerMessage
{
    public static Action<ILogger, string> DefineInformation(string message) =>
        (logger, arg) => logger.LogInformation(message.Replace("{Arg}", arg));
}

class Program
{
    static void Main()
    {
        var logger = new ConsoleLogger<Program>();
        var greet = LoggerMessage.DefineInformation("Merhaba {Arg}");
        greet(logger, "Ayşe");
    }
}

Temsilciyi yeniden kullan

Define ile alınan temsilci static readonly alanda saklanır. Böylece uygulama başlatıldığında bir kez üretilir, sonrasında her çağrı aynı nesneyi kullanır. Şablon ayrıştırma bir kere yapılır.

Sık çağrılan sıcak yollarda (örneğin döngü içindeki günlükler) bu yaklaşım belirgin performans kazancı verir. Seyrek çağrılan yerlerde ise doğrudan LogInformation kullanmak yeterince hızlıdır; aşırı tasarım kaçınılmalıdır.

Kendini test et

  1. Define çağrısını tamamla

    var greet = LoggerMessage.____("Merhaba {User}");
    Cevabı göster
    var greet = LoggerMessage.DefineInformation("Merhaba {User}");
  2. LoggerMessage.Define neden tercih edilir?

    • Daha kısa kod yazmak için
    • Günlükleri renklendirmek için
    • Yalnızca hataları yakalamak için
    • Her çağrıda dize ayırmayı önlemek için
    Cevabı göster

    Her çağrıda dize ayırmayı önlemek için — Doğru. Define şablonu bir kez derler; tekrarlayan ayırmayı önler.

  3. LoggerMessage kavramlarını eşleştir

    Define
    Şablonu derleyen metot
    Action<ILogger, T>
    Döndürülen temsilci
    static readonly
    Temsilciyi saklar
    {Arg}
    Yer tutucu

İleri seviye bölümündeki tüm dersler