日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core 源码学习之 Logging[2]:Configure

發布時間:2023/12/4 asp.net 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 源码学习之 Logging[2]:Configure 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一章中,我們對 ASP.NET Logging 系統做了一個整體的介紹,而在本章中則開始從最基本的配置開始,逐步深入到源碼當中去。

默認配置

在 ASP.NET Core 2.0 中,對默認配置做了很大的簡化,并把一些基本配置移動到了程序的入口點?Program?類中,更加簡潔。

public class Program{ ?

?public static void Main(string[] args) ? ?{BuildWebHost(args).Run();} ?
?
??public static IWebHost BuildWebHost(string[] args) =>WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build(); }

如上,可以看到基本的配置都放到了?CreateDefaultBuilder?方法中,而?WebHost則在?MetaPackages?中,提供了一些簡化方法。

public static IWebHostBuilder CreateDefaultBuilder(string[] args){ ? ?

var builder = new WebHostBuilder().UseKestrel().UseContentRoot(Directory.GetCurrentDirectory()).ConfigureAppConfiguration((hostingContext, config) =>{ ? ? ? ?
? ? ? ? ?? ?var env = hostingContext.HostingEnvironment;config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); ?
? ? ? ? ?? ?? ?if (env.IsDevelopment()){ ? ? ? ? ? ? ?
? ? ? ? ?? ?? ? ?var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); ? ? ? ?
? ? ? ? ?? ?? ? if (appAssembly != null){config.AddUserSecrets(appAssembly, optional: true);}}config.AddEnvironmentVariables(); ? ?
? ? ? ? ?? if (args != null){config.AddCommandLine(args);}}).ConfigureLogging((hostingContext, logging) =>{logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));logging.AddConsole();logging.AddDebug();}).UseIISIntegration().UseDefaultServiceProvider((context, options) =>{options.ValidateScopes = context.HostingEnvironment.IsDevelopment();}); ?
? ? ? ??return builder; }

如上可以看到一些我們在 1.0 中非常熟悉的代碼,而?ConfigureLogging?則是?IWebHostBuilder?類的一個擴展方法:

public static IWebHostBuilder ConfigureLogging(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, ILoggingBuilder> configureLogging){ ?

?return hostBuilder.ConfigureServices((context, collection) => collection.AddLogging(builder => configureLogging(context, builder))); }

而?AddLogging?則是 Logging 系統的入口點,是由?Microsoft.Extensions.Logging?所提供的擴展方法:

public static IServiceCollection AddLogging(this IServiceCollection services, Action<ILoggingBuilder> configure){ ?
?if (services == null){ ? ? ?
? ?throw new ArgumentNullException(nameof(services));}services.AddOptions();services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>))); ? ?services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<LoggerFilterOptions>>( ? ? ?
? ? ?new DefaultLoggerLevelConfigureOptions(LogLevel.Information)));configure(new LoggingBuilder(services)); ?
? ? ? ?return services; }

首先注冊了 Logging 系統基本服務的默認實現,用來激活 Logging 系統,然后創建?LoggingBuilder?對象,而后一系列對日志系統的配置,都是調用的該對象的擴展方法。

internal class LoggingBuilder : ILoggingBuilder{ ?
?public LoggingBuilder(IServiceCollection services) ? ?{Services = services;} ? ?public IServiceCollection Services { get; } }

現在回頭看看?CreateDefaultBuilder方法中通過?ConfigureLogging?來對日志系統所做的默認配置。

AddConfiguration

該方法是對日志系統的一個全局配置:

logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));

public static ILoggingBuilder AddConfiguration(this ILoggingBuilder builder, IConfiguration configuration){builder.Services.AddSingleton<IConfigureOptions<LoggerFilterOptions>>(new LoggerFilterConfigureOptions(configuration));builder.Services.AddSingleton<IOptionsChangeTokenSource<LoggerFilterOptions>>(new ConfigurationChangeTokenSource<LoggerFilterOptions>(configuration)); ?
?return builder; }

首先使用?Options?模式注冊了一個?LoggerFilterOptions:

public class LoggerFilterOptions{
? ?public LogLevel MinLevel { get; set; } ?
? ? ?public IList<LoggerFilterRule> Rules { get; } = new List<LoggerFilterRule>(); }
? ? ?public class LoggerFilterRule{... ?
? ? ??public string ProviderName { get; } ?
? ? ??public string CategoryName { get; } ?
? ? ?? ?public LogLevel? LogLevel { get; } ?
? ? ?? ??public Func<string, string, LogLevel, bool> Filter { get; }.... }

而默認實現?LoggerFilterConfigureOptions?的邏輯很簡單,就是從配置文件中讀取?LogLevel?的配置:

