<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Loading

      玩轉ASP.NET Core中的日志組件

      簡介

      日志組件,作為程序員使用頻率最高的組件,給程序員開發調試程序提供了必要的信息。ASP.NET Core中內置了一個通用日志接口ILogger,并實現了多種內置的日志提供器,例如

      • Console
      • Debug
      • EventSource
      • EventLog
      • TraceSource
      • Azure App Service

      除了內置的日志提供器,ASP.NET Core還支持了多種第三方日志工具,例如

      開發人員在ASP.Net Core中可以自由指定日志提供器,并將日志發送到指定的位置。
      本篇博文中,我們將由淺入深的介紹ASP.Net Core中通用日志接口,最后我們將實現一些自定義的日志提供器(Log Provider)。

      使用系統提供的內置日志提供器

      日志級別(Log Level)

      ASP.NET Core中提供了6種日志級別,分別是Trace, Debug, Information, Warning, Error, Critical。以下是他們的具體使用場景

      日志級別 常用場景
      Trace 記錄一些對程序員調試問題有幫助的信息,
      其中可能包含一些敏感信息, 所以應該避免在
      生產環境中啟用Trace日志
      Debug 記錄一些在開發和調試階段有用的短時變
      量(Short-term usefulness), 所以除非為了臨時排除生產環境的
      故障,開發人員應該盡量避免在生產環境中啟用Debug日志
      Information 記錄應用程序的一些流程, 例如,記錄當前api請求的url
      Warning 記錄應用程序中發生的不正?;蛘呶搭A期的事件信息。
      這些信息中可能包含錯誤消息或者錯誤產生的條件, 例如, 文件未找到
      Error 記錄應用程序中某個操作產生的錯誤和異常信息。
      Critical 記錄一些需要立刻修復的問題。例如數據丟失,磁盤空間不足。

      如何創建日志

      為了創建一個日志,我們首先需要通過依賴注入獲取一個實現ILogger<日志類別>的泛型接口對象。

      已以下代碼為例, 在ValuesController的構造函數中,我們注入了一個ILogger的日志記錄器

          [Route("api/[controller]")]
          [ApiController]
          public class ValuesController : ControllerBase
          {
              private readonly ILogger<ValuesController> _logger = null;
      
              public ValuesController(ILogger<ValuesController> logger)
              {
                  _logger = logger;
              }
      
              // GET api/values
              [HttpGet]
              public ActionResult<IEnumerable<string>> Get()
              {
                  _logger.LogInformation("[Test Log]Getting items.");
                  return new string[] { "value1", "value2" };
              }
      
      
          }
      

      然后我們使用ILogger接口提供的LogInformation方法添加了一個Information類型日志"[Test Log]Getting items"。

      注:ILogger為了提供了6個可用的輸出日志方法,分別對應了6個不同的日志級別

      • LogTrace
      • LogDebug
      • LogInformation
      • LogWarning
      • LogError
      • LogCritical!

      下面我們使用Kestral服務器啟動項目

      項目產生的日志如下,我們手動輸出的日志出現在控制臺中。

      日志配置

      可能針對以上的代碼,有些同學可能有疑問,我們沒有在Startup.cs中注入任何日志提供器,但是日志卻正常產生了。這是由于Program.cs中默認使用WebHost.CreateDefaultBuilder方法添加了2個日志提供器。

      默認日志提供器

      當創建一個新的ASP.NET Core WebApi項目,我們通常在Program.cs中看到以下代碼。

          public class Program
          {
              public static void Main(string[] args)
              {
                  CreateWebHostBuilder(args).Build().Run();
              }
      
              public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                  WebHost.CreateDefaultBuilder(args)
                      .UseStartup<Startup>();
          }
      

      下面我們看一下WebHost.CreateDefaultBuilder的源代碼

          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.UseConfiguration(hostingContext.Configuration.GetSection("Logging"));
                      logging.AddConsole();
                      logging.AddDebug();
                  })
                  .UseIISIntegration()
                  .UseDefaultServiceProvider((context, options) =>
                  {
                      options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
                  })
                  .ConfigureServices(services =>
                  {
                      services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>();
                  });
      
              return builder;
          }
      

      你會發現代碼中通過logging.AddConsolelogging.AddDebug默認配置了Console和Debug類型的日志提供器,這也就是為什么我們沒有注入任何日志提供器,日志卻能正常產生了。

      手動添加日志提供器

      看了以上代碼后,你應該可以也清楚了如何自己添加其他內置的日志提供器。我們只需要在Program.cs中使用ConfigureLogging方法就可以配置我們需要的日志提供器了。

      例:

          public class Program
          {
              public static void Main(string[] args)
              {
                  CreateWebHostBuilder(args).Build().Run();
              }
      
              public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                  WebHost.CreateDefaultBuilder(args)
                  .ConfigureLogging((hostingContext, logging) =>
                  {
                      logging.AddConsole();
                      logging.AddDebug();
                      logging.AddEventSourceLogger();
                  })
                  .UseStartup<Startup>();
          }
      

      除了在Program.cs添加日志提供器之外,我們還可以在Startup.cs中添加日志提供器。
      在Startup.cs中,我們可以為Configure方法添加第三個參數ILoggerFactory loggerFactory, 并使用該參數添加日志提供器。

      例:

          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
      
              loggerFactory.AddConsole();
              loggerFactory.AddDebug();
              
              app.UseMvc();
          }
      

      配置文件及日志級別過濾

      ASP.NET Core默認會從appSetting.json中的Logging屬性讀取日志的配置(當然你也可以從其他文件中讀取配置),這里設置了不同的日志提供器產生的最低的日志級別,配置樣例如下。

      {
        "Logging": {
          "Debug": {
            "LogLevel": {
              "Default": "Information"
            }
          },
          "Console": {
            "LogLevel": {
              "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
              "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
              "Microsoft.AspNetCore.Mvc.Razor": "Error",
              "Default": "Trace"
            }
          },
          "LogLevel": {
            "Default": "Debug"
          }
        }
      }
      

      以上代碼中的Debug表示Debug日志提供器, Console表示Console日志提供器, 最后一個LogLevel表示其他日志提供器通用。
      Debug中的Default設置為Information, 即Debug中產生的日志最低級別是Information, 低于Information級別的日志不會輸出。Console中的配置同理。

      自定義日志組件

      在學習了以上基礎知識之后,我們應該對內置的日志提供器有了簡單的認識。下面我們嘗試自定義2個日志提供器。
      在ASP.NET Core中,我們可以通過實現ILogger, ILoggerProvider2個接口來創建我們自己的日志提供器。

      編寫一個自定義樣式的控制臺日志組件

      這里我們希望添加一個在控制臺中輸出的日志,但是和內置Console類型日志的區別是我們為不同的日志類型設置了不同的顏色。

      首先我們創建一個新的Api項目ColoredConsoleLoggerSample

      然后我們創建一個針對不同日志級別的字體顏色配置類ColoredConsoleLoggerConfiguration, 代碼如下

          public class ColoredConsoleLoggerConfiguration
          {
              public LogLevel LogLevel { get; set; } = LogLevel.Warning;
              public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
          }
      

      這個類中定義了針對不同日志類型設置不同的字體顏色。

      然后我們創建一個日志類ColoredConsoleLogger, 它實現了ILogger接口,代碼如下

          public class ColoredConsoleLogger : ILogger
          {
              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;
                  }
                  
                  var color = Console.ForegroundColor;
                  Console.ForegroundColor = _config.Color;
                  Console.WriteLine($"{logLevel.ToString()} - {_name} - {formatter(state, exception)}");
                  Console.ForegroundColor = color;
              }
          }
      

      代碼解釋

      • ColoredConsoleLogger僅針對一種日志級別
      • 只要當前產生的日志級別和ColoredConsoleLogger中定義的日志級別一樣時,日志才會輸出,這里我們是用IsEnable方法判斷的
      • Log是ILogger接口中定義的方法,我們就是在這個方法中輸出日志的
      • 這里我們在輸入日志前記錄下了當前控制臺的原始字體顏色, 當輸出日志完成之后,我們將字體顏色恢復成了原來的顏色

      然后我們添加一個Logger提供器類ColoredConsoleLoggerProvider,代碼如下

          public class ColoredConsoleLoggerProvider : ILoggerProvider
          {
              private readonly ColoredConsoleLoggerConfiguration _config;
      
              public ColoredConsoleLoggerProvider(ColoredConsoleLoggerConfiguration config)
              {
                  _config = config;
              }
      
              public ILogger CreateLogger(string categoryName)
              {
                  return new ColoredConsoleLogger(categoryName, _config);
              }
      
              public void Dispose()
              {
      
              }
          }
      

      代碼解釋

      • ColoredConsoleLoggerProvider僅針對一種日志級別
      • CreateLoggerILoggerProvider接口中定義的方法,它是用來返回一個日志生成器的

      最后我們修改Startup.cs中的Configure方法, 代碼如下

          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
              
              loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration
              {
                  LogLevel = LogLevel.Information,
                  Color = ConsoleColor.Blue
              }));
              loggerFactory.AddProvider(new ColoredConsoleLoggerProvider(new ColoredConsoleLoggerConfiguration
              {
                  LogLevel = LogLevel.Debug,
                  Color = ConsoleColor.Gray
              }));
      
              app.UseMvc();
          }
      

      這里我們添加了2個日志日志提供器,分別是針對Information級別日志和Debug級別日志的

      最終效果

      我們的日志根據我們預設的字體顏色正確的顯示了出來

      編寫一個與SignalR集成的實時日志組件

      下面我們再來自定義一個與SignalR集成的日志提供器,我們希望產生的日志通過一個SignalR服務器推送到一個網頁中。

      首先我們創建一個ASP.NET Core WebApi項目,命名為SignalrServer, 創建之后,我們右鍵項目屬性,修改App Url為http://localhost:5000

      然后我們創建一個LogHub類,它集成自Hub類,代碼如下

          public class LogHub : Hub
          {
              public async Task WriteLog(Log log)
              {
                  await Clients.All.SendAsync("showLog", log);
              }
          }
      
          public class Log
          {
              public LogLevel Level { get; set; }
      
              public string Content { get; set; }
          }
      

      代碼解釋

      • 這里我們創建了一個寫日志的方法,它會把日志推送到所有連接到SignalR服務器的客戶端,并調用客戶端的showLog方法來展示推送的日志信息。

      然后我們修改Startup.cs文件,代碼如下

          public class Startup
          {
              public Startup(IConfiguration configuration)
              {
                  Configuration = configuration;
              }
      
              public IConfiguration Configuration { get; }
      
              // This method gets called by the runtime. Use this method to add services to the container.
              public void ConfigureServices(IServiceCollection services)
              {
                  services.AddCors();
                  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                  
                  services.AddSignalR();
              }
      
              // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
              public void Configure(IApplicationBuilder app, IHostingEnvironment env)
              {
                  if (env.IsDevelopment())
                  {
                      app.UseDeveloperExceptionPage();
                  }
                  app.UseCors(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
                  app.UseSignalR(routes =>
                  {
                      routes.MapHub<LogHub>("/logHub");
                  });
      
                  
      
                  app.UseMvc();
              }
          }
      

      代碼解釋

      • 我們通過service.AddSignalR注冊了SignalR服務
      • 我們通過app.UserSignalR方法注冊一個logHub
      • 這里我們啟用了CORS, 因為需要提供跨域訪問

      然后我們創建一個另外一個ASP.NET Core WebApi項目, SignalRLoggerSample

      項目創建成功之后,我們右鍵點擊項目屬性,并設置App URL為http://localhost:5001

      然后我們使用Package Console Manager, 安裝Microsoft.AspNetCore.SignalR.Client

      PM> install-package Microsoft.AspNetCore.SignalR.Client

      為了創建一個SignalR日志提供器, 我們分別創建一個SignalRLogger類和一個SignalRLoggerProvider類, 代碼如下

      SignalRLogger.cs

          public class SignalRLogger : ILogger
          {
              HubConnection connection;
      
              public SignalRLogger()
              {
                  connection = new HubConnectionBuilder()
                   .WithUrl("http://localhost:5000/LogHub")
                   .Build();
              }
      
              public IDisposable BeginScope<TState>(TState state)
              {
                  return null;
              }
      
              public bool IsEnabled(LogLevel logLevel)
              {
                  return true;
              }
      
              public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
              {
                  if (!IsEnabled(logLevel))
                  {
                      return;
                  }
      
                  connection.StartAsync().Wait();
                  var task = connection.SendAsync("writeLog", new { Level = logLevel, Content = formatter(state, exception) });
                  task.Wait();
              }
          }
      

      SignalRLoggerProvider.cs

          public class SignalRLoggerProvider : ILoggerProvider
          {
              public SignalRLoggerProvider()
              {
              }
      
              public ILogger CreateLogger(string categoryName)
              {
                  return new SignalRLogger();
              }
      
              public void Dispose()
              {
      
              }
          }
      

      代碼解釋

      • 這里使用HubConnectionBuilder創建了一個SignalR連接
      • 連接啟動成功之后,我們使用connection.SendAsync方法,將當前產生的日志信息發送到SignalR服務器

      添加完成之后,我們在wwwroot文件夾中創建一個index.html, 在其中引入jquery和signalr的js庫,并指定連接的signalR服務器是http://localhost:5000/logHub

      index.html

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8" />
          <title></title>
          <script src="jquery-1.10.2.min.js"></script>
          <script src="signalr.min.js"></script>
      </head>
      <body>
          <h1>Logs</h1>
          <div id="content" style="border:1px solid #0094ff">
      
          </div>
          <script type="text/javascript">
              var levels = [
                  { level: 0, name: 'Trace', backgroundColor: 'gray' },
                  { level: 1, name: 'Debug', backgroundColor: 'green' },
                  { level: 2, name: 'Information', backgroundColor: 'blue' },
                  { level: 3, name: 'Warning', backgroundColor: 'yellow' },
                  { level: 4, name: 'Error', backgroundColor: 'orange' },
                  { level: 5, name: 'Critical', backgroundColor: 'red' },
              ];
      
              function getLevelName(level) {
                  return levels.find(function (o) {
                      return o.level == level;
                  }).name;
              }
      
              function getLevelColor(level) {
                  return levels.find(function (o) {
                      return o.level == level;
                  }).backgroundColor;
              }
      
              var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:5000/logHub").build();
      
              connection.on("showLog", function (message) {
                  var div = "<div style='background-color:" + getLevelColor(message.level)+"'>[" + getLevelName(message.level) + "]:" + message.content + "</div>";
                  $("#content").append(div);
              });
      
              connection.start().catch(function (err) {
                  return console.error(err.toString());
              });
          </script>
      </body>
      </html>
      

      然后我們修改ValuesController文件,代碼如下

          [Route("api/[controller]")]
          [ApiController]
          public class ValuesController : ControllerBase
          {
              private ILogger<ValuesController> _logger = null;
      
              public ValuesController(ILogger<ValuesController> logger)
              {
                  _logger = logger;
              }
      
              // GET api/values
              [HttpGet]
              public ActionResult<IEnumerable<string>> Get()
              {
                  _logger.LogTrace("User call the /api/values api");
                  _logger.LogDebug("User call the /api/values api");
                  _logger.LogInformation("User call the /api/values api");
                  _logger.LogWarning("User call the /api/values api");
                  _logger.LogError("User call the /api/values api");
                  _logger.LogCritical("User call the /api/values api");
                  return new string[] { "value1", "value2" };
              }
          }
      

      代碼解釋

      • 我們創建了一個ValueController類的日志
      • 當用戶請求/api/values時,我們輸出了6個不同級別的日志

      最后我們修改Startup.cs中的Configure方法,使用我們之前介紹的方法,將SignalRLoggerProvider添加到管道中

          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
              app.UseStaticFiles();
      
              loggerFactory.AddProvider(new SignalRLoggerProvider());
      
              app.UseMvc();
      
      
          }
      

      最終效果

      最后我們按照順序,先啟動SignalRServer, 再啟動SignalRLoggerSample, 效果如下

      本篇源代碼

      參考文獻

      posted @ 2018-09-21 21:42  LamondLu  閱讀(19548)  評論(18)    收藏  舉報
      主站蜘蛛池模板: 国产无遮挡又黄又大又爽| 精品中文人妻中文字幕| 久久国内精品一区二区三区| 麻豆精品一区二区综合av| 亚洲人成电影网站色mp4| 国产成人亚洲综合图区| 亚洲国产精品va在线观看麻豆| 亚洲成人网在线观看| 久久亚洲精品中文字幕馆| 日本三级香港三级三级人!妇久| 一区二区三区四区自拍偷拍| 濮阳县| 亚洲国产精品毛片在线看| 国产99青青成人A在线| 亚洲欧美日韩久久一区二区| 日韩无矿砖一线二线卡乱| 日韩人妻系列无码专区| av在线播放观看国产| 天堂а√在线最新版中文在线| 国产精品中文字幕观看| 乌苏市| 色综合久久久久综合体桃花网| 日本高清中文字幕免费一区二区| 车致| 男女啪啪高潮激烈免费版| 男女男免费视频网站国产| 无码AV无码免费一区二区| av午夜福利亚洲精品福利| WWW丫丫国产成人精品| 久久精品亚洲精品国产区| 成全我在线观看免费第二季| 最近2019免费中文字幕8| 亚洲国产精品一区二区第一页| 亚洲国产码专区在线观看| 亚洲伊人精品久视频国产| 国产精品天堂蜜av在线播放| 亚洲av激情一区二区| 国产亚洲日韩av在线播放不卡| 天堂网在线.www天堂在线资源| 91中文字幕一区在线| 性xxxx视频播放免费|