当前位置: 首页 > news >正文

梅州建设工程交易中心网站做设计常逛的网站

梅州建设工程交易中心网站,做设计常逛的网站,做网站怎么赚钱 知乎,wordpress comer前言鲁迅都说#xff1a;没有日志的系统不能上线(鲁迅说#xff1a;这句我没说过#xff0c;但是在理)#xff01;日志对于一个系统而言#xff0c;特别重要#xff0c;不管是用于事务审计#xff0c;还是用于系统排错#xff0c;还是用于安全追踪.....都扮演了很重要的… 前言鲁迅都说没有日志的系统不能上线(鲁迅说这句我没说过但是在理)日志对于一个系统而言特别重要不管是用于事务审计还是用于系统排错还是用于安全追踪.....都扮演了很重要的角色之前有很多第三方的日志框架也很给力如Log4Net、NLog和Serilog等在.NetCore中也集成了日志模型使用便捷同时很方便的与第三方日志框架进行集成扩展正文实例演示之前先了解一下日志级别后续如果不想输出全部日志可以通过日志级别进行过滤同时通过日志级别可以标注日志内容的重要程度namespace Microsoft.Extensions.Logging {// 日志级别从下往上递增所以根据级别可以过滤掉低级别的日志信息public enum LogLevel{Trace,Debug,Information,Warning,Error,Critical,None} } 来一个控制台程序实例演示运行结果咋样使用还是依旧简单这里是控制台程序还需要写配置框架和依赖注入相关的代码逻辑如果在WebAPI项目直接就可以使用日志记录了如下对于WebAPI项目而言在项目启动流程分析的时候就提到内部已经注册了相关服务了所以才能这样如此简单的使用难道日志就这样结束了吗猜想看到这的小伙伴也不甘心是的得进一步了解不需要特别深入但至少得知道关键嘛对不对老规矩程序中能看到日志相关点当然就从这开始看看是如何注册日志啊相关服务的对应代码namespace Microsoft.Extensions.DependencyInjection {// IServiceCollection的扩展方法用于注册日志相关服务public static class LoggingServiceCollectionExtensions{public static IServiceCollection AddLogging(this IServiceCollection services){return services.AddLogging(delegate{});}// 核心方法上面的方法就是调用下面这个public static IServiceCollection AddLogging(this IServiceCollection services, ActionILoggingBuilder configure){if (services null){throw new ArgumentNullException(services);}// 为了支持Options选项得注册Options相关服务上篇讲过services.AddOptions();// 注册ILoggerFactoryservices.TryAdd(ServiceDescriptor.SingletonILoggerFactory, LoggerFactory());// 注册ILoggerservices.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger), typeof(Logger)));// 注册日志级别过滤并默认设置级别为Informationservices.TryAddEnumerable(ServiceDescriptor.Singleton((IConfigureOptionsLoggerFilterOptions)new DefaultLoggerLevelConfigureOptions(LogLevel.Information)));// 执行传入的委托方法configure(new LoggingBuilder(services));return services;}} } 日志相关服务注册了解了那接着看看关键实现其实日志记录有三个核心类型ILogger、ILoggerFactory和ILoggerProvider对应的实现分别是Logger、LoggerFactory、xxxLoggerProviderxxxLoggerProvider针对于不同的目的地创建对应的xxxLogger这里的xxxLogger负责在目的地(文件、数据库、控制台等)写入内容;LoggerFactory负责创建Logger其中包含所有注册的xxxLoggerProvider对应LoggerLogger以上两种;    扒开这三个类型的定义简单看看都定义了什么....ILogger/Loggernamespace Microsoft.Extensions.Logging {public interface ILogger{// 记录日志方法其中包含日志级别、事件ID、写入的内容、格式化内容等void LogTState(LogLevel logLevel, EventId eventId, TState state, Exception exception, FuncTState, Exception, string formatter);// 判断对应的日志级别是否可用bool IsEnabled(LogLevel logLevel);// 日志作用域IDisposable BeginScopeTState(TState state);} } Logger中挑了比较关键的属性和方法简单说说internal class Logger : ILogger {// 用于缓存真正Logger记录器的public LoggerInformation[] Loggers { get; set; }public MessageLogger[] MessageLoggers { get; set; }// 这个用于缓存日志作用域Loggers    public ScopeLogger[] ScopeLoggers { get; set; }// Log日志记录方法 public void LogTState(LogLevel logLevel, EventId eventId, TState state, Exception exception, FuncTState, Exception, string formatter){var loggers MessageLoggers;if (loggers null){return;}ListException exceptions null;// 遍历对应的Loggers for (var i 0; i loggers.Length; i){ref readonly var loggerInfo ref loggers[i];if (!loggerInfo.IsEnabled(logLevel)){continue;}// 执行内部方法LoggerLog(logLevel, eventId, loggerInfo.Logger, exception, formatter, ref exceptions, state);}if (exceptions ! null exceptions.Count 0){ThrowLoggingError(exceptions);}static void LoggerLog(LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, FuncTState, Exception, string formatter, ref ListException exceptions, in TState state){try{// 记录日志内容 logger.Log(logLevel, eventId, state, exception, formatter);}catch (Exception ex){if (exceptions null){exceptions new ListException();}exceptions.Add(ex);}}} } ILoggerFactory/LoggerFactorynamespace Microsoft.Extensions.Logging {// 创建 ILogger和注册LoggerProviderpublic interface ILoggerFactory : IDisposable{// 根据名称创建ILogger    ILogger CreateLogger(string categoryName);// 注册ILoggerProvidervoid AddProvider(ILoggerProvider provider);} } ........省略方法-私下研究...... // LoggerFactory挑了几个关键方法进行说明 // 创建Logger public ILogger CreateLogger(string categoryName) {if (CheckDisposed()){throw new ObjectDisposedException(nameof(LoggerFactory));}lock (_sync){if (!_loggers.TryGetValue(categoryName, out var logger)){// new一个Logger这是LoggerFactory管理的Logger        logger new Logger{// 根据注册的xxxLoggerProvider创建具体的xxxLogger// 并将其缓存到LoggerFactory创建的Logger对应的Loggers属性中                            Loggers CreateLoggers(categoryName),};// 根据消息级别和作用域范围赋值对应的MessageLoggers、ScopeLoggers(logger.MessageLoggers, logger.ScopeLoggers) ApplyFilters(logger.Loggers);// 同时将创建出来的logger缓存在字典中_loggers[categoryName] logger;}return logger;} } // 这个用于注册具体的xxxLoggerProvider public void AddProvider(ILoggerProvider provider) {if (CheckDisposed()){throw new ObjectDisposedException(nameof(LoggerFactory));}lock (_sync){// 将传入的provider封装了结构体进行缓存   AddProviderRegistration(provider, dispose: true);// 同时创建对应的logger,创建过程和上面一样foreach (var existingLogger in _loggers){var logger existingLogger.Value;var loggerInformation logger.Loggers;// 在原来基础上增加具体的xxxLoggervar newLoggerIndex loggerInformation.Length;Array.Resize(ref loggerInformation, loggerInformation.Length 1);loggerInformation[newLoggerIndex] new LoggerInformation(provider, existingLogger.Key);logger.Loggers loggerInformation;(logger.MessageLoggers, logger.ScopeLoggers) ApplyFilters(logger.Loggers);}} } // 封装对应的xxxLoggerProvider然后进行缓存 private void AddProviderRegistration(ILoggerProvider provider, bool dispose) {// 先封装成结构体然后在缓存方便后续生命周期管理_providerRegistrations.Add(new ProviderRegistration{Provider provider,ShouldDispose dispose});// 判断是否继承了ISupportExternalScope if (provider is ISupportExternalScope supportsExternalScope){if (_scopeProvider null){_scopeProvider new LoggerExternalScopeProvider();}supportsExternalScope.SetScopeProvider(_scopeProvider);} } // 创建具体的xxxLogger private LoggerInformation[] CreateLoggers(string categoryName) {// 根据注册的xxxLoggerProvider个数初始化一个数组var loggers new LoggerInformation[_providerRegistrations.Count];// 遍历注册的xxxLoggerProvider创建具体的xxxLogger   for (var i 0; i _providerRegistrations.Count; i){// 创建具体的xxxLogger    loggers[i] new LoggerInformation(_providerRegistrations[i].Provider, categoryName);}return loggers; } ........省略方法-私下研究...... ILoggerProvider/xxxLoggerProvidernamespace Microsoft.Extensions.Logging {public interface ILoggerProvider : IDisposable{// 根据名称创建对应的LoggerILogger CreateLogger(string categoryName);} } namespace Microsoft.Extensions.Logging {public interface ILoggerProvider : IDisposable{// 根据名称创建对应的LoggerILogger CreateLogger(string categoryName);} } namespace Microsoft.Extensions.Logging.Console {[ProviderAlias(Console)]public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope{// 支持Options动态监听  private readonly IOptionsMonitorConsoleLoggerOptions _options;// 缓存对应的xxxLogger        private readonly ConcurrentDictionarystring, ConsoleLogger _loggers;// 日志处理        private readonly ConsoleLoggerProcessor _messageQueue;private IDisposable _optionsReloadToken;private IExternalScopeProvider _scopeProvider NullExternalScopeProvider.Instance;// 构造函数初始化public ConsoleLoggerProvider(IOptionsMonitorConsoleLoggerOptions options){_options options;_loggers new ConcurrentDictionarystring, ConsoleLogger();ReloadLoggerOptions(options.CurrentValue);_optionsReloadToken _options.OnChange(ReloadLoggerOptions);_messageQueue new ConsoleLoggerProcessor();// 判断是否是Windows系统因为即日至的方式不一样            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)){ // 如果是windows_messageQueue.Console new WindowsLogConsole();_messageQueue.ErrorConsole new WindowsLogConsole(stdErr: true);}else{ // 如果是其他平台_messageQueue.Console new AnsiLogConsole(new AnsiSystemConsole());_messageQueue.ErrorConsole new AnsiLogConsole(new AnsiSystemConsole(stdErr: true));}}private void ReloadLoggerOptions(ConsoleLoggerOptions options){foreach (var logger in _loggers){logger.Value.Options options;}}// 根据名称获取或创建对应xxxLoggerpublic ILogger CreateLogger(string name){// 根据名称获取如果没有则根据传入的委托方法进行创建        return _loggers.GetOrAdd(name, loggerName new ConsoleLogger(name, _messageQueue){Options _options.CurrentValue,ScopeProvider _scopeProvider});}......省略一些方法,私下研究.......} }想了想这里就不一一针对不同目的地(比如Trace、EventLog)扒代码看了不然说着说着就变成了代码解读了如果有兴趣可以私下照着以下思路去看看代码每一个目的地日志记录都会有一个实现xxxLoggerProvider和对应的记录器xxxLogger(真实记录日志内容)LoggerFactory创建的Logger(暴露给程序员使用的)包含了对应的具体的记录器比如以写入日志控制台为例有一个ConsoleLoggerProvider的实现和对应的ConsoleLoggerConsoleLoggerProvider负责通过名称创建对应的ConsoleLogger而LoggerFactory创建出来的Logger就是包含已注册ConsoleLoggerProvider创建出来的ConsoleLogger从而我们调用记录日志方法的时候其实最终是调用ConsoleLoggerProvider创建的ConsoleLogger对象方法 总结本来想着日志应该用的很频繁了直接举例演示就OK了但是写着写着用的多不一定清除关键步骤于是又扒了下代码挑出了几个关键方法简单的说说希望使用的小伙伴不困惑深入研究就靠私下好好瞅瞅代码了下一节实例演示日志的使用、日志的作用域、集成第三方日志框架进行日志扩展.....------------------------------------------------一个被程序搞丑的帅小伙关注Code综艺圈识别关注跟我一起学~~~
http://www.zqtcl.cn/news/167597/

