ASP.NET Core Diagnostics Endpoints Setup

  • 2 minutes to read

이 문서에서는 운영 환경에서 진단을 위한 Minimal API 엔드포인트를 Program.cs와 확장 메서드로 구성하는 방법을 설명합니다. 진단 API는 Egress IP 확인Health 체크 기능을 제공합니다.


DiagnosticsEndpoints 확장 메서드

Azunt.Endpoints.DiagnosticsEndpoints 클래스는 MapDiagnosticsEndpoints 확장 메서드를 제공합니다. 이 메서드는 /api/diagnostics 그룹과 /health/egress-ip 엔드포인트를 설정합니다.

코드: Azunt\Azunt.Web\Endpoints\DiagnosticsEndpoints.cs

using Microsoft.AspNetCore.Builder;   // MapGet 확장 메서드
using Microsoft.AspNetCore.Http;      // Results.*
using Microsoft.AspNetCore.Routing;   // IEndpointRouteBuilder
using System.Net.Http;
using System.Net.Http.Headers;

namespace Azunt.Endpoints;

public static class DiagnosticsEndpoints
{
    /// <summary>
    /// 운영 진단용 미니멀 API 묶음 등록 (인증 필요)
    /// </summary>
    public static IEndpointRouteBuilder MapDiagnosticsEndpoints(this IEndpointRouteBuilder app)
    {
        ArgumentNullException.ThrowIfNull(app);
        var endpoints = app;

        // 이 그룹에 포함된 모든 엔드포인트는 인증 필요
        var diag = endpoints.MapGroup("/api/diagnostics")
                            .WithTags("Diagnostics")
                            .RequireAuthorization();

        // 그룹에 포함된 엔드포인트 (자동으로 인증 필요)
        diag.MapGet("/egress-ip", async (IHttpClientFactory httpClientFactory, CancellationToken ct) =>
        {
            var client = httpClientFactory.CreateClient("egress-ip");

            static async Task<string?> TryGetAsync(HttpClient http, string url, CancellationToken ct)
            {
                try
                {
                    using var resp = await http.GetAsync(url, ct);
                    if (!resp.IsSuccessStatusCode) return null;

                    var text = (await resp.Content.ReadAsStringAsync(ct)).Trim();
                    return string.IsNullOrWhiteSpace(text) ? null : text;
                }
                catch
                {
                    return null;
                }
            }

            // 여러 공급자 중 되는 것 하나 사용 (순차 폴백)
            var ip =
                await TryGetAsync(client, "https://api.ipify.org", ct) ??
                await TryGetAsync(client, "https://ifconfig.me/ip", ct) ??
                await TryGetAsync(client, "https://checkip.amazonaws.com", ct);

            return ip is not null
                ? Results.Json(new { ip })
                : Results.Problem("Unable to determine outbound IP address right now. Try again shortly.");
        })
        .WithName("GetEgressIp")
        .Produces(StatusCodes.Status200OK)
        .ProducesProblem(StatusCodes.Status503ServiceUnavailable);

        // health 엔드포인트 (그룹 밖, 개별 RequireAuthorization 적용)
        endpoints.MapGet("/health/egress-ip", async (IHttpClientFactory httpClientFactory, CancellationToken ct) =>
        {
            var client = httpClientFactory.CreateClient("egress-ip");
            try
            {
                var ip = (await client.GetStringAsync("https://api.ipify.org", ct)).Trim();
                return Results.Text(ip, "text/plain");
            }
            catch
            {
                return Results.StatusCode(StatusCodes.Status503ServiceUnavailable);
            }
        })
        .WithName("HealthEgressIp")
        .WithTags("Diagnostics")
        .RequireAuthorization(); // 개별 인증 요구

        return endpoints;
    }
}

특징

  • /api/diagnostics/egress-ip 인증된 사용자만 접근 가능하며, 외부 서비스(api.ipify.org 등)를 통해 서버의 Outbound IP를 반환합니다. 여러 서비스 호출을 순차 폴백 방식으로 시도합니다.
  • /health/egress-ip 단순 Health Check 엔드포인트로, 외부 서비스 호출 실패 시 503 Service Unavailable을 반환합니다.

Program.cs 통합

Program.cs에서는 HttpClientFactory 설정과 함께 Diagnostics 엔드포인트를 등록합니다.

// HttpClientFactory 등록
builder.Services.AddHttpClient("egress-ip", client =>
{
    client.Timeout = TimeSpan.FromSeconds(5);
    client.DefaultRequestHeaders.UserAgent.ParseAdd("Azunt-EgressIp/1.0");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
});

// 엔드포인트 매핑
var app = builder.Build();
app.MapDiagnosticsEndpoints();
app.Run();
VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com