中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Asp.Net Core如何利用日志監視進行服務遙測

發布時間:2021-06-17 14:59:48 來源:億速云 閱讀:147 作者:小新 欄目:開發技術

小編給大家分享一下Asp.Net Core如何利用日志監視進行服務遙測,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

前言

在 Net Core 2.2 中,官方文檔表示,對 EventListener 這個日志監視類的內容進行了擴充,同時賦予了跟蹤 CoreCLR 事件的權限;通過跟蹤 CoreCLR 事件,比如通過跟蹤 CoreCLR 事件,可以了解和收集到比如 GC,JIT,ThreadPool,intreop 這些運行時服務的行為;通過使用配置注入,我們將獲得一種動態跟蹤事件的能力。

1. EventListener 介紹

1.1 EventListener 中文直譯為:事件偵聽器

EventListener 位于程序集 System.Diagnostics.Tracing 中,該類提供了一組啟用/禁用的方法,按照慣例,先來看一下源代碼,了解一下其結構

 public abstract class EventListener : IDisposable
 {
 protected EventListener();

 public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated;
 
 public event EventHandler<EventWrittenEventArgs> EventWritten;

 protected static int EventSourceIndex(EventSource eventSource);
 
 public void DisableEvents(EventSource eventSource);
 
 public virtual void Dispose();
 
 public void EnableEvents(EventSource eventSource, EventLevel level);
 
 public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword);
 
 protected internal virtual void OnEventWritten(EventWrittenEventArgs eventData);
 }

從類結構中可以看出,EventListener 中的方法并不多,而且從名字都可以推斷出其行為,
因為該類是一個抽象類,并不能直接使用,接下來我們創建一個 ReportListener 類繼承它

2. 創建自定義事件偵聽器

 public class ReportListener : EventListener
 {
  public ReportListener() { }

  public Dictionary<string, ListenerItem> Items { get; set; } = new Dictionary<string, ListenerItem>();
  public ReportListener(Dictionary<string, ListenerItem> items)
  {
   this.Items = items;
  }

  protected override void OnEventSourceCreated(EventSource eventSource)
  {
   if (Items.ContainsKey(eventSource.Name))
   {
    var item = Items[eventSource.Name];
    EnableEvents(eventSource, item.Level, item.Keywords);
   }
  }

  protected override void OnEventWritten(EventWrittenEventArgs eventData)
  {
   if (Items.ContainsKey(eventData.EventSource.Name))
   {
    Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventSource.Name}.{eventData.EventName}");
    for (int i = 0; i < eventData.Payload.Count; i++)
    {
     string payloadString = eventData.Payload[i]?.ToString() ?? string.Empty;
     Console.WriteLine($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
    }
    Console.WriteLine("\n");
   }
  }
 }

ReportListener 自定義事件偵聽器的代碼非常簡單,只是簡單的繼承了 EventListener 后,重寫了父類的兩個方法:創建事件和寫入事件

同時,還定義了一個公共屬性 Dictionary<string, ListenerItem> Items ,該屬性接受一個 ListenerItem 的跟蹤配置集,通過配置文件注入,動態覺得哪些事件可以被寫入到偵聽器中

3. 配置跟蹤項目

在配置文件 appsettings.json 中增加以下內容

{
 "listener": [
 {
  "name": "HomeEventSource",
  "level": 5,
  "keywords": -1
 }
 ]
}

配置說明

上面的配置文件表示,定義一個事件源對象(EventSource),名稱為 HomeEventSource,事件級別(EventLevel)為 5,關鍵字(EventKeywords)為 -1

關于事件級別和事件關鍵字的值,和系統定義的一致

3.1 事件級別定義

namespace System.Diagnostics.Tracing
{
 public enum EventLevel
 {
  LogAlways = 0,
  Critical = 1,
  Error = 2,
  Warning = 3,
  Informational = 4,
  Verbose = 5
 }
}

3.2 事件關鍵字定義

namespace System.Diagnostics.Tracing
{
 [Flags]
 public enum EventKeywords : long
 {
  All = -1,
  None = 0,
  WdiContext = 562949953421312,
  MicrosoftTelemetry = 562949953421312,
  WdiDiagnostic = 1125899906842624,
  Sqm = 2251799813685248,
  AuditFailure = 4503599627370496,
  CorrelationHint = 4503599627370496,
  AuditSuccess = 9007199254740992,
  EventLogClassic = 36028797018963968
 }
}

3.3 配置文件完全按照系統值定義,為了更好的使用配置文件,我們定義了下面的實體類

 public class ListenerItem
 {
  public string Name { get; set; }
  public EventLevel Level { get; set; } = EventLevel.Verbose;
  public EventKeywords Keywords { get; set; } = EventKeywords.All;
 }

4. 開始使用事件偵聽器

為了在應用程序中使用事件偵聽器,我們需要初始化事件偵聽器,你可以初始化多個事件偵聽器;但是,每個事件偵聽器僅需要初始化一次即可

4.1 初始化自定義事件偵聽器,在 Startup.cs 文件中加入以下代碼

  public void AddEventListener(IServiceCollection services)
  {
   var listeners = this.Configuration.GetSection("listener").Get<List<ListenerItem>>();
   Dictionary<string, ListenerItem> dict = new Dictionary<string, ListenerItem>();
   if (listeners != null)
   {
    foreach (var item in listeners)
    {
     dict.Add(item.Name, item);
    }
   }
   var report = new ReportListener(dict);
   services.AddSingleton<ReportListener>(report);
  }

  public void ConfigureServices(IServiceCollection services)
  {
   AddEventListener(services);
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  }

初始化動作非常簡單,僅是從配置文件中讀取需要跟蹤的項,然后注冊到 ReportListener 內部即可,為了演示事件的注冊,我們需要創建一個事件源,就像配置文件中的名稱 HomeEventSource

4.2 創建自定義的事件源對象

 public class HomeEventSource : EventSource
 {
  public static HomeEventSource Instance = new HomeEventSource();

  [Event(1001)]
  public void RequestStart(string message) => WriteEvent(1001, message);

  [Event(1002)]
  public void RequestStop(string message) => WriteEvent(1002, message);
 }

自定義事件源 HomeEventSource 繼承自 EventSource,我們可無需為該自定義事件源進行顯式命名,因為默認將會使用 HomeEventSource 類名進行注冊事件

現在,我們嘗試著 HomeController 去生產一個事件,看看效果

5. 生產事件

5.1 轉到 HomeController,在 HomeController 的 Get 方法中使用 HomeEventSource 生產兩個事件

 [Route("api/[controller]")]
 [ApiController]
 public class HomeController : ControllerBase
 {
  [HttpGet]
  public ActionResult<IEnumerable<string>> Get()
  {
   HomeEventSource.Instance.RequestStart("處理業務開始");
   var arra = new string[] { "value1", "value2" };
   HomeEventSource.Instance.RequestStop("處理業務結束");
   return arra;
  }
 }

5.2 回顧一下自定義事件偵聽器 ReportListener 的重寫方法

  protected override void OnEventSourceCreated(EventSource eventSource)
  {
   if (Items.ContainsKey(eventSource.Name))
   {
    var item = Items[eventSource.Name];
    EnableEvents(eventSource, item.Level, item.Keywords);
   }
  }

  protected override void OnEventWritten(EventWrittenEventArgs eventData)
  {
   if (Items.ContainsKey(eventData.EventSource.Name))
   {
    Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventSource.Name}.{eventData.EventName}");
    for (int i = 0; i < eventData.Payload.Count; i++)
    {
     string payloadString = eventData.Payload[i]?.ToString() ?? string.Empty;
     Console.WriteLine($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
    }
    Console.WriteLine("\n");
   }
  }

由于我們做配置文件中指定了必須是 HomeEventSource 事件源才啟用事件,所以上面的代碼表示,當一個 HomeEventSource 事件進入的時候,將事件的內容打印到控制臺,實際應用中,你可以將這些信息推送到日志訂閱服務器,以方便跟蹤和匯總

5.3 運行程序,看看輸出結果如何

Asp.Net Core如何利用日志監視進行服務遙測

可以看到,事件生產成功,實際上,CoreCLR 內部生產了非常多的事件,下面我們嘗試啟用以下 3 個事件源,預期將會收到大量的事件信息

5.4 嘗試更多事件源

  protected override void OnEventSourceCreated(EventSource eventSource)
  {
   if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
   {
    EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
   }

   else if (eventSource.Name.Equals("System.Data.DataCommonEventSource"))
   {
    EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
   }

   else if (eventSource.Name.Equals("Microsoft-AspNetCore-Server-Kestrel"))
   {
    EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
   }
  }

5.5 再次運行程序,看下圖輸出結果

Asp.Net Core如何利用日志監視進行服務遙測

從圖中可以看出,這次我們跟蹤到了 Microsoft-AspNetCore-Server-Kestrel 事件源生產的開始和結束連接事件

結束語

  • 在 CoreCLR 的事件總線中,包含了千千萬萬的事件源生產的事件,以上的實驗只是冰山一角,如果你把創建事件源的 EventKeywords 指定為 All,你將會看到天量的日志信息,但是,在這里,友情提示大家,千萬不要這樣做,這種做法會對服務性能帶來極大損害

  • 在業務代碼中,寫入大量的調試日志是不可取的,但是使用事件偵聽器,可以控制事件的創建和寫入,當需要對某個接口進行監控的時候,通過將需要調試的事件源加入配置文件中進行監控,這將非常有用

以上是“Asp.Net Core如何利用日志監視進行服務遙測”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

土默特右旗| 江华| 永和县| 景泰县| 茂名市| 磐石市| 东阿县| 毕节市| 揭东县| 河间市| 丹寨县| 依兰县| 盐亭县| 克拉玛依市| 礼泉县| 连云港市| 多伦县| 望谟县| 宁夏| 大悟县| 兴文县| 大兴区| 龙泉市| 偃师市| 南陵县| 睢宁县| 延庆县| 石阡县| 泌阳县| 论坛| 昌都县| 洛阳市| 唐海县| 云梦县| 伽师县| 甘谷县| 荆州市| 灵丘县| 北宁市| 重庆市| 丰宁|