성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - (.NET Core 2.2부터 가능한) 프로세스 내부에서 CLR ETW 이벤트 수신</h1> <p> 예전에도 ETW를 다뤄봤는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - ETW 관련 Win32 API 사용 예제 코드 (4) CLR ETW Consumer ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12300'>https://www.sysnet.pe.kr/2/0/12300</a> ETW(Event Tracing for Windows)를 이용한 닷넷 프로그램의 내부 이벤트 활용 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12244'>https://www.sysnet.pe.kr/2/0/12244</a> </pre> <br /> 저렇게 구현하는 것에 아쉬움이 있었다면 프로세스 외부에서 관리자 권한으로만 이벤트 수신이 가능하다는 점이었습니다. 게다가 in-proc 모니터링을 지원하는 Private Logger는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - ETW 관련 Win32 API 사용 예제 코드 (5) - Private Logger ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12302'>https://www.sysnet.pe.kr/2/0/12302</a> </pre> <br /> 로그 파일로만 출력할 수 있다는 제약이 있었고! 그런데, .NET Core 2.2부터 in-proc 모니터링이 가능하도록 만들었다는 것을 ^^; 이제서야 알게 되었습니다. (.NET Framework에선 4.8까지도 지원하지 않습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > In-process CLR event listeners with .NET Core 2.2 ; <a target='tab' href='https://medium.com/criteo-labs/c-in-process-clr-event-listeners-with-net-core-2-2-ef4075c14e87'>https://medium.com/criteo-labs/c-in-process-clr-event-listeners-with-net-core-2-2-ef4075c14e87</a> (그나저나, 전에도 criteo.com 자료였는데 이번에도 좋은 글을 썼군요. ^^) </pre> <br /> 게다가 소스 코드도 매우 간단합니다. 단순히 다음과 같이 EventListener를 상속받은 타입을 정의하는 것으로,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Diagnostics.Tracing; namespace ConsoleApp2 { class Program { static MyEventListener _listener; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12473'>static Program()</a> { <span style='color: blue; font-weight: bold'>_listener = new MyEventListener();</span> } static void Main(string[] args) { Console.WriteLine("In-proc ETW Enabled on .NET Core 2.2 or later"); } } } <span style='color: blue; font-weight: bold'>internal class MyEventListener : EventListener</span> { protected override void OnEventSourceCreated(EventSource eventSource) { base.OnEventSourceCreated(eventSource); } protected override void OnEventWritten(EventWrittenEventArgs eventData) { } } </pre> <br /> 뼈대가 완성됩니다. 이제 원하는 이벤트를 수신하도록 만들면 되는데요, 가령 <a target='tab' href='https://www.sysnet.pe.kr/2/0/12244'>"예외(Exception)" 이벤트를 수신</a>하고 싶다면 다음과 같이 코드를 작성합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > internal class MyEventListener : <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.tracing.eventlistener'>EventListener</a> { // CLR ETW Keywords and Levels // <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/framework/performance/clr-etw-keywords-and-levels'>https://learn.microsoft.com/en-us/dotnet/framework/performance/clr-etw-keywords-and-levels</a> private const int EXCEPTIONKEYWORD = 0x00008000; protected override void OnEventSourceCreated(EventSource eventSource) { base.OnEventSourceCreated(eventSource); <span style='color: blue; font-weight: bold'>if (eventSource.Name == "Microsoft-Windows-DotNETRuntime") { EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)EXCEPTIONKEYWORD); }</span> } protected override void OnEventWritten(EventWrittenEventArgs eventData) { <span style='color: blue; font-weight: bold'>if ((int)eventData.Keywords == EXCEPTIONKEYWORD) { Console.WriteLine($"{DateTime.Now}: {eventData.EventName}"); }</span> } } </pre> <br /> 그럼 정말 잘 동작하는지 테스트를 해봐야겠죠? ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void Main(string[] args) { while (true) { Console.ReadLine(); try { <span style='color: blue; font-weight: bold'>throw new ApplicationException("Exception-thrown");</span> } catch (Exception e) { Console.WriteLine($"{DateTime.Now}: User-exception"); } } } </pre> <br /> 실행 후, 예외를 발생시키면 이제 화면에는 다음과 같은 출력 결과를 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 2021-01-04 오후 5:23:57: User-exception 2021-01-04 오후 5:23:57: ExceptionThrown_V1 2021-01-04 오후 5:23:57: ExceptionCatchStart 2021-01-04 오후 5:23:57: ExceptionCatchStop 2021-01-04 오후 5:23:57: ExceptionThrownStop </pre> <br /> 시간을 보면 알 수 있듯이, <a target='tab' href='https://www.sysnet.pe.kr/2/0/12244#ex_event'>외부 프로세스에서 ETW 이벤트를 감시할 때는 시간차가 발생했던 것</a>과는 달리 이제 실시간으로 이벤트를 수신하는 것을 확인할 수 있습니다.<br /> <br /> .NET Core 2.2 이상에서만 지원한다는 사실만 제외하면, 모든 면에서 완벽한 CLR ETW 이벤트 수신 기능을 지원하고 있습니다. ^^<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1695&boardid=331301885'>첨부 파일은 이 글의 예제 프로젝트를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1781
(왼쪽의 숫자를 입력해야 합니다.)