相关文章:

  • 网站设计宽屏尺寸盐城网站建设渠道合作
  • 网站所有者查询hexo做网站
  • 杭州专业网站设计策划大数据网站建设和
  • 建一个自己的网站需要多少钱泰州网站快速排名优化
  • 企业网站的建设企业湖南网络推广
  • 山西省建设厅投诉网站郴州新网交友手机版
  • 营销网站建设是什么flash个人网站欣赏
  • 网站建设最简单的教程视频教程建设厅注册中心网站首页
  • 免费做网站凡科wordpress 分享到微信 插件
  • 购物网站项目建设内容有啥网站是专做时尚穿搭
  • 网上下载的网站模板怎么用wordpress 注册密码
  • 网站建设免费国外撤销网站备案申请书
  • 佛山做网站那家好网站建设公司如何盈利
  • 傻瓜建网站设计感网站
  • 北京网站优化软件陕西省建筑信息平台
  • 广州越秀建网站济南房产网新开楼盘
  • 线上咨询预约网站建设方案保定外贸网站制作
  • 网站流量如何增加提高工作效率的措施
  • 龙湖镇华南城网站建设.net 网站开发书籍
  • 域名费用和网站服务器费用是同样的吗推广营销方案
  • 安徽网站设计方案中文外贸网站有哪些
  • 衡阳手机网站设计响应式网站做多大的尺寸
  • 海尔电子商务网站建设预算灵台县门户网
  • 四川网站建设设计公司排名开发公司与建筑公司合作协议
  • 江西智能网站建设嘉定注册公司
  • 海口网站建设联系方式十大免费软文推广平台
  • 石碣镇做网站帮别人做网站开价
  • 站长 网站ip客户都不愿意做网站
  • 网站开发和软件开发哪个难网站备案账号
  • 2昌平区网站建设安徽盛绿建设网站