注:本文隸屬於《理解ASP.NET Core》系列文章,請檢視置頂部落格或點選此處檢視全文目錄
快速上手
新增日誌提供程式
在文章主機(Host)中,講到Host.CreateDefaultBuilder
方法,預設通過呼叫ConfigureLogging
方法新增了Console
、Debug
、EventSource
和EventLog
(僅Windows)共四種日誌記錄提供程式(Logger Provider),然後在主機Build
過程中,通過AddLogging()
註冊了日誌相關的服務。
.ConfigureLogging((hostingContext, logging) =>
{
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
}
// 新增 Logging 配置
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
// ConsoleLoggerProvider
logging.AddConsole();
// DebugLoggerProvider
logging.AddDebug();
// EventSourceLoggerProvider
logging.AddEventSourceLogger();
if (isWindows)
{
// 在Windows平臺上,新增 EventLogLoggerProvider
logging.AddEventLog();
}
logging.Configure(options =>
{
options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
| ActivityTrackingOptions.TraceId
| ActivityTrackingOptions.ParentId;
});
})
public class HostBuilder : IHostBuilder
{
private void CreateServiceProvider()
{
var services = new ServiceCollection();
// ...
services.AddLogging();
// ...
}
}
如果不想使用預設新增的日誌提供程式,我們可以通過ClearProviders
清除所有已新增的日誌記錄提供程式,然後新增自己想要的,如Console
:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders()
.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
記錄日誌
日誌記錄提供程式均實現了介面ILoggerProvider
,該介面可以建立ILogger
例項。
通過注入服務ILogger<TCategoryName>
,就可以非常方便的進行日誌記錄了。
該服務需要指定日誌的類別,可以是任意字串,但是我們約定使用所屬類的名稱,通過泛型體現。例如,在控制器ValuesController
中,日誌類別就是ValuesController
類的完全限定型別名。
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger;
public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
[HttpGet]
public string Get()
{
_logger.LogInformation("ValuesController.Get");
return "Ok";
}
}
當請求Get
方法後,你就可以在控制檯中看到看到輸出的“ValuesController.Get”
如果你想要顯式指定日誌類別,則可以使用ILoggerFactory.CreateLogger
方法:
public class ValuesController : ControllerBase
{
private readonly ILogger _logger1;
public ValuesController(ILoggerFactory loggerFactory)
{
_logger1 = loggerFactory.CreateLogger("MyCategory");
}
}
配置日誌
預設模板中,日誌的配置如下(在appsettings.{Environment}.json檔案中):
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
針對所有日誌記錄提供程式進行配置
LogLevel
,顧名思義,就是指要記錄的日誌的最低階別(即要記錄大於等於該級別的日誌),想必大家都不陌生。下方會詳細介紹日誌級別。
LogLevel
中的欄位,如上面示例中的“Default”、“Microsoft”等,表示日誌的類別,也就是我們們上面注入ILogger
時指定的泛型引數。可以為每種類別設定記錄的最小日誌級別,也就是這些類別所對應的值。
下面詳細解釋一下示例中的三種日誌類別。
Default
預設情況下,如果分類沒有進行特別配置(即沒有在LogLevel
中配置),則應用Default
的配置。
Microsoft
所有分類以Microsoft
開頭的日誌均應用Microsoft
的配置。例如,Microsoft.AspNetCore.Routing.EndpointMiddleware
類別的日誌就會應用該配置。
Microsoft.Hosting.Lifetime
所有分類以Microsoft.Hosting.Lifetime
開頭的日誌均應用Microsoft.Hosting.Lifetime
的配置。例如,分類Microsoft.Hosting.Lifetime
就會應用該配置,而不會應用Microsoft
,因為Microsoft.Hosting.Lifetime
比Microsoft
更具體。
OK,以上三種日誌類別就說這些了。
回到示例,你可能沒有注意到,這裡面沒有針對某個日誌記錄提供程式進行單獨配置(如:Console只記錄Error及以上級別日誌,而EventSource則需要記錄記錄所有級別日誌)。像這種,如果沒有針對特定的日誌記錄提供程式進行配置,則該配置將會應用到所有日誌記錄提供程式。
Windows
EventLog
除外。EventLog
必須顯式地進行配置,否則會使用其預設的LogLevel.Warning
。
針對指定的日誌記錄提供程式進行配置
接下來看一下如何針對指定的日誌記錄提供程式進行配置,先上示例:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"LogLevel": {
"Default": "Error"
}
},
"Debug": {
"LogLevel": {
"Microsoft": "None"
}
},
"EventSource": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Trace",
"Microsoft.Hosting.Lifetime": "Trace"
}
}
}
}
就像appsettings.{Environment}.json
和appsettings.json
之間的關係一樣,Logging.{Provider}.LogLevel
中的配置將會覆蓋Logging.LogLevel
中的配置。
例如Logging.Console.LogLevel.Default
將會覆蓋Logging.LogLevel.Default
,Console
日誌記錄器將預設記錄Error
及其以上級別的日誌。
剛才提到了,Windows EventLog
比較特殊,它不會繼承Logging.LogLevel
的配置。EventLog
預設日誌級別為LogLevel.Warning
,如果想要修改,則必須顯式進行指定,如:
{
"Logging": {
"EventLog": {
"LogLevel": {
"Default": "Information"
}
}
}
}
配置的篩選原理
當建立ILogger<TCategoryName>
的物件例項時,ILoggerFactory
根據不同的日誌記錄提供程式,將會:
- 查詢匹配該日誌記錄提供程式的配置。如果找不到,則使用通用配置。
- 然後匹配擁有最長字首的配置類別。如果找不到,則使用
Default
配置。 - 如果匹配到了多條配置,則採用最後一條。
- 如果沒有匹配到任何配置,則使用
MinimumLevel
,這是個配置項,預設是LogLevel.Information
。
可以在
ConfigureLogging
擴充套件中使用SetMinimumLevel
方法設定MinimumLevel
。
Log Level
日誌級別指示了日誌的嚴重程度,一共分為7等,從輕到重為(最後的None
較為特殊):
日誌級別 | 值 | 描述 |
---|---|---|
Trace |
0 | 追蹤級別,包含最詳細的資訊。這些資訊可能包含敏感資料,預設情況下是禁用的,並且絕不能出現在生產環境中。 |
Debug |
1 | 除錯級別,用於開發人員開發和除錯。資訊量一般比較大,在生產環境中一定要慎用。 |
Information |
2 | 資訊級別,該級別平時使用較多。 |
Warning |
3 | 警告級別,一些意外的事件,但這些事件並不對導致程式出錯。 |
Error |
4 | 錯誤級別,一些無法處理的錯誤或異常,這些事件會導致當前操作或請求失敗,但不會導致整個應用出錯。 |
Critical |
5 | 致命錯誤級別,這些錯誤會導致整個應用出錯。例如記憶體不足等。 |
None |
6 | 指示不記錄任何日誌 |
日誌記錄提供程式
Console
日誌將輸出到控制檯中。
Debug
日誌將通過System.Diagnostics.Debug
類進行輸出,可以通過VS輸出視窗檢視。
在 Linux 上,可以在/var/log/message
或/var/log/syslog
下找到
EventSource
跨平臺日誌記錄,在Windows上則使用 ETW
Windows EventLog
僅在Windows系統下生效,可通過“事件檢視器”進行日誌檢視。
預設情況下
LogName
為“Application”SourceName
為“NET Runtime”MachineName
為本地計算機的名稱。
這些欄位都可以通過EventLogSettings
進行修改:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddEventLog(settings =>
{
settings.LogName = "My App";
settings.SourceName = "My Log";
settings.MachineName = "My Computer";
})
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
日誌記錄過濾器
通過日誌記錄過濾器,允許你書寫複雜的邏輯,來控制是否要記錄日誌。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging
// 針對所有 LoggerProvider 設定 Microsoft 最小日誌級別,建議通過配置檔案進行配置
.AddFilter("Microsoft", LogLevel.Trace)
// 針對 ConsoleLoggerProvider 設定 Microsoft 最小日誌級別,建議通過配置檔案進行配置
.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Debug)
// 針對所有 LoggerProvider 進行過濾配置
.AddFilter((provider, category, logLevel) =>
{
// 由於下面單獨針對 ConsoleLoggerProvider 新增了過濾配置,所以 ConsoleLoggerProvider 不會進入該方法
if (provider == typeof(ConsoleLoggerProvider).FullName
&& category == typeof(ValuesController).FullName
&& logLevel <= LogLevel.Warning)
{
// false:不記錄日誌
return false;
}
// true:記錄日誌
return true;
})
// 針對 ConsoleLoggerProvider 進行過濾配置
.AddFilter<ConsoleLoggerProvider>((category, logLevel) =>
{
if (category == typeof(ValuesController).FullName
&& logLevel <= LogLevel.Warning)
{
// false:不記錄日誌
return false;
}
// true:記錄日誌
return true;
});
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
日誌訊息模版
應用開發過程中,對於某一類的日誌,我們希望它們的訊息格式保持一致,僅僅是某些引數發生變化。這就要用到日誌訊息模板了。
舉個例子:
[HttpGet("{id}")]
public int Get(int id)
{
_logger.LogInformation("Get {Id}", id);
return id;
}
其中Get {Id}
就是一個日誌訊息模板,{Id}
則是模板引數(注意,請在裡面書寫名稱,而不是數字,這樣更容易理解引數含義)。
不過,需要注意的是,{Id}
這個模板引數,僅僅是用於讓人容易理解其含義的,和後面的引數名沒有任何關係,模板值關心引數的順序。例如:
[HttpGet("{id}")]
public int Get(int id)
{
_logger.LogInformation("Get {Id} at {Time}", DateTime.Now, id);
return id;
}
假設傳入id = 1,它的輸出是:Get 11/02/2021 11:42:14 at 1
日誌訊息模板是一項非常重要的功能,在眾多開源日誌中介軟體中,均有使用。
主機構建期間的日誌記錄
ASP.NET Core框架不直接支援在主機構建期間進行日誌記錄。但是可以通過獨立的日誌記錄提供程式進行日誌記錄,例如,使用第三方日誌記錄提供程式:Serilog
安裝Nuget包:Install-Package Serilog.AspNetCore
public static void Main(string[] args)
{
// 從appsettings.json和命令列引數中讀取配置
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddCommandLine(args)
.Build();
// 建立Logger
Log.Logger = new LoggerConfiguration()
.WriteTo.Console() // 輸出到控制檯
.WriteTo.File(config["Logging:File:Path"]) // 輸出到指定檔案
.CreateLogger();
try
{
CreateHostBuilder(args).Build().Run();
}
catch(Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
throw;
}
finally
{
Log.CloseAndFlush();
}
}
appsettings.json
{
"Logging": {
"File": {
"Path": "logs/host.log"
}
}
}
控制檯日誌格式配置
控制檯日誌記錄提供程式是我們開發過程中必不可少的,通過上面我們已經得知可以通過AddConsole()
進行新增。不過它的侷限性比較大,日誌格式我們都無法進行自定義。
因此,在.NET 5中,對控制檯日誌記錄提供程式進行了擴充套件,預置了三種日誌輸出格式:Json、Simple、Systemd。
實際上,之前也有列舉
ConsoleLoggerFormat
提供了Simple和Systemd格式,不過不能進行自定義,已經棄用了。
這些 Formatter 均繼承自抽象類ConsoleFormatter
,該抽象類建構函式接收一個“名字”引數,要求其實現類必須擁有名字。你可以通過靜態類ConsoleFormatterNames
獲取到內建的三種格式的名字。
public abstract class ConsoleFormatter
{
protected ConsoleFormatter(string name)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
}
public string Name { get; }
public abstract void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter);
}
public static class ConsoleFormatterNames
{
public const string Simple = "simple";
public const string Json = "json";
public const string Systemd = "systemd";
}
你可以在使用AddConsole()
時,配置ConsoleLoggerOptions
的FormatterName
屬性,以達到自定義格式的目的,其預設值為“simple”。不過,為了方便使用,.NET 框架已經把內建的三種格式幫我們封裝好了。
這些 Formatter 的選項類均繼承自選項類ConsoleFormatterOptions
,該選項類包含以下三個屬性:
public class ConsoleFormatterOptions
{
// 啟用作用域,預設 false
public bool IncludeScopes { get; set; }
// 設定時間戳的格式,顯示在日誌訊息開頭
// 預設為 null,不展示時間戳
public string TimestampFormat { get; set; }
// 是否將時間戳時區設定為 UTC,預設是false,即本地時區
public bool UseUtcTimestamp { get; set; }
}
SimpleConsoleFormatter
通過擴充套件方法AddSimpleConsole()
可以新增支援Simple
格式的控制檯日誌記錄提供程式,預設行為與AddConsole()
一致。
.ConfigureLogging(logging =>
{
logging.ClearProviders()
.AddSimpleConsole();
}
示例輸出:
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Repos\WebApplication
另外,你可以通過SimpleConsoleFormatterOptions
進行一些自定義配置:
.ConfigureLogging(logging =>
{
logging.ClearProviders()
.AddSimpleConsole(options =>
{
// 一條日誌訊息展示在同一行
options.SingleLine = true;
options.IncludeScopes = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";
options.UseUtcTimestamp = false;
});
}
示例輸出:
2021-11-02 15:53:33 info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000
2021-11-02 15:53:33 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down.
2021-11-02 15:53:33 info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development
2021-11-02 15:53:33 info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Repos\WebApplication
SystemdConsoleFormatter
通過擴充套件方法AddSystemdConsole()
可以新增支援Systemd
格式的控制檯日誌記錄提供程式。如果你熟悉Linux,那你對它也一定不陌生。
.ConfigureLogging(logging =>
{
logging.ClearProviders()
.AddSystemdConsole();
}
示例輸出:
<6>Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000
<6>Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down.
<6>Microsoft.Hosting.Lifetime[0] Hosting environment: Development
<6>Microsoft.Hosting.Lifetime[0] Content root path: C:\Repos\WebApplication
前面的<6>
表示日誌級別info,如果你有興趣瞭解Systemd,可以訪問阮一峰老師的Systemd 入門教程:命令篇
JsonConsoleFormatter
通過擴充套件方法AddJsonConsole()
可以新增支援Json
格式的控制檯日誌記錄提供程式。
.ConfigureLogging(logging =>
{
logging.ClearProviders()
.AddJsonConsole(options =>
{
options.JsonWriterOptions = new JsonWriterOptions
{
// 啟用縮排,看起來更舒服
Indented = true
};
});
}
示例輸出:
{
"EventId": 0,
"LogLevel": "Information",
"Category": "Microsoft.Hosting.Lifetime",
"Message": "Now listening on: http://localhost:5000",
"State": {
"Message": "Now listening on: http://localhost:5000",
"address": "http://localhost:5000",
"{OriginalFormat}": "Now listening on: {address}"
}
}
{
"EventId": 0,
"LogLevel": "Information",
"Category": "Microsoft.Hosting.Lifetime",
"Message": "Application started. Press Ctrl\u002BC to shut down.",
"State": {
"Message": "Application started. Press Ctrl\u002BC to shut down.",
"{OriginalFormat}": "Application started. Press Ctrl\u002BC to shut down."
}
}
{
"EventId": 0,
"LogLevel": "Information",
"Category": "Microsoft.Hosting.Lifetime",
"Message": "Hosting environment: Development",
"State": {
"Message": "Hosting environment: Development",
"envName": "Development",
"{OriginalFormat}": "Hosting environment: {envName}"
}
}
{
"EventId": 0,
"LogLevel": "Information",
"Category": "Microsoft.Hosting.Lifetime",
"Message": "Content root path: C:\\Repos\\WebApplication",
"State": {
"Message": "Content root path: C:\\Repos\\WebApplication",
"contentRoot": "C:\\Repos\\WebApplication",
"{OriginalFormat}": "Content root path: {contentRoot}"
}
}
如果你同時新增了多種格式的控制檯記錄程式,那麼只有最後一個新增的生效。
以上介紹的是通過程式碼進行控制檯日誌記錄提供程式的設定,不過我想大家應該更喜歡通過配置去設定日誌記錄提供程式。下面是一個簡單地配置示例:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"FormatterName": "json",
"FormatterOptions": {
"SingleLine": true,
"IncludeScopes": true,
"TimestampFormat": "yyyy-MM-dd HH:mm:ss ",
"UseUtcTimestamp": false,
"JsonWriterOptions": {
"Indented": true
}
}
}
}
}
ILogger<TCategoryName>物件例項的建立
講到這裡,不知道你會不會對ILogger<TCategoryName>
物件例項的建立有疑惑:它到底是如何被new
出來的呢?
要解決這個問題,我們先從AddLogging()
擴充套件方法入手:
public static class LoggingServiceCollectionExtensions
{
public static IServiceCollection AddLogging(this IServiceCollection services)
{
return AddLogging(services, builder => { });
}
public static IServiceCollection AddLogging(this IServiceCollection services, Action<ILoggingBuilder> configure)
{
services.AddOptions();
// 註冊單例 ILoggerFactory
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
// 註冊單例 ILogger<>
services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));
// 批量註冊單例 IConfigureOptions<LoggerFilterOptions>
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<LoggerFilterOptions>>(
new DefaultLoggerLevelConfigureOptions(LogLevel.Information)));
configure(new LoggingBuilder(services));
return services;
}
}
你可能也猜到了,這個Logger<>
不會是LoggerFactory
建立的吧?要不然註冊個這玩意幹嘛呢?
彆著急,我們們接著先檢視ILogger<>
服務的實現類Logger<>
:
public interface ILogger
{
void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);
// 檢查能否記錄該日誌等級的日誌
bool IsEnabled(LogLevel logLevel);
IDisposable BeginScope<TState>(TState state);
}
public interface ILogger<out TCategoryName> : ILogger
{
}
public class Logger<T> : ILogger<T>
{
// 介面實現內部均是使用該例項進行操作
private readonly ILogger _logger;
// 果不其然,注入了 ILoggerFactory 例項
public Logger(ILoggerFactory factory)
{
// 還記得嗎?上面提到顯式指定日誌類別時,也是這樣建立 ILogger 例項的
_logger = factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(typeof(T), includeGenericParameters: false, nestedTypeDelimiter: '.'));
}
// ...
}
沒錯,你猜對了,那就來看看這個LoggerFactory
吧(只列舉核心程式碼):
public interface ILoggerFactory : IDisposable
{
ILogger CreateLogger(string categoryName);
void AddProvider(ILoggerProvider provider);
}
public class LoggerFactory : ILoggerFactory
{
// 用於單例化 Logger<>
private readonly Dictionary<string, Logger> _loggers = new Dictionary<string, Logger>(StringComparer.Ordinal);
// 存放 ILoggerProviderRegistrations
private readonly List<ProviderRegistration> _providerRegistrations = new List<ProviderRegistration>();
private readonly object _sync = new object();
public LoggerFactory(IEnumerable<ILoggerProvider> providers, IOptionsMonitor<LoggerFilterOptions> filterOption, IOptions<LoggerFactoryOptions> options = null)
{
// ...
// 註冊 ILoggerProviders
foreach (ILoggerProvider provider in providers)
{
AddProviderRegistration(provider, dispose: false);
}
// ...
}
public ILogger CreateLogger(string categoryName)
{
lock (_sync)
{
// 如果不存在,則 new
if (!_loggers.TryGetValue(categoryName, out Logger logger))
{
logger = new Logger
{
Loggers = CreateLoggers(categoryName),
};
(logger.MessageLoggers, logger.ScopeLoggers) = ApplyFilters(logger.Loggers);
// 單例化 Logger<>
_loggers[categoryName] = logger;
}
return logger;
}
}
private void AddProviderRegistration(ILoggerProvider provider, bool dispose)
{
_providerRegistrations.Add(new ProviderRegistration
{
Provider = provider,
ShouldDispose = dispose
});
// ...
}
private LoggerInformation[] CreateLoggers(string categoryName)
{
var loggers = new LoggerInformation[_providerRegistrations.Count];
// 迴圈遍歷所有 ILoggerProvider
for (int i = 0; i < _providerRegistrations.Count; i++)
{
loggers[i] = new LoggerInformation(_providerRegistrations[i].Provider, categoryName);
}
return loggers;
}
}
注意
- 若要在
Startup.Configure
方法中記錄日誌,直接在引數上注入ILogger<Startup>
即可。 - 不支援在
Startup.ConfigureServices
方法中使用ILogger
,因為此時DI容器還未配置完成。 - 沒有非同步的日誌記錄方法。日誌記錄動作執行應該很快,不值的犧牲效能使用非同步方法。如果日誌記錄動作比較耗時,如記錄到MSSQL中,那麼請不要直接寫入MSSQL。你應該考慮先將日誌寫入到快速儲存介質,如記憶體佇列,然後通過後臺工作執行緒將其從記憶體轉儲到MSSQL中。
- 無法使用日誌記錄 API 在應用執行時更改日誌記錄配置。不過,一些配置提供程式(如檔案配置提供程式)可重新載入配置,這可以立即更新日誌記錄配置。
小結
Host.CreateDefaultBuilder
方法中,預設新增了Console
、Debug
、EventSource
和EventLog
(僅Windows)共四種日誌記錄提供程式(Logger Provider)。- 通過注入服務
ILogger<TCategoryName>
,可以方便的進行日誌記錄。 - 可以通過程式碼或配置對日誌記錄提供程式進行設定,如
LogLevel
、FormatterName
等。 - 可以通過擴充套件方法
AddFilter
新增日誌記錄過濾器,允許你書寫複雜的邏輯,來控制是否要記錄日誌。 - 支援日誌訊息模板。
- 對於控制檯記錄日誌程式,.NET框架內建了
Simple
(預設)、Systemd
、Json
三種日誌輸出格式。 - .NET 6 預覽版中新增了一個稱為“編譯時日誌記錄源生成”的功能,該功能非常實用,有興趣的可以先去瞭解一下。
- 最後,給大家列舉一些常用的日誌開源中介軟體: