본문

와탭모니터링
닷넷 데스크탑 애플리케이션 성능 모니터링 및 디버깅

작성일 2024년 11월 19일

이번 글에서는 와탭 닷넷 모니터링을 활용하여 닷넷 데스크톱 애플리케이션의 성능을 모니터링하고, 디버깅하는 방법에 대해 알아보겠습니다. 현재 와탭 닷넷 모니터링은 닷넷 코어 버전에서만 사용 가능하며, 추후 닷넷 프레임워크 버전으로 확대될 예정입니다.


사용법

먼저, 와탭의 닷넷 모니터링 에이전트를 설치해야 합니다. 설치 방법에 대한 자세한 내용은 공식 문서나 와탭 지원팀을 통해 확인할 수 있습니다. 이번 글에서는 설치 과정 대신, 에이전트가 설치되었다는 가정하에 진행하겠습니다.

성능 모니터링은 기본적으로 WAS 환경에서 동작하기 때문에, 아래와 같이 환경 설정을 통해 데스크톱 애플리케이션도 모니터링 범위에 포함시켜야 합니다. 따라서 데스크톱 애플리케이션을 실행하기 전에 아래 순서대로 실행하시면 됩니다.

모니터링 대상 애플리케이션의 이름이 WinForm-Monitoring.exe라고 가정하겠습니다.

SET COR_PROFILER={D76F1D76-A9E0-4C87-874F-C0AD93D4229B}
SET COR_ENABLE_PROFILING=1

SET CORECLR_PROFILER={21CAE18A-4E44-4578-83FD-0576AAA47E68}
SET CORECLR_ENABLE_PROFILING=1
SET DOTNET_STARTUP_HOOKS=C:\Program Files\WhaTap .NET\core\Whatap.Startup.NetCore.dll

SET WHATAP_TRACE_IIS_ONLY=0
SET EXPAND_TRANSACTION_LEVEL=1
SET EXPAND_TRANSACTION_BASETIME=100

WinForm-Monitoring.exe

다른 항목은 그대로 사용하시면 되고, WinForm-Monitoring.exe 부분만 본인의 애플리케이션 파일 이름으로 교체하여 콘솔에서 실행하시면 됩니다.


사용자 정의 트레이스가 필요한 이유

위 설정만으로도 기본적인 데이터 수집은 가능하지만, 웹 애플리케이션만큼 상세한 정보를 얻기는 어렵습니다. 이러한 경우, System.Diagnostics를 활용해 이벤트를 발생시키고 이를 성능 관리 도구로 전달하면 더 상세한 정보를 모니터링할 수 있습니다.

이벤트를 직접 발생시킬 수도 있지만, 아래의 코드를 프로젝트에 복사해 사용하면 더 편리하게 구현할 수 있습니다.

using System.Diagnostics;

public static class WhatapDiagnostic
{
    private static readonly DiagnosticSource diagnosticSource = new DiagnosticListener("WhatapDiagnosticListener");

    public static void TraceStart(string host, string url, string userId)
    {
        if (diagnosticSource.IsEnabled("Whatap.Diagnostic.Trace.Start"))
        {
            diagnosticSource.Write("Whatap.Diagnostic.Trace.Start", new { Host = host, Url = url, UserId = userId });
        }
    }

    public static void SetExceptionForTrace(Exception exception)
    {
        if (diagnosticSource.IsEnabled("Whatap.Diagnostic.Trace.Exception"))
        {
            diagnosticSource.Write("Whatap.Diagnostic.Trace.Exception", exception);
        }
    }

    public static void StepStart(string message)
    {
        diagnosticSource.Write("Whatap.Diagnostic.Step.Start", message);
    }

    public static void StepStop()
    {
        diagnosticSource.Write("Whatap.Diagnostic.Step.Stop", new { });
    }

    public static void TraceStop()
    {
        if (diagnosticSource.IsEnabled("Whatap.Diagnostic.Trace.Stop"))
        {
            diagnosticSource.Write("Whatap.Diagnostic.Trace.Stop", new { });
        }
    }

    public static void UserLog(string message)
    {
        if (diagnosticSource.IsEnabled("Whatap.Diagnostic.UserLog"))
        {
            diagnosticSource.Write("Whatap.Diagnostic.UserLog", message);
        }
    }
}

모니터링에서 가장 기본적인 단위는 트레이스(트랜잭션)입니다. 하나의 트레이스는 여러 개의 스텝(step)으로 구성될 수 있습니다.

예를 들어, “/api/users”라는 API를 호출한다고 가정해 보겠습니다. 이 호출은 하나의 트레이스로 처리되며, 모니터링 대시보드의 히트맵에 하나의 점으로 표시됩니다.

API를 처리하는 백엔드 코드에서는 필요에 따라 데이터베이스나 Redis 등을 사용할 수 있는데, 이러한 각각의 처리 내용은 하나의 스텝으로 처리됩니다. 만약 API 하나를 처리하는데 SQL 실행을 10번 한다면, 하나의 트랜잭션 안에 10개의 스텝이 모니터링 화면에 표시됩니다.

하지만 데스크톱 애플리케이션에서는 자동으로 트레이스를 구별할 기준이 명확하지 않습니다. 따라서 개발자가 코드의 어느 부분이 트레이스의 시작과 끝인지 명시해주어야 합니다.


사용자 정의 트레이스 사용방법

private async void button1_ClickAsync(object sender, EventArgs e)
{
    WhatapDiagnostic.TraceStart("test.desktop", "button1_Click", "");
    try
    {
        WhatapDiagnostic.UserLog("button2_Click");
        WhatapDiagnostic.StepStart("Step1");
        // delay 0.5sec
        Thread.Sleep(500);
        WhatapDiagnostic.StepStop();
    }
    catch (Exception ex)
    {
        WhatapDiagnostic.SetExceptionForTrace(ex);
    }
    finally
    {
        WhatapDiagnostic.TraceStop();
    }
}

WhatapDiagnostic 클래스를 프로젝트에 복사해 두었다면, 다음과 같은 메서드를 실행하여 사용자 정의 트레이스와 스텝을 발생시킬 수 있습니다.

성능 모니터링은 기본적으로 WAS에서 실행되는 환경을 고려하여, 표시 방식도 마치 WAS에서 실행되는 것처럼 나타나는 점을 유의하시기 바랍니다.
  • WhatapDiagnostic.TraceStart("test.desktop", "button1_Click", "");
    • 트레이스 시작 지점을 표시합니다.
    • 매개변수:
      • host: 데스크톱에서는 큰 의미가 없지만, 애플리케이션 종류를 구별하는 데 사용 가능합니다.
      • url: 현재 수행 중인 액션을 구별하는 데 사용합니다.
      • userId: 동시 사용자 수가 필요할 때는 사용자별로 다른 문자열을 입력하시면 됩니다.
  • WhatapDiagnostic.TraceStop();
    • 트레이스 종료 지점을 표시합니다.
  • WhatapDiagnostic.SetExceptionForTrace(ex);
    • 트레이스 도중 오류가 발생한 경우 사용합니다.
  • WhatapDiagnostic.UserLog("button1_Click 시작");
    • 사용자 로그를 남길 때 사용합니다.
  • WhatapDiagnostic.StepStart("Step1");
    • 스텝의 시작 지점을 표시합니다.
    • 매개변수:
      • message: 어떤 스텝이 실행되었는지와 구체적인 정보를 입력합니다.
  • WhatapDiagnostic.StepStop();
    • 스텝의 종료 지점을 표시합니다.


다음 이미지는 모니터링 결과를 캡처한 것입니다. 스텝의 시작과 종료 사이에 0.5초 지연을 주었기 때문에 경과 시간이 약 0.5초로 표시된 것을 확인할 수 있습니다.

8f4fc69b2688050881c3ce636e5b6934_1732004639_9164.png
 

자동으로 모니터링되는 대상에 대한 예

아래 코드는 사용자 정의 트레이스 안에서 데이터베이스 관련 코드를 사용했을 경우의 예시입니다.

private void button2_Click(object sender, EventArgs e)
{
    WhatapDiagnostic.TraceStart("test.desktop", "button2_Click", "");
    try
    {
        WhatapDiagnostic.UserLog("button2_Click");
        string query = @"SELECT * FROM [dbo].[Customer] WHERE Deleted = 0";
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    ...
                }
            }
        }
    }
    catch (Exception ex)
    {
        WhatapDiagnostic.SetExceptionForTrace(ex);
    }
    finally
    {
        WhatapDiagnostic.TraceStop();
    }
}


다음은 위 코드에 대한 모니터링 결과 이미지입니다. 데이터베이스 서버 접속 정보 및 쿼리 호출 내용이 자동으로 모니터링되는 것을 확인할 수 있습니다.

8f4fc69b2688050881c3ce636e5b6934_1732004621_1427.png 

마무리

이번 글에서는 와탭의 닷넷 모니터링 에이전트를 이용하여 닷넷 데스크톱 애플리케이션의 성능을 모니터링하고 디버깅하는 방법에 대해 알아보았습니다. 사용자 정의 트레이스를 통해 상세한 정보를 수집함으로써 애플리케이션의 성능을 향상시키고 문제점을 빠르게 찾아낼 수 있습니다.

또한, 앞으로 닷넷 프레임워크 버전에서도 지원 범위가 확대될 예정이므로 지속적인 업데이트를 통해 보다 효율적인 모니터링이 가능해질 것입니다. 와탭을 통해 애플리케이션의 안정성과 성능을 더욱 향상시켜 보시기 바랍니다.


류종택[email protected]
Development TeamAPM Agent Developer

지금 바로
와탭을 경험해 보세요.