internal class LoggerFilterConfigureOptions : IConfigureOptions<LoggerFilterOptions> {... ?
?private void LoadDefaultConfigValues(LoggerFilterOptions options) ? ?{ ? ? ? ?if (_configuration == null){ ? ? ? ?
? ? ?return;} ? ? ? ?
? ? ?foreach (var configurationSection in _configuration.GetChildren()){ ? ? ? ?
? ? ?? ?if (configurationSection.Key == "LogLevel"){ ? ? ? ? ? ?
? ? ?? ? ? ?// Load global category defaultsLoadRules(options, configurationSection, null);} ? ? ?
? ? ?? ? ? else{ ? ? ??var logLevelSection = configurationSection.GetSection("LogLevel"); ? ? ?
? ? ?? ? ? ? ? ? ? ?if (logLevelSection != null){ ? ? ? ? ? ? ? ? ? ?// Load logger specific rulesvar logger = configurationSection.Key;LoadRules(options, logLevelSection, logger);}}}} ?
? ? ?? ?
? ? ?? ??private void LoadRules(LoggerFilterOptions options, IConfigurationSection configurationSection, string logger) ?
?
{ ? ? ?
? ? ?? ???foreach (var section in configurationSection.AsEnumerable(true)){ ? ? ? ? ?
? ? ?? ??? ?if (TryGetSwitch(section.Value, out var level)){ ? ? ? ? ? ?
? ? ?? ??? ?? ?var category = section.Key; ? ?
? ? ?? ??? ?? ? ? ? ? ?if (category == "Default"){category = null;} ? ? ? ? ? ? ?
? ? ?? ??? ?? ? ? ? ? ? ?var newRule = new LoggerFilterRule(logger, category, level, null);options.Rules.Add(newRule);}}}... }

通過代碼,我們可以清楚的知道,我們的配置文件應該按如下格式來定義

{"Logging": {"LogLevel": { // 表示全局"Default": "Warning" // 不指定CategoryName,應用于所有Category},"Console":{ // 指定 ProviderName,僅針對于 ConsoleProvider"Default": "Warning","Microsoft": "Error" // 指定CategoryName為Microsoft的日志級別為Error}}}

而?IOptionsChangeTokenSource 是對上面?IConfigureOptions 的一個補充,為我們獲取?OptionsMonitor?注入了必要的服務,更多關于 Options 的介紹可以看我之前文章?IOptionsMonitor。

而在 Logging 系統中,也是通過注入?IOptionsMonitor<LoggerFilterOptions>?來使用?LoggerFilterOptions?的:

public LoggerFactory(IEnumerable<ILoggerProvider> providers, IOptionsMonitor<LoggerFilterOptions> filterOption){
_providerRegistrations = providers.Select(provider => new ProviderRegistration { Provider = provider }).ToList();
_changeTokenRegistration = filterOption.OnChange(RefreshFilters);RefreshFilters(filterOption.CurrentValue); }

AddConsole

上面我們提到,在配置文件中可以指定針對某個 Provider 的配置,而?AddConsole?則是用來添加一個 Console 類型的 Provider,用來將日志記錄到控制臺中:

public static ILoggingBuilder AddConsole(this ILoggingBuilder builder){builder.Services.AddSingleton<ILoggerProvider, ConsoleLoggerProvider>(); ?
?return builder; }
?public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action<ConsoleLoggerOptions> configure){ ?
??if (configure == null){ ? ? ?
?? ?throw new ArgumentNullException(nameof(configure));}builder.AddConsole();builder.Services.Configure(configure); ?
?? ? ?return builder; }

以上代碼在?Microsoft.Extensions.Logging.Console?Package 中,首先提供了?ILoggerProvider?的注入方法,用來啟用控制臺的日志記錄功能,而且還提供了一個方法重載,用來指定針對 ConsoleProvider 的配置。

AddDebug

而 AddDebug 與 AddConsole 類似,只不過是把日志輸出在 Debug 窗口中。

更多關于 Provider 的配置,會在以后再詳細探索。

自定義配置

上面介紹了 ASP.NET Core 中對日志系統的默認配置,那么如果我們想再添加一些其它配置應該怎么做呢?

在 1.0 時代,我們通過是在 Startup 類中的 Configure 方法中,注入?ILoggerFactory?來進行配置,當然,在 2.0 中我們仍然可以這樣做,但是更加推薦的做法是在 Program 入口方法中進行配置,而 Configure 方法通過是對一些中間件的配置。

我們可以直接使用上面介紹過的?ConfigureLogging?擴展方法來添加我們自己的配置:

public static IWebHost BuildWebHost(string[] args) =>WebHost.CreateDefaultBuilder(args).ConfigureLogging(build =>{build.AddFilter(f => f == LogLevel.Debug);build.AddEventSourceLogger();}).UseStartup<Startup>().Build();

我們添加了一個 EventSource Provider,并且使用了?AddFilter擴展方法對日志的過濾進行配置。而?AddFilter?的作用類似于 前面介紹的?AddConfiguration,只是把配置方式從配置文件變成了代碼。

public static class FilterLoggingBuilderExtensions{ ?
?// 具有多個重載,此處省略public static ILoggingBuilder AddFilter(this ILoggingBuilder builder, Func<string, string, LogLevel, bool> filter) =>builder.ConfigureFilter(options => options.AddFilter(filter)); ?
?
??private static ILoggingBuilder ConfigureFilter(this ILoggingBuilder builder, Action<LoggerFilterOptions> configureOptions) ? ?{builder.Services.Configure(configureOptions); ? ? ?
???return builder;} }

可以看到,最終也是對?ConfigureOptions?的配置,而后執行的配置會覆蓋之前配置的。

總結

本章從 Logging 系統的起始點入手,詳細分析了如何對 Logging 系統進行配置,分為日志級別過濾和日志提供者兩種配置,而下一章則會分析一下日志的過濾原理。

相關文章:?

  • ASP.NET Core 源碼學習之 Options[1]:Configure

  • ASP.NET Core 源碼學習之 Options[2]:IOptions

  • ASP.NET Core 源碼學習之 Options[3]:IOptionsSnapshot

  • ASP.NET Core 源碼學習之 Options[4]:IOptionsMonitor

  • ASP.NET Core 源碼學習之Logging[1]:Introduction

  • ASP.NET Core MVC 源碼學習:詳解 Action 的匹配

  • asp.net core源碼飄香:從Hosting開始

  • asp.net core源碼飄香:Configuration組件

  • asp.net core源碼飄香:Options組件

  • asp.net core源碼飄香:Logging組件

原文地址:http://www.cnblogs.com/RainingNight/p/asp-net-core-logging-configure.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的ASP.NET Core 源码学习之 Logging[2]:Configure的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。