.NET kitaplığı yazarları için günlüğe kaydetme kılavuzu
Bir kitaplık yazarı olarak, günlüğe kaydetmeyi kullanıma sunmak, tüketicilere kitaplığınızın iç çalışmalarıyla ilgili içgörüler sağlamanın harika bir yoludur. Bu kılavuz, günlüğü diğer .NET kitaplıkları ve çerçeveleriyle tutarlı bir şekilde kullanıma sunmanıza yardımcı olur. Ayrıca, aksi halde belirgin olmayan yaygın performans sorunlarını önlemenize de yardımcı olur.
Arabirimin ne zaman kullanılacağı ILoggerFactory
Günlükleri yayan bir kitaplık yazarken, günlükleri kaydetmek için bir ILogger nesneye ihtiyacınız vardır. Bu nesneyi almak için API'niz bir ILogger<TCategoryName> parametreyi kabul edebilir veya çağırdığınız ILoggerFactory.CreateLoggerbir ILoggerFactory parametreyi kabul edebilir. Hangi yaklaşım tercih edilmelidir?
Tümünün günlükleri yayabilmesi için birden çok sınıfa geçirilebilen bir günlük nesnesine ihtiyacınız olduğunda kullanın
ILoggerFactory
. Her sınıfın, sınıfla aynı adlı ayrı bir kategoriye sahip günlükler oluşturması önerilir. Bunu yapmak için fabrikanın günlükleri yayan her sınıf için benzersizILogger<TCategoryName>
nesneler oluşturması gerekir. Yaygın örnekler arasında, bir kitaplık için genel giriş noktası API'leri veya dahili olarak yardımcı sınıflar oluşturabilecek türlerin ortak oluşturucuları yer alır.Yalnızca bir sınıfta kullanılan ve hiç paylaşılmamış bir günlük nesnesine ihtiyacınız olduğunda, kullanın
ILogger<TCategoryName>
. BuradaTCategoryName
günlükleri oluşturan türdür. Bunun yaygın bir örneği, bağımlılık ekleme tarafından oluşturulan bir sınıf için oluşturucudur.
Zaman içinde kararlı kalması gereken bir genel API tasarlarsanız, gelecekte iç uygulamanızı yeniden düzenlemeyi isteyebileceğinizi unutmayın. Bir sınıf başlangıçta herhangi bir iç yardımcı türü oluşturmasa bile, kod geliştikçe bu değişebilir. kullanımı ILoggerFactory
, genel API'yi değiştirmeden tüm yeni sınıflar için yeni nesneler oluşturmayı ILogger<TCategoryName>
kapsar.
Daha fazla bilgi için bkz . Filtreleme kuralları nasıl uygulanır?
Kaynak tarafından oluşturulan günlüğü tercih edin
API, ILogger
API'yi kullanmaya yönelik iki yaklaşımı destekler. ve LoggerExtensions.LogInformationgibi LoggerExtensions.LogError yöntemleri çağırabilir veya günlüğe kaydetme kaynak oluşturucuyu kullanarak kesin olarak yazılan günlük yöntemlerini tanımlayabilirsiniz. Çoğu durumda, üstün performans ve daha güçlü yazma özelliği sunduğundan kaynak oluşturucu önerilir. Ayrıca ileti şablonları, kimlikler ve günlük düzeyleri gibi günlüğe kaydetmeye özgü endişeleri de çağıran koddan ayırır. Kaynak oluşturulmayan yaklaşım, kodu daha kısa hale getirmek için bu avantajlardan vazgeçmeye istekli olduğunuz senaryolar için öncelikli olarak yararlıdır.
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
Yukarıdaki kod:
- türünde uzantı yöntemlerini
ILogger
tanımlamak için kullanılabilmesi için adlandırılmışLogMessages
birpartial class
öğesinistatic
tanımlar. - Bir
LogProductSaleDetails
uzantı yöntemini özniteliği veMessage
şablonuylaLoggerMessage
süsler. LogProductSaleDetails
ve 'yi genişletenILogger
ve kabul edenquantity
description
öğesini bildirir.
İpucu
Hata ayıklama sırasında kaynak tarafından oluşturulan koda adım atabilirsiniz çünkü bu kod, onu çağıran kodla aynı derlemenin bir parçasıdır.
Pahalı parametre değerlendirmesini önlemek için kullanın IsEnabled
Parametreleri değerlendirmenin pahalı olduğu durumlar olabilir. Önceki örneği genişleterek parametresinin description
işlem için pahalı bir string
parametre olduğunu düşünün. Belki de satılan ürün kolay bir ürün açıklaması alır ve bir veritabanı sorgusuna veya bir dosyadan okumaya dayanır. Böyle durumlarda, kaynak oluşturucuya korumayı atlayıp IsEnabled
korumayı IsEnabled
çağrı alanına el ile eklemesini sağlayabilirsiniz. Bu, kullanıcının korumanın nerede çağrıldığını belirlemesine olanak tanır ve hesaplanması pahalı olabilecek parametrelerin yalnızca gerçekten gerekli olduğunda değerlendirilmesini sağlar. Aşağıdaki kodu inceleyin:
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information,
SkipEnabledCheck = true)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
LogProductSaleDetails
Uzantı yöntemi çağrıldığında, IsEnabled
koruma el ile çağrılır ve pahalı parametre değerlendirmesi gerektiğinde ile sınırlıdır. Aşağıdaki kodu inceleyin:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Daha fazla bilgi için bkz . Derleme zamanı günlüğü kaynak oluşturma ve .NET'te yüksek performanslı günlük.
Günlükte dize ilişkilendirmesini önleme
Günlük iletileri oluşturmak için dize ilişkilendirmesini kullanmak yaygın bir hatadır. Dize, ilgili LogLevel
etkin olmasa bile değerlendirildiğinden, günlükteki dize ilişkilendirmesi performans açısından sorunludur. Dize ilişkilendirmesi yerine günlük iletisi şablonunu, biçimlendirmesini ve bağımsız değişken listesini kullanın. Daha fazla bilgi için bkz . .NET'te oturum açma: Günlük iletisi şablonu.
İşlem dışı günlük varsayılanlarını kullanma
Bazen, veya ILoggerFactory
olmasını bekleyen ILogger
günlük API'lerini kullanıma sunan bir kitaplık kullanırken günlükçü sağlamak istemediğiniz zamanlar olabilir. Bu gibi durumlarda, Microsoft.Extensions.Logging.Abstractions NuGet paketi, çalışma dışı günlük varsayılanları sağlar.
Kitaplık tüketicileri, sağlanmayan ILoggerFactory
null günlüğe kaydetmeyi varsayılan olarak kullanabilir. Null günlüğe kaydetmenin kullanılması, türleri null olmayan türler olduğundan, türlerin null atanabilir ()ILoggerFactory?
olarak tanımlanmasından farklıdır. Bu kolaylık tabanlı türler hiçbir şeyi günlüğe kaydetmez ve temelde işlem yapılmaz. Uygun olduğunda kullanılabilir soyutlama türlerinden herhangi birini kullanmayı göz önünde bulundurun: