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("
"); } } }
ReportListener 사용자 정의 이벤트 디텍터 의 코드 는 매우 간단 합 니 다.EventListener 를 간단하게 계승 한 후에 부모 클래스 의 두 가지 방법 을 다시 썼 습 니 다.이 벤트 를 만 들 고 이 벤트 를 기록 하 는 것 입 니 다.
또한 하나의 공공 속성Dictionary<string, ListenerItem> Items을 정 의 했 습 니 다.이 속성 은 Listener Item 의 추적 설정 집합 을 받 아들 이 고 설정 파일 을 통 해 주입 되 며 어떤 사건 이 디텍터 에 기 록 될 수 있 는 지 동적 으로 생각 합 니 다.
3.추적 항목 설정
프로필 apptsettings.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("
"); } }
설정 파일 에서 HomeEventSource 이벤트 원본 이 어야 이 벤트 를 사용 할 수 있 도록 지정 되 어 있 기 때문에 위의 코드 는 HomeEventSource 이벤트 가 들 어 올 때 이벤트 의 내용 을 콘 솔 에 인쇄 하고 실제 응용 프로그램 에서 이 정 보 를 로그 구독 서버 에 전송 하여 추적 과 집합 을 편리 하 게 할 수 있 습 니 다.
5.3 프로그램 실행,출력 결과 보기

이 를 통 해 알 수 있 듯 이 이벤트 가 성공 적 으로 생산 되 었 습 니 다.실제로 CoreCLR 내부 에서 매우 많은 이벤트 가 생산 되 었 습 니 다.다음 세 개의 이벤트 소스 를 사용 해 보 겠 습 니 다.대량의 이벤트 정 보 를 받 을 것 으로 예상 합 니 다.
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 프로그램 을 다시 실행 하고 다음 그림 출력 결 과 를 보십시오.

그림 에서 알 수 있 듯 이 이번에 우 리 는 Microsoft-AspNetCore-server-Kestrel 이벤트 소스 생산의 시작 과 끝 연결 사건 을 추적 했다.
종결 어
  • CoreCLR 의 이벤트 버스 에 수천 만 개의 이벤트 소스 가 생산 된 사건 이 포함 되 어 있 습 니 다.이상 의 실험 은 빙산 의 일각 에 불과 합 니 다.이벤트 소스 를 만 든 EventKeywords 를 All 로 지정 하면 엄 청 난 로그 정 보 를 볼 수 있 습 니 다.하지만 여기 서 우정 은 여러분 에 게 절대 그 러 지 말 라 고 알려 줍 니 다.이런 방법 은 서비스 성능 에 큰 손 해 를 가 져 올 것 이다
  • 업무 코드 에 대량의 디 버 깅 로 그 를 기록 하 는 것 은 바람 직 하지 않 지만 사건 수사 기 를 사용 하면 사건 의 생 성과 기록 을 제어 할 수 있 습 니 다.특정한 인 터 페 이 스 를 모니터링 해 야 할 때 디 버 깅 이 필요 한 사건 소스 를 설정 파일 에 추가 하여 모니터링 하 는 것 이 매우 유용 합 니 다
  • 예제 코드 다운로드:http://xiazai.jb51.net/201812/yuanma/Ron.ListenerDemo_jb51.rar
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기