在本章中,也就是整個系列的第一部分將介紹如何定制日志記錄(系列內容查閱《玩轉ASP.NET 6.0框架-序言》)。默認日志記錄僅寫入控制臺或調試窗口,這在大多數情況下都很好,但有時需要寫入到文件或數據庫,或者,您可能希望擴展日志記錄的其他信息。在這些情況下,您需要知道如何更改默認日志記錄。
在本章,我們將介紹以下主題:
配置日志記錄
創建自定義日志記錄
使用第三方日志框架
以上主題涉及ASP.NET Core
框架的Host
層。
技術要求
為了演示,我們創建一個ASP.NET Core MVC
應用程序。請打開控制臺、shell
或Bash
終端,然后切換到工作目錄,然后使用以下命令創建新的應用程序:
dotnet new mvc -n LoggingSample -o LoggingSample
在Visual Studio
中雙擊打開該項目,或者在控制臺中鍵入以下命令用Visual Studio Code
打開該項目:
cd LoggingSample code .
配置日志記錄
在ASP.NET Core
的早期版本中(即2.0版之前的版本),日志記錄是在Startup.cs
配置的。之后Startup.cs
文件慢慢簡化,許多配置被移動到Program.cs
的WebHostBuilder
,日志記錄也是在這個時候被移動到WebHostBuilder
。
在ASP.NET Core 3.1
及更高版本的程序,Program.cs
文件變得更加通用,IHostBuilder
將最先創建,它是引導應用啟動的關鍵(我們將在后面詳解IHostBuilder
),通過IHostBuilder
,我們可以創建IWebHostBuilder
用以配置ASP.NET Core
:
public class Program { public static void Main(string[] args){ CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>();});
}
在ASP.NET Core 6.0
中,Microsoft
引入了簡化配置的迷你API(minimal API
)方法。這種方法不使用Startup
文件,而是將所有配置添加到Program.cs
文件,如下代碼段:
var builder = WebApplication.CreateBuilder(args); //添加服務到容器.
builder.Services.AddControllersWithViews();
var app = builder.Build();
…
在ASP.NET Core
,您可以覆蓋和自定義幾乎所有內容,包括日志記錄。IWebHostBuilder
有很多擴展方法,允許我們覆蓋不同功能的默認行為。要覆蓋日志記錄的默認設置,我們需要使用ConfigureLogging
方法。
以下代碼片段顯示的日志記錄與上面的ConfigureWebHostDefaults()
方法中配置的日志記錄幾乎完全相同:
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{ webBuilder.ConfigureLogging((hostingContext, logging) => {logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }).UseStartup<Startup>();
使用
minimal API
方法,我們不再需要ConfigureLogging
方法,我們可以直接使用WebApplicationBuilder
的Logging
屬性:
builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
builder.Logging.AddConsole();
builder.Logging.AddDebug();
現在我們已經了解了如何配置日志記錄,接下來我們看看如何自定義日志記錄。
創建自定義日志記錄
為了演示,我們這里創建一個小而簡單的日志記錄器,它能夠在控制臺中使用特定的日志級別對日志條目進行著色。此日志記錄稱為ColoredConsoleLogger
,它會使用LoggerProvider
創建。要指定顏色和日志級別,我們還需要添加一個配置類Configuration
。
在接下來的代碼片段中,將分別創建這三個關鍵類(Configuration
、LoggerProvider
和Logger
):
1.ColoredConsoleLoggerConfiguration
我們創建一個名為CustomLogger.cs
的文件中,它與Program.cs
位于同一文件夾中,我們在CustomLogger.cs
中創建ColoredConsoleLoggerConfiguration
,該配置類包含三個可設置的屬性:LogLevel
、EventId
和Color
:
public class ColoredConsoleLoggerConfiguration
{ public LogLevel LogLevel { get; set; } = LogLevel.Warning; public int EventId { get; set; } = 0; public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}
2.ColoredConsoleLoggerProvider
接下來,我們需要一個提供程序來檢索配置并創建實際的日志記錄實例
public class ColoredConsoleLoggerProvider : ILoggerProvider
{ private readonly ColoredConsoleLoggerConfiguration _config; private readonly ConcurrentDictionary<string, ColoredConsoleLogger> _loggers = new ConcurrentDictionary<string,ColoredConsoleLogger>(); public ColoredConsoleLoggerProvider (ColoredConsoleLoggerConfiguration config) { _config = config; } public ILogger CreateLogger(string categoryName) { return _loggers.GetOrAdd(categoryName,name => new ColoredConsoleLogger(name, _config)); }public void Dispose() {_loggers.Clear(); }
}
不要忘記引入
System.Collections.Concurrent
3.ColoredConsoleLogger
第三類是我們真正使用的日志記錄器:
public class ColoredConsoleLogger : ILogger
{private static readonly object _lock = new Object();private readonly string _name;private readonly ColoredConsoleLoggerConfiguration _config;public ColoredConsoleLogger(string name,ColoredConsoleLoggerConfiguration config){_name = name;_config = config;}public IDisposable BeginScope<TState>(TState state){return null;}public bool IsEnabled(LogLevel logLevel){return logLevel == _config.LogLevel;}public void Log<TState>(LogLevel logLevel,EventId eventId,TState state,Exception exception,Func<TState, Exception, string> formatter){if (!IsEnabled(logLevel)){return;}lock (_lock){if (_config.EventId == 0 || _config.EventId == eventId.Id){var color = Console.ForegroundColor;Console.ForegroundColor = _config.Color;Console.Write($"{logLevel} - ");Console.Write($"{eventId.Id} - {_name} - ");Console.Write($"{formatter(state, exception)}\n");Console.ForegroundColor = color;}}}
}
我們現在需要lock
(鎖定) 控制臺的輸出——這是因為控制臺本身并不是真正的線程安全的,可能出現錯誤的著色。
完成后,我們可以將新的記錄插入到Program.cs
的配置中。
using LoggingSample;builder.Logging.ClearProviders();
var config = new ColoredConsoleLoggerConfiguration
{LogLevel = LogLevel.Information,Color = ConsoleColor.Red
};
builder.Logging.AddProvider(new ColoredConsoleLoggerProvider(config));
首先需要向引入LoggerSample
命名空間。
using LoggingSample;
如果不想使用現有的日志框架,可以清除之前添加的所有日志框架提供程序
builder.Logging.ClearProviders();
然后,我們調用AddProvider
來添加ColoredConsoleLoggerProvider
實例。
這里配置了不同的日志級別,您可以使用這種方法發送有關錯誤的電子郵件,或者將調試消息記錄到別的日志接收器等等。
下圖顯示了日志框架的彩色輸出:
在許多時候,編寫自定義日志框架是沒有意義的,因為已經有許多優秀的第三方日志記錄框架可用,例如ELMAH
、log4net
和NLog
。
下面,我們將介紹如何在ASP.NET Core
中使用NLog
。
使用第三方日志框架NLog
NLog
是最早的一款可用于ASP.NET Core
的日志框架,NLog
提供了一個日志記錄提供程序插件,可以方便地插入ASP.NET Core
。(你可以通過NuGet
找到NLog)
1.配置Nlog
我們需要添加一個NLog.Config
配置文件,用于定義兩個不同的日志記錄:
所有標準消息記錄在一個日志文件中;
而自定義消息記錄在另一個文件中
<targets><!-- 標準消息 --><target xsi:type="File" name="allfile" fileName="C:\git\dotnetconf\001-logging\nlog-all-${shortdate}.log"layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}|${message} ${exception}" /><!-- 自定義消息 --><target xsi:type="File" name="ownFile-web" fileName="C:\git\dotnetconf\001-logging\nlog-own-${shortdate}.log"layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}| ${message} ${exception}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" /><target xsi:type="Null" name="blackhole" /></targets><!-- rules to map from logger name to target --><rules><!--All logs, including from Microsoft--><logger name="*" minlevel="Trace" writeTo="allfile" /><!--Skip Microsoft logs and so log only own logs--><logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" /><logger name="*" minlevel="Trace" writeTo="ownFile-web" /></rules>
2.引入NuGet包
然后我們需要NuGet
添加NLog
的ASP.NET Core
包:
dotnet add package NLog.Web.AspNetCore
3.將NLog
與IWebHostBuilder
結合使用
清除ConfigureLogging
方法中的其他提供程序,使用UseNLog()
方法將NLog
與IWebHostBuilder
結合使用:
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureLogging((hostingContext,logging) => { //清除其他提供程序 logging.ClearProviders(); logging.SetMinimumLevel(LogLevel.Trace); }).UseNLog().UseStartup<Startup>();
});
使用minimal API
看起來簡單得多:
using NLog.Web; var builder = WebApplication.CreateBuilder(args); //清除其他提供程序
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.WebHost.UseNLog();
在這里,您可以根據需要添加任意多個日志記錄提供程序。
回顧 & 思考
現在,讓我們回顧一下本文所涵蓋的內容:
配置日志記錄
創建自定義日志記錄
使用第三方日志框架
思考:我們應該如何自定義應用的配置?歡迎關注下篇內容《如何自定義.NET 6.0的應用配置》。