Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
.NET, uygulama davranışını izleme ve sorunları tanılamaya yardımcı olmak için ILogger API'si aracılığıyla yüksek performanslı, yapılandırılmış günlüğe kaydetmeyi destekler. Farklı hedeflere günlük yazmak için farklı günlük sağlayıcıları yapılandırın. Temel günlük sağlayıcıları yerleşiktir ve birçok üçüncü taraf sağlayıcı kullanılabilir.
Kullanmaya başlayın
Bu ilk örnekte temel bilgiler gösterilmektedir, ancak yalnızca önemsiz bir konsol uygulaması için uygundur. Bu örnek konsol uygulaması aşağıdaki NuGet paketlerine dayanır:
Sonraki bölümde, ölçeklendirme, performans, yapılandırma ve tipik programlama desenlerini göz önünde bulundurarak kodun nasıl geliştirilip geliştirilediğini göreceksiniz.
using Microsoft.Extensions.Logging;
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
Yukarıdaki örnek:
- bir ILoggerFactoryoluşturur. ,
ILoggerFactorygünlük iletilerinin nereye gönderileceğini belirleyen tüm yapılandırmayı depolar. Bu durumda, günlük iletilerinin konsola yazılması için konsol günlüğü sağlayıcısını yapılandırın. - "Program" adlı kategoriye sahip bir ILogger oluşturur.
Kategori, nesne tarafından
stringgünlüğe kaydedilen her iletiyle ilişkili birILoggerkategoridir. Günlükleri ararken veya filtrelerken aynı sınıftan (veya kategoriden) gelen günlük iletilerini gruplandırıyor. -
LogInformation'yı
Informationseviyesinde bir mesaj kaydetmek için çağırır. Günlük düzeyi, günlüğe kaydedilen olayın önem derecesini gösterir ve daha az önemli günlük iletilerini filtreler. Günlük girdisi ayrıca bir ileti şablonu"Hello World! Logging is {Description}."ve anahtar-değer çiftiDescription = funiçerir. Anahtar adı (veya yer tutucu), şablondaki küme ayraçlarının içindeki sözcükten gelir ve değer de geri kalan yöntem bağımsız değişkeninden elde edilir.
Bu örnek için bu proje dosyası iki NuGet paketi içerir:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.1" />
</ItemGroup>
</Project>
İpucu
Günlük tutma örnek kaynak kodunun tamamı, indirilmek üzere Samples Browser'da bulunur. Daha fazla bilgi için Kod örneklerine göz atma: .NET'te günlük kaydı bölümüne bakın.
Karmaşık bir uygulamada kayıt tutma
Daha az basit bir senaryoda oturum açarken, önceki örnekte bu değişiklikleri yapmayı düşünün.
Uygulamanız Bağımlılık Ekleme (DI) veya ASP.NET'in WebApplication veya Genel Konak gibi bir konak kullanıyorsa,
ILoggerFactoryveILoggernesnelerini doğrudan oluşturmak yerine ilgili DI kapsayıcılarından kullanın. Daha fazla bilgi için DI ve Ana Bilgisayarlarla Tümleştirme bölümüne bakın.Derleme zamanı kaynak oluşturmanın günlüğe kaydedilmesi genellikle gibi genişletme yöntemlerine daha iyi bir alternatiftir. Günlük kaydı kaynağı oluşturma, daha iyi performans, daha güçlü türleme sunar ve
stringsabitlerin yöntemlerinize yayılmasını önler. Sonuç olarak, bu tekniğin kullanılması biraz daha fazla kod gerektirir.
using Microsoft.Extensions.Logging;
internal partial class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
LogStartupMessage(logger, "fun");
}
[LoggerMessage(Level = LogLevel.Information, Message = "Hello World! Logging is {Description}.")]
static partial void LogStartupMessage(ILogger logger, string description);
}
- Günlük kategorisi adları için en iyi uygulama, günlük iletisini oluşturan sınıfın tam nitelikli adını kullanmaktır. Bu, günlük iletilerini oluşturan kodla ilişkilendirmeye yardımcı olur ve günlükleri filtrelerken iyi bir denetim düzeyi sunar.
CreateLogger , bu adlandırmanın kolay olmasını sağlamak için bir
Typekabul eder.
using Microsoft.Extensions.Logging;
internal class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger<Program>();
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
}
}
- Konsol günlüklerini tek üretim izleme çözümünüz olarak kullanmıyorsanız, kullanmayı planladığınız günlük sağlayıcılarını ekleyin. Örneğin, OTLP (OpenTelemetry protokolü) üzerinden günlük göndermek için OpenTelemetry kullanın:
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using ILoggerFactory factory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(logging =>
{
logging.AddOtlpExporter();
});
});
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
Ev sahipleriyle tümleştirme ve bağımlılık enjeksiyonu
Uygulamanız Bağımlılık Ekleme (DI) veya ASP.NET'in WebApplication veya Genel Ana Bilgisayar gibi bir konak kullanıyorsa, nesneleri doğrudan oluşturmak yerine DI kapsayıcısından ILoggerFactory ve ILogger nesnelerini kullanın.
DI'dan ILogger al
Barındırılan bir uygulamada ASP.NET Minimal API kullanarak ILogger nesnesi alan bu örnek:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
var handler = app.Services.GetRequiredService<ExampleHandler>();
app.MapGet("/", handler.HandleRequest);
app.Run();
partial class ExampleHandler(ILogger<ExampleHandler> logger)
{
public string HandleRequest()
{
LogHandleRequest(logger);
return "Hello World";
}
[LoggerMessage(LogLevel.Information, "ExampleHandler.HandleRequest was called")]
public static partial void LogHandleRequest(ILogger logger);
}
Yukarıdaki örnek:
- adlı
ExampleHandlertekton hizmet oluşturuldu ve gelen web istekleriExampleHandler.HandleRequestişlevini çalıştıracak şekilde eşlendi. - 12. Satır, C# 12'de eklenen bir özellik olan ExampleHandler için birincil oluşturucu tanımlar. Eski stil C# oluşturucusu aynı şekilde iyi çalışır, ancak biraz daha ayrıntılıdır.
- Oluşturucu, türünde
ILogger<ExampleHandler>bir parametre tanımlar. ILogger<TCategoryName>, ILogger öğesinden türetilir veILoggernesnesinin hangi kategoriye sahip olduğunu gösterir. DI kapsayıcısı doğru kategoriye sahip birILoggerbulur ve bunu oluşturucu bağımsız değişkeni olarak sağlar. Henüz bu kategoriye sahipILoggeryoksa, DI kapsayıcısı bunu hizmet sağlayıcısındakiILoggerFactory'den otomatik olarak oluşturur. -
loggerOluşturucuya alınan parametre,HandleRequestfonksiyonunda günlüğe kaydetmek için kullanılır.
Konak tarafından sağlanan ILoggerFactory
Konak oluşturucuları varsayılan yapılandırmayı başlatır, ardından konak oluşturulduğunda konağın DI kapsayıcısına yapılandırılmış ILoggerFactory bir nesne ekler. Konak oluşturulmadan önce, günlük yapılandırmasını HostApplicationBuilder.Logging veya WebApplicationBuilder.Logging gibi diğer konaklardaki benzer API'ler aracılığıyla ayarlayın. Sunucular ayrıca appsettings.json ve ortam değişkenleri gibi varsayılan yapılandırma kaynaklarından günlük kaydı yapılandırmasını uygular. Daha fazla bilgi için bkz . .NET'te yapılandırma.
Bu örnek, ILoggerFactory tarafından sağlanan WebApplicationBuilder öğesini özelleştirmek için öncekini genişletir. OpenTelemetry'yi, günlükleri OTLP (OpenTelemetry protokolü) üzerinden ileten bir günlük sağlayıcısı olarak ekler.
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddOpenTelemetry(logging => logging.AddOtlpExporter());
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
DI ile ILoggerFactory oluşturma
Konağı olmayan bir DI kapsayıcısı kullanıyorsanız, kapsayıcıyı yapılandırmak için AddLogging ve kapsayıcıya eklemek için ILoggerFactory kullanın.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// Add services to the container including logging
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddConsole());
services.AddSingleton<ExampleService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
// Get the ExampleService object from the container
ExampleService service = serviceProvider.GetRequiredService<ExampleService>();
// Do some pretend work
service.DoSomeWork(10, 20);
class ExampleService(ILogger<ExampleService> logger)
{
public void DoSomeWork(int x, int y)
{
logger.LogInformation("DoSomeWork was called. x={X}, y={Y}", x, y);
}
}
Yukarıdaki örnek:
- Konsola yazacak şekilde yapılandırılmış
ILoggerFactoryiçeren bir DI hizmet kapsayıcısı oluşturuldu. - Kapsayıcıya bir singleton
ExampleServiceeklendi - DI kapsayıcısından
ExampleService'ın bir örneğini oluşturdunuz. Bu, oluşturucu bağımsız değişkeni olarak kullanılacak birILogger<ExampleService>öğesini de otomatik olarak oluşturdu. - çağrılır
ExampleService.DoSomeWorkve konsolda bir iletiyi günlüğe kaydetmek için kullanılırILogger<ExampleService>.
Günlük tutmayı yapılandırmak
Loglama yapılandırmasını, kod üzerinde veya yapılandırma dosyaları ve ortam değişkenleri gibi dış kaynaklar aracılığıyla ayarlayın. Uygulamayı yeniden derlemeden değiştirebildiğiniz için mümkün olduğunda dış yapılandırmanın kullanılması yararlı olur. Ancak, günlük sağlayıcılarını ayarlamak gibi bazı görevler yalnızca kod ile yapılandırılabilir.
Kod yazmadan günlük kaydını yapılandırma
Konak kullanan uygulamalar için "Logging".{Environment}.json dosyalarının bölümü genellikle günlük yapılandırması sağlar. Konak kullanmayan uygulamalar için, dış yapılandırma kaynaklarını açıkça ayarlayın veya bunları kodda yapılandırın .
Aşağıdaki uygulama ayarları. Development.json dosyası .NET Çalışanı hizmet şablonları tarafından oluşturulur:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
Yukarıdaki JSON kodunda:
-
"Default","Microsoft"ve"Microsoft.Hosting.Lifetime"log düzeyi kategorileri belirtilir. - Değer,
"Default"aksi belirtilmediği halde tüm kategoriler için geçerli olur ve tüm kategoriler"Information"için tüm varsayılan değerleri etkili bir şekilde oluşturur. Kategori için bir değer belirterek bu davranışı geçersiz kılın. -
"Microsoft"kategorisi"Microsoft"ile başlayan tüm kategorilere uygulanır. -
"Microsoft"kategorisi,Warningve daha yüksek bir seviyede günlüğe kaydeder. -
"Microsoft.Hosting.Lifetime"kategorisi,"Microsoft"kategorisinden daha belirgindir, bu nedenle"Microsoft.Hosting.Lifetime"kategorisi günlüğe"Information"ve üzeri bir günlüğe kaydedilir. - Belirli bir günlük sağlayıcısı belirtilmediğinden,
LogLevelWindows EventLog dışındaki tüm etkin günlük sağlayıcıları için geçerlidir.
Logging özelliği, LogLevel ve günlük sağlayıcı özelliklerine sahip olabilir.
LogLevel, belirli kategoriler için kaydedilecek en düşük düzeyi belirtir. Önceki JSON'da Information ve Warning günlük düzeyleri belirtilmiştir.
LogLevel logun önem derecesini gösterir ve 0 ile 6 arasında seviyeler içerir:
Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 ve None = 6.
LogLevel belirtildiğinde, belirtilen düzeyde ve daha yüksek düzeydeki iletiler için kayıtlar etkinleştirilir. Önceki JSON'da, Default kategorisi, Information ve daha yüksek değerler için günlüğe kaydedilir. Örneğin Information, Warning, Error ve Critical iletileri günlüğe kaydedilir.
LogLevel belirtilmediği takdirde, günlük kaydı varsayılan olarak Information düzeyine ayarlanır. Daha fazla bilgi için aşağıdaki Günlük Düzeyleri kısmına bakınız.
Sağlayıcı özelliği bir LogLevel özelliği belirtebilir. Sağlayıcının altındaki LogLevel, söz konusu sağlayıcı için günlüğe alınacak düzeyleri belirtir ve sağlayıcı dışı günlük ayarlarını geçersiz kılar. Aşağıdaki appsettings.json dosyasını göz önünde bulundurun:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting": "Trace"
}
},
"EventSource": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
Logging.{ProviderName}.LogLevel sınıfındaki ayarlar Logging.LogLevel ayarlarını geçersiz kılar. Yukarıdaki JSON'da sağlayıcının varsayılan günlük düzeyi Debug olarak ayarlanmıştır:
Logging:Debug:LogLevel:Default:Information
Önceki ayar, Information hariç, her Logging:Debug: kategorisi için Microsoft.Hosting günlük düzeyini belirtir. Belirli bir kategori listelendiğinde, listelenen kategori varsayılan kategoriyi geçersiz kılar. Önceki JSON'da, Logging:Debug:LogLevel içindeki ayarları "Microsoft.Hosting"kategoriler "Default" ve Logging:LogLevel geçersiz kılar.
Şunlardan herhangi biri için en düşük log düzeyini belirtin:
- Belirli sağlayıcılar: Örneğin
Logging:EventSource:LogLevel:Default:Information - Belirli kategoriler: Örneğin
Logging:LogLevel:Microsoft:Warning - Tüm sağlayıcılar ve tüm kategoriler:
Logging:LogLevel:Default:Warning
En düşük düzeyin altındaki günlükler kaydedilmez:
- Sağlayıcıya iletildi.
- Günlüğe kaydedilir veya görüntülenir.
Tüm günlükleri engellemek için LogLevel.None değerini belirtin.
LogLevel.None değeri 6'dır ve bu değer LogLevel.Critical (5) değerinden yüksektir.
Sağlayıcı günlük kapsamlarını destekliyorsa IncludeScopes bunların etkinleştirilip etkinleştirilmediğini gösterir. Daha fazla bilgi için günlük kapsamlarınıgörün.
Aşağıdaki appsettings.json dosyası tüm yerleşik sağlayıcıların ayarlarını içerir:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft.Extensions.Hosting": "Warning",
"Default": "Information"
}
},
"EventSource": {
"LogLevel": {
"Microsoft": "Information"
}
},
"EventLog": {
"LogLevel": {
"Microsoft": "Information"
}
},
"AzureAppServicesFile": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Warning"
}
},
"AzureAppServicesBlob": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Information"
}
},
"ApplicationInsights": {
"LogLevel": {
"Default": "Information"
}
}
}
}
Yukarıdaki örnekte:
- Kategoriler ve düzeyler önerilen değerler değildir. Örnekte tüm varsayılan sağlayıcılar gösterilir.
-
Logging.{ProviderName}.LogLevelsınıfındaki ayarlarLogging.LogLevelayarlarını geçersiz kılar. ÖrneğinDebug.LogLevel.DefaultdüzeyiLogLevel.Defaultdüzeyini geçersiz kılar. - Her sağlayıcının diğer adı kullanılır. Her sağlayıcı, tam tür adının yerine yapılandırmada kullanabileceğiniz bir takma ad tanımlar. Yerleşik sağlayıcıların diğer adları şunlardır:
ConsoleDebugEventSourceEventLogAzureAppServicesFileAzureAppServicesBlobApplicationInsights
Komut satırı, ortam değişkenleri ve diğer yapılandırmalarla günlük düzeyini ayarlayın.
Günlük seviyesini, yapılandırma sağlayıcılarından herhangi birini kullanarak ayarlayın. Örneğin, Information değerine sahip Logging:LogLevel:Microsoft adlı kalıcı bir ortam değişkeni oluşturun.
Günlük düzeyi değeri göz önüne alındığında kalıcı hale getirilmiş ortam değişkeni oluşturun ve atayın.
:: Assigns the env var to the value
setx "Logging__LogLevel__Microsoft" "Information" /M
Komut İstemi'nin yeni bir örneğinde ortam değişkenini okuyun.
:: Prints the env var value
echo %Logging__LogLevel__Microsoft%
Önceki ortam ayarı ortamda kalır. .NET Çalışanı hizmet şablonlarıyla oluşturulan bir uygulamayı kullanırken ayarları test etmek için, ortam değişkeni atandıktan sonra proje dizinindeki komutunu kullanın dotnet run .
dotnet run
İpucu
Ortam değişkenini ayarladıktan sonra, yeni eklenen ortam değişkenlerinin kullanılabilir olduğundan emin olmak için tümleşik geliştirme ortamınızı (IDE) yeniden başlatın.
Azure App Service üzerinde, sayfasında > seçin. Azure App Service uygulama ayarları şunlardır:
- Bekleme sırasında şifrelenir ve şifrelenmiş bir kanal üzerinden iletilir.
- Ortam değişkenleri olarak açığa çıkarılır.
Ortam değişkenlerini kullanarak .NET yapılandırma değerlerini ayarlama hakkında daha fazla bilgi için bkz . ortam değişkenleri.
Kodla günlük kayıt yapılandırma
Kod içinde loglamayı yapılandırmak için API'yi ILoggingBuilder kullanın. Farklı yerlerden erişebilirsiniz:
-
ILoggerFactoryöğesini doğrudan oluşturduğunuzda, LoggerFactory.Create içinde yapılandırma yapın. - Ana bilgisayar olmadan DI kullanırken, içinde LoggingServiceCollectionExtensions.AddLogging yapılandırın.
- Bir konak kullanırken, HostApplicationBuilder.Logging veya WebApplicationBuilder.Logging gibi konağa özgü API'lerle yapılandırın.
Bu örnekte konsol günlüğü sağlayıcısının ve çeşitli filtrelerin ayarlanması gösterilmektedir.
using Microsoft.Extensions.Logging;
using var loggerFactory = LoggerFactory.Create(static builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
.AddConsole();
});
ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogDebug("Hello {Target}", "Everyone");
Yukarıdaki örnekte, AddFilter çeşitli kategoriler için etkinleştirilen günlük düzeyini ayarlar.
AddConsole konsol günlüğü sağlayıcısını ekler. Varsayılan olarak, Debug önem derecesindeki günlükler etkinleştirilmez, ancak yapılandırma filtreleri ayarlandığında konsolda "Herkese Merhaba" hata ayıklama mesajı görüntülenir.
Filtreleme kuralları nasıl uygulanır?
Bir ILogger<TCategoryName> nesnesi oluşturulduğunda ILoggerFactory nesnesi bu günlükçüye uygulamak üzere sağlayıcı başına tek bir kural seçer. Örnek, ILogger yazdığı tüm iletileri seçilen kurallara göre filtreler. Kullanılabilir kurallar arasından her sağlayıcı ve kategori çifti için en belirgin kural seçilir.
Belirli bir kategori için ILogger oluşturulduğunda her sağlayıcı için aşağıdaki algoritma kullanılır:
- Sağlayıcıyla veya sağlayıcının diğer adıyla eşleşen tüm kuralları seçin. Eşleşme bulunamazsa sağlayıcısı boş olan tüm kurallar seçilir.
- Önceki adımın sonucundan, eşleşen kategori ön eki en uzun olan kuralları seçin. Eşleşme bulunamazsa bir kategori belirtmeyen tüm kuralları seçin.
- Birden çok kural seçildiyse, sonuncusunu alın.
- Hiçbir kural seçilmezse, LoggingBuilderExtensions.SetMinimumLevel(ILoggingBuilder, LogLevel) ögesini en düşük günlük düzeyini belirtmek için kullanın.
Günlük kategorisi
ILogger nesnesi oluşturulduğunda bir kategori belirtilir. Söz konusu kategori bu ILogger örneğiyle oluşturulan her günlük iletisine eklenir. Kategori dizesi rastgeledir, ancak kural tam sınıf adını kullanmaktır. Örneğin, aşağıdaki nesne gibi tanımlanmış bir hizmete sahip bir uygulamada, kategori şöyle "Example.DefaultService"olabilir:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger<DefaultService> _logger;
public DefaultService(ILogger<DefaultService> logger) =>
_logger = logger;
// ...
}
}
Daha fazla kategori isteniyorsa, kural, tam sınıf adına bir alt kategori ekleyerek hiyerarşik bir ad kullanmak ve LoggerFactory.CreateLogger kullanarak kategoriyi açıkça belirtmektir:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger _logger;
public DefaultService(ILoggerFactory loggerFactory) =>
_logger = loggerFactory.CreateLogger("Example.DefaultService.CustomCategory");
// ...
}
}
Olayların kategoriye göre düzenlenebilmesi için birden çok sınıfta/türde kullanıldığında sabit bir adla çağırmak CreateLogger yararlı olur.
ILogger<T>, CreateLogger tam nitelikli tür adıyla T yöntemini çağırmanın eşdeğeridir.
Kayıt seviyesi
Aşağıdaki tabloda LogLevel değerleri, uygun Log{LogLevel} uzantısı yöntemi ve önerilen kullanım listelenir:
| Log Seviyesi | Değer | Metot | Açıklama |
|---|---|---|---|
| İzleme | 0 | LogTrace | En ayrıntılı iletileri içerir. Bu iletiler hassas uygulama verileri içerebilir. Bu iletiler varsayılan olarak devre dışı bırakılmıştır ve üretimde etkinleştirilmemesi gerekir. |
| Hata ayıklama | 1 | LogDebug | Hata ayıklama ve geliştirme için. Yüksek hacim nedeniyle üretimde dikkatli kullanın. |
| Bilgi | 2 | LogInformation | Uygulamanın genel akışını izler. Uzun vadeli bir değere sahip olabilir. |
| Uyarı | 3 | LogWarning | Anormal veya beklenmeyen olaylar için. Normalde uygulamanın başarısız olmasına neden olmayan hataları veya koşulları içerir. |
| Hata | 4 | LogError | Ele alınamayan hatalar ve istisnalar için. Bu iletiler uygulama genelindeki bir hatayı değil geçerli işlem veya istekteki hatayı gösterir. |
| Kritik | 5 | LogCritical | Hemen dikkat edilmesi gereken hatalar için. Örnekler: veri kaybı senaryoları, yetersiz disk alanı. |
| Hiçbiri | 6 | Hiçbir iletinin yazılmaması gerektiğini belirtir. |
Yukarıdaki tabloda LogLevel en düşük önem derecesinden en yükseğe doğru listelenmiştir.
Log yönteminin ilk parametresi LogLevel, günlüğün önem derecesini belirtir. Geliştiricilerin çoğu Log(LogLevel, ...) yöntemini çağırmak yerine Log{LogLevel} uzantı yöntemlerini çağırır.
Log{LogLevel} uzantı yöntemleri Log yöntemini çağırır ve LogLevel'yi belirtir. Örneğin, aşağıdaki iki log çağrısı işlevsel olarak eşdeğerdir ve aynı logu oluşturur.
public void LogDetails()
{
var logMessage = "Details for log.";
_logger.Log(LogLevel.Information, AppLogEvents.Details, logMessage);
_logger.LogInformation(AppLogEvents.Details, logMessage);
}
AppLogEvents.Details olay kimliğidir ve örtük olarak sabit Int32 bir değerle temsil edilir.
AppLogEvents çeşitli adlandırılmış tanımlayıcı sabitlerini kullanıma sunan ve Günlük olay kimliği bölümünde görüntülenen bir sınıftır.
Aşağıdaki kod Information ve Warning günlüklerini oluşturur:
public async Task<T> GetAsync<T>(string id)
{
_logger.LogInformation(AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
return result;
}
Yukarıdaki kodda, ilk Log{LogLevel} parametre, AppLogEvents.Read Log olay kimliğidir . İkinci parametre, kalan yöntem parametreleri tarafından sağlanan bağımsız değişken değerleri için yer tutucular içeren bir ileti şablonudur. Yöntem parametreleri, bu makalenin devamında ileti şablonu bölümünde açıklanmıştır.
Uygun günlük düzeyini yapılandırın ve belirli bir depolama ortamına ne kadar log çıktısı yazılacağını kontrol etmek için doğru Log{LogLevel} yöntemleri çağırın. Örneğin:
- Üretimde:
-
TraceveyaDebugdüzeylerinde loglama, ayrıntılı ve yüksek hacimli günlük iletileri oluşturur. Veri depolama sınırlarını aşmamak ve maliyetleri kontrol altında tutmak içinTraceveDebugdüzeyindeki iletileri, yüksek hacimli ve düşük maliyetli bir veri deposuna kaydedin.TraceveDebugdüzeylerini belirli kategorilerle sınırlamayı göz önünde bulundurun. -
WarningileCriticaldüzeyleri aralarında kayıt tutmak az sayıda kayıt iletisi üretmelidir.- Maliyetler ve depolama sınırları genellikle sorun değildir.
- Daha az sayıda günlük, veri deposu seçimlerinde daha fazla esneklik sağlar.
-
- Geliştirme aşamasında:
-
Warningolarak ayarlayın. - Sorun giderme sırasında
TraceveyaDebugiletilerini ekleyin. Çıkışı sınırlamak içinTraceveyaDebugdüzeyini yalnızca araştırma kapsamındaki kategoriler için ayarlayın.
-
Aşağıdaki JSON kümeleri Logging:Console:LogLevel:Microsoft:Information:
{
"Logging": {
"LogLevel": {
"Microsoft": "Warning"
},
"Console": {
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Kayıt olay kimliği
Her bir günlük kayıt bir olay tanımlayıcısı belirtebilir; bir EventId yapıdır ve isteğe bağlı Id salt okunur özelliklere sahiptir. Örnek kaynak kodu, olay kimliklerini tanımlamak için sınıfını AppLogEvents kullanır:
using Microsoft.Extensions.Logging;
internal static class AppLogEvents
{
internal static EventId Create = new(1000, "Created");
internal static EventId Read = new(1001, "Read");
internal static EventId Update = new(1002, "Updated");
internal static EventId Delete = new(1003, "Deleted");
// These are also valid EventId instances, as there's
// an implicit conversion from int to an EventId
internal const int Details = 3000;
internal const int Error = 3001;
internal static EventId ReadNotFound = 4000;
internal static EventId UpdateNotFound = 4001;
// ...
}
İpucu
'int öğesinin EventId öğesine dönüştürülmesi hakkında daha fazla bilgi için bkz: EventId.Implicit(Int32 to EventId) İşleci.
Olay kimliği bir dizi olayı ilişkilendirir. Örneğin, bir depodan değerleri okumayla ilgili tüm loglar 1001 olabilir.
Günlük sağlayıcısı olay kimliğini bir kimlik alanında, günlük iletisinde günlüğe kaydedebilir veya hiç günlüğe kaydetmeyebilir. Hata ayıklama sağlayıcısı olay kimliklerini göstermez. Konsol sağlayıcısı olay kimliklerini kategori adından sonra köşeli parantez içinde gösterir.
info: Example.DefaultService.GetAsync[1001]
Reading value for a1b2c3
warn: Example.DefaultService.GetAsync[4000]
GetAsync(a1b2c3) not found
Bazı günlük sağlayıcıları olay kimliğini bir alanda depolar, bu da kimliğe göre filtrelemeye imkan verir.
Günlük iletisi şablonu
Her bir günlük API, bir mesaj şablonu kullanır. İleti şablonu bağımsız değişkenlerin sağlandığı yer tutucular içerebilir. Yer tutucular için sayı değil ad kullanın. Yer tutucuların adları değil sırası, değerlerini sağlamak için hangi parametrelerin kullanılacağını belirler. Aşağıdaki kodda, ileti şablonunda parametre adları sıra dışıdır:
string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
Yukarıdaki kod, parametre değerlerini sırayla içeren bir günlük iletisi oluşturur:
Parameter values: param1, param2
Not
Tek bir ileti şablonunda birden çok yer tutucu kullanırken, sıra tabanlı oldukları için dikkatli olun. Adlar, argümanları yer tutucularla hizalamak için kullanılmaz.
Bu yaklaşım, günlük sağlayıcılarının anlamsal veya yapılandırılmış günlük kaydı uygulamasına olanak tanır. Bağımsız değişkenler, yalnızca biçimlendirilmiş ileti şablonuna değil, doğrudan günlük sistemine iletilir. Bu sayede kayıt sağlayıcıları parametre değerlerini alanlar olarak depolayabilir. Aşağıdaki loglama yöntemini göz önünde bulundurun:
_logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now);
Örneğin Azure Tablo Depolama'da oturum açarken:
- Her Azure Tablo varlığının
IDveRunTimeözellikleri olabilir. - Özellikleri olan tablolar, günlüğe kaydedilmiş veriler üzerinde çalıştırılan sorguları basitleştirir. Örneğin bir sorgu, metin iletisinden zamanı ayıklamak zorunda kalmadan belirli bir
RunTimearalığındaki tüm günlükleri bulabilir.
Günlük iletisi şablonu biçimlendirmesi
Kayıt mesajı şablonları yer tutucu biçimlendirmeyi destekler. Şablonlar, verilen tür bağımsız değişkeni için herhangi bir geçerli biçimi belirtebilir. Örneğin, aşağıdaki Information günlükçü ileti şablonunu göz önünde bulundurun:
_logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow);
// Logged on January 06, 2022
Önceki örnekte, DateTimeOffset örneği, günlükçü mesaj şablonundaki PlaceHolderName öğesine karşılık gelen türdür. Değerler sıra tabanlı olduğundan bu ad herhangi bir şey olabilir. Format MMMM dd, yyyy, tür DateTimeOffset için geçerlidir.
Daha fazla bilgi için DateTime ve DateTimeOffset biçimlendirmeye bakın, Özel tarih ve saat formatı dizeleri.
Örnekler
Aşağıdaki örnekler, {} yer tutucu söz dizimini kullanarak bir ileti şablonunun nasıl biçimlendirileceğini göstermektedir. Ayrıca, yer tutucu söz diziminin {} çıkışıyla birlikte bir kaçış örneği gösterilir. Son olarak, şablon oluşturma yer tutucularıyla dize ilişkilendirmesi de gösterilir:
logger.LogInformation("Number: {Number}", 1); // Number: 1
logger.LogInformation("{{Number}}: {Number}", 3); // {Number}: 3
logger.LogInformation($"{{{{Number}}}}: {{Number}}", 5); // {Number}: 5
İpucu
- Çoğu durumda, giriş kaydı yaparken log mesaj şablonu biçimlendirmesini kullanmanız gerekir. Dize ilişkilendirmesinin kullanılması performans sorunlarına neden olabilir.
- Kod çözümleme kuralı CA2254: Şablon statik bir ifade olmalıdır, günlük iletilerinizin düzgün biçimlendirme kullanmadığı yerler konusunda sizi uyarmaya yardımcı olur.
Kayıt özel durumları
Logger yöntemlerinde istisna parametresi alan aşırı yüklemeler vardır.
public void Test(string id)
{
try
{
if (id is "none")
{
throw new Exception("Default Id detected.");
}
}
catch (Exception ex)
{
_logger.LogWarning(
AppLogEvents.Error, ex,
"Failed to process iteration: {Id}", id);
}
}
Özel durum günlüğü sağlayıcıya özgüdür.
Varsayılan kayıt düzeyi
Varsayılan günlük düzeyi ayarlı değilse, varsayılan günlük düzeyi değeri olur Information.
Örneğin, aşağıdaki çalışan hizmeti uygulamasını göz önünde bulundurun:
- .NET Worker şablonları ile oluşturulmuş.
- appsettings.json ve appsettings.Development.json silindi veya yeniden adlandırıldı.
Yukarıdaki kurulumda gizlilik veya giriş sayfasına gitmek, kategori adında Trace içeren birçok Debug, Information ve Microsoft iletisi oluşturur.
Aşağıdaki kod, varsayılan günlük düzeyinin yapılandırmada ayarlanmamış olması durumunda varsayılan günlük düzeyini ayarlar:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
using IHost host = builder.Build();
await host.RunAsync();
Filter işlevi
Yapılandırma veya kod tarafından kendilerine atanmış kuralları olmayan tüm sağlayıcılar ve kategoriler için filtre işlevi çağrılır:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddFilter((provider, category, logLevel) =>
{
return provider.Contains("ConsoleLoggerProvider")
&& (category.Contains("Example") || category.Contains("Microsoft"))
&& logLevel >= LogLevel.Information;
});
using IHost host = builder.Build();
await host.RunAsync();
Yukarıdaki kod, kategori Example veya Microsoft içerdiğinde ve günlük düzeyi Information veya daha yüksek olduğunda konsol günlüklerini görüntüler.
Kayıt kapsamları
Kapsam, bir dizi Mantıksal işlemi gruplandırır. Bu gruplandırma, bir kümenin parçası olarak oluşturulan her günlüğe aynı verileri ekleyebilir. Örneğin, bir işlemi işleme sürecinin parçası olarak oluşturulan her günlük, işlem kimliğini içerebilir.
Kapsam:
- IDisposable yöntemi tarafından döndürülen bir BeginScope türüdür.
- Atılana kadar kalır.
Bu sağlayıcılar, aşağıdaki kapsamları destekler.
Günlükçü çağrılarını bir using bloğunda sarmalayarak kapsam kullanın.
public async Task<T> GetAsync<T>(string id)
{
T result;
var transactionId = Guid.NewGuid().ToString();
using (_logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("TransactionId", transactionId),
}))
{
_logger.LogInformation(
AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(
AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
}
return result;
}
Aşağıdaki JSON, konsol sağlayıcısı için kapsamları etkinleştirir:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Warning",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
Aşağıdaki kod, konsol sağlayıcısı için kapsam alanlarını etkinleştirmeye olanak tanır.
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddSimpleConsole(options => options.IncludeScopes = true);
using IHost host = builder.Build();
await host.RunAsync();
Main'de günlük oluşturma
Aşağıdaki kod, DI'den bir Main örneği alarak konağı oluşturduktan sonra ILogger'e giriş yapar:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using IHost host = Host.CreateApplicationBuilder(args).Build();
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Host created.");
await host.RunAsync();
Yukarıdaki kod iki NuGet paketine dayanır:
Proje dosyası aşağıdakine benzer:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
</ItemGroup>
</Project>
Eşzamansız kaydedici yöntemleri yok
Günlük kaydının o kadar hızlı olması gerekir ki asenkron kodun performans maliyetine değmesin. Günlük veri deposu yavaşsa, doğrudan oraya günlükleri yazmayın. Günlük mesajlarını önce hızlı bir depoya yazmayı, daha sonra yavaş depoya taşımayı düşünün. Örneğin, SQL Server'a günlüğe kaydederken, bunu doğrudan Log yönteminde yapmayın, çünkü Log yöntemleri eşzamanlıdır. Bunun yerine, günlük iletilerini zaman uyumlu biçimde bir bellek içi kuyruğa ekleyin ve bir arka plan işçisi verileri SQL Server'a zaman uyumsuz biçimde aktarmak için iletileri kuyruktan çeksin.
Çalışmakta olan bir uygulamada kayıt düzeylerini değiştirme
Günlük tutma API'si, bir uygulama çalışırken günlük seviyelerini değiştirmeye yönelik bir senaryo içermez. Ancak, bazı yapılandırma sağlayıcıları yapılandırmayı yeniden yükleyebilir ve bu da günlük yapılandırması üzerinde hemen etkili olur. Örneğin, Dosya Yapılandırma Sağlayıcısı günlük yapılandırmasını varsayılan olarak yeniden yükler. Bir uygulama çalışırken koddaki yapılandırmayı değiştirirseniz uygulama, uygulamanın günlük yapılandırmasını güncelleştirmek için IConfigurationRoot.Reload'ı çağırabilir.
NuGet paketleri
ILogger<TCategoryName> ve ILoggerFactory arabirimleri ve uygulamaları örtük paket başvurusu olarak çoğu .NET SDK'sında yer alır. Bunlar, örtük olarak başvurulmuyorsa aşağıdaki NuGet paketlerinde de açıkça kullanılabilir:
- Arabirimler Microsoft.Extensions.Logging.Abstractions içindedir.
- Varsayılan uygulamalar Microsoft.Extensions.Logging içindedir.
Daha fazla bilgi için hangi .NET SDK'sı örtük paket başvuruları içerdiğine bakın: .NET SDK: örtük ad alanı tablosu.