다음을 통해 공유


ASP.NET Core 메트릭

메트릭은 시간에 따라 보고된 숫자 측정값입니다. 일반적으로 앱의 상태를 모니터링하고 경고를 생성하는 데 사용됩니다. 예를 들어, 웹 서비스는 다음 수를 추적할 수 있습니다.

  • 초당 수신된 요청입니다.
  • 응답하는 데 밀리초가 걸렸습니다.
  • 응답에서 오류를 보냈습니다.

이러한 메트릭은 정기적으로 모니터링 시스템에 보고할 수 있습니다. 대시보드를 설정하여 사용자에게 문제를 알리기 위해 만든 메트릭 및 경고를 볼 수 있습니다. 웹 서비스가 400ms 이내의 요청에 응답하고 600ms에서 응답을 시작하는 경우 모니터링 시스템은 운영 직원에게 앱 응답이 정상보다 느리다는 것을 알릴 수 있습니다.

특성과 함께 모든 계측의 포괄적인 목록은 ASP.NET Core 메트릭을 참조하세요.

메트릭 사용

.NET 앱에서 메트릭을 사용하는 데는 다음과 같은 두 부분이 있습니다.

  • 계측: .NET 라이브러리의 코드는 측정을 수행하여 이러한 측정값을 메트릭 이름과 연결합니다. .NET 및 ASP.NET Core에는 많은 기본 제공 메트릭이 포함됩니다.
  • 컬렉션: .NET 앱은 외부 스토리지 및 분석을 위해 앱에서 전송될 명명된 메트릭을 구성합니다. 일부 도구는 구성 파일이나 UI 도구를 사용하여 앱 외부에서 구성을 수행할 수 있습니다.

계측된 코드는 숫자 측정값을 기록할 수 있지만 모니터링에 유용한 메트릭을 만들려면 측정값을 집계, 전송 및 저장해야 합니다. 데이터를 모아서 전송하고 저장하는 과정을 컬렉션이라고 합니다. 이 자습서에서는 메트릭 수집에 대한 몇 가지 예를 보여 줍니다.

측정값은 분석을 위해 데이터를 분류할 수 있는 태그라는 키-값 쌍과도 연결될 수 있습니다. 자세한 내용은 다차원 메트릭을 참조 하세요.

시작 앱 만들기

다음 명령을 사용하여 새 ASP.NET Core 앱을 만듭니다.

dotnet new web -o WebMetric
cd WebMetric
dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore --prerelease
dotnet add package OpenTelemetry.Extensions.Hosting

Program.cs의 내용을 다음 코드로 바꿉니다.

using OpenTelemetry.Metrics;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
    .WithMetrics(builder =>
    {
        builder.AddPrometheusExporter();

        builder.AddMeter("Microsoft.AspNetCore.Hosting",
                         "Microsoft.AspNetCore.Server.Kestrel");
        builder.AddView("http.server.request.duration",
            new ExplicitBucketHistogramConfiguration
            {
                Boundaries = new double[] { 0, 0.005, 0.01, 0.025, 0.05,
                       0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 }
            });
    });
var app = builder.Build();

app.MapPrometheusScrapingEndpoint();

app.MapGet("/", () => "Hello OpenTelemetry! ticks:"
                     + DateTime.Now.Ticks.ToString()[^3..]);

app.Run();

dotnet-counters를 사용하여 메트릭 보기

dotnet-counters는 필요에 따라 .NET Core 앱에 대한 라이브 메트릭을 볼 수 있는 명령줄 도구입니다. 설정이 필요하지 않으므로 임시 조사나 메트릭 계측이 작동하는지 확인하는 데 유용합니다. System.Diagnostics.Metrics 기반 API 및 EventCounters 모두에서 작동합니다.

dotnet-counters 도구가 설치되지 않은 경우 다음 명령을 실행합니다.

dotnet tool update -g dotnet-counters

테스트 앱이 실행되는 동안 dotnet-counters를 시작 합니다. 다음 명령은 미터dotnet-counters 모든 메트릭을 모니터링하는 예제를 Microsoft.AspNetCore.Hosting 보여 줍니다.

dotnet-counters monitor -n WebMetric --counters Microsoft.AspNetCore.Hosting

다음과 비슷한 출력이 표시됩니다.

Press p to pause, r to resume, q to quit.
    Status: Running

[Microsoft.AspNetCore.Hosting]
    http-server-current-requests
        host=localhost,method=GET,port=5045,scheme=http                    0
    http-server-request-duration (s)
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0.001
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0.001
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0.001
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0
        host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro           0

자세한 내용은 dotnet 카운터를 참조하세요.

ASP.NET Core 요청 메트릭 보강

ASP.NET Core에는 많은 기본 제공 메트릭이 있습니다. 메트릭:http.server.request.duration

  • 서버에서 HTTP 요청의 기간을 기록합니다.
  • 일치하는 경로 및 응답 상태 코드와 같은 태그에서 요청 정보를 캡처합니다.

메트릭은 http.server.request.duration .를 사용하여 IHttpMetricsTagsFeature태그 보강을 지원합니다. 보강은 라이브러리 또는 앱이 자체 태그를 메트릭에 추가하는 경우입니다. 이는 앱이 메트릭을 사용하여 빌드된 대시보드 또는 경고에 사용자 지정 분류를 추가하려는 경우에 유용합니다.

using Microsoft.AspNetCore.Http.Features;

var builder = WebApplication.CreateBuilder();
var app = builder.Build();

app.Use(async (context, next) =>
{
    var tagsFeature = context.Features.Get<IHttpMetricsTagsFeature>();
    if (tagsFeature != null)
    {
        var source = context.Request.Query["utm_medium"].ToString() switch
        {
            "" => "none",
            "social" => "social",
            "email" => "email",
            "organic" => "organic",
            _ => "other"
        };
        tagsFeature.Tags.Add(new KeyValuePair<string, object?>("mkt_medium", source));
    }

    await next.Invoke();
});

app.MapGet("/", () => "Hello World!");

app.Run();

진행 예제:

  • 미들웨어를 추가하여 ASP.NET Core 요청 메트릭을 보강합니다.
  • 에서 가져옵니다 IHttpMetricsTagsFeatureHttpContext. 이 기능은 누군가가 메트릭을 수신 대기하는 경우에만 컨텍스트에 있습니다. 사용 전이 아닌지 null 확인 IHttpMetricsTagsFeature 합니다.
  • 요청의 마케팅 원본이 포함된 사용자 지정 태그를 메트릭에 http.server.request.duration 추가합니다.
    • 태그에는 utm_medium 쿼리 문자열 값을 기반으로 하는 이름과 mkt_medium 값이 있습니다. 값은 utm_medium 알려진 값 범위로 확인됩니다.
    • 태그를 사용하면 웹앱 트래픽을 분석할 때 유용할 수 있는 마케팅 중간 유형별로 요청을 분류할 수 있습니다.

참고 항목

사용자 지정 태그를 사용하여 보강할 때 다차원 메트릭 모범 사례를 따릅니다. 태그가 너무 많거나 언바운드 범위가 있는 태그로 인해 태그가 많이 조합됩니다. 컬렉션 도구는 카운터에 대해 지원하는 조합 수에 제한이 있으며 과도한 메모리 사용을 방지하기 위해 결과 필터링을 시작할 수 있습니다.

사용자 지정 메트릭 만들기

메트릭은 네임스페이스의 API를 System.Diagnostics.Metrics 사용하여 만들어집니다. 사용자 지정 메트릭을 만드는 방법에 대한 자세한 내용은 사용자 지정 메트릭 만들기를 참조하세요.

를 사용하여 ASP.NET Core 앱에서 메트릭 만들기 IMeterFactory

를 사용하여 ASP.NET Core 앱에서 인스턴스를 IMeterFactory만드는 Meter 것이 좋습니다.

ASP.NET Core는 IMeterFactory 기본적으로 DI(종속성 주입)에 등록됩니다. 미터 팩터리는 메트릭을 DI와 통합하여 메트릭을 쉽게 격리하고 수집할 수 있습니다. IMeterFactory 는 테스트에 특히 유용합니다. 이를 통해 여러 테스트를 나란히 실행하고 테스트에 기록된 메트릭 값만 수집할 수 있습니다.

앱에서 사용 IMeterFactory 하려면 앱의 사용자 지정 메트릭을 만드는 데 사용하는 IMeterFactory 형식을 만듭니다.

public class ContosoMetrics
{
    private readonly Counter<int> _productSoldCounter;

    public ContosoMetrics(IMeterFactory meterFactory)
    {
        var meter = meterFactory.Create("Contoso.Web");
        _productSoldCounter = meter.CreateCounter<int>("contoso.product.sold");
    }

    public void ProductSold(string productName, int quantity)
    {
        _productSoldCounter.Add(quantity,
            new KeyValuePair<string, object?>("contoso.product.name", productName));
    }
}

다음에서 DI를 사용하여 메트릭 형식을 등록합니다.Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ContosoMetrics>();

필요한 경우 메트릭 형식 및 레코드 값을 주입합니다. 메트릭 형식은 DI에 등록되므로 MVC 컨트롤러, 최소 API 또는 DI에서 만든 다른 형식과 함께 사용할 수 있습니다.

app.MapPost("/complete-sale", (SaleModel model, ContosoMetrics metrics) =>
{
    // ... business logic such as saving the sale to a database ...

    metrics.ProductSold(model.ProductName, model.QuantitySold);
});

"Contoso.Web" 미터를 모니터링하려면 다음 dotnet-counters 명령을 사용합니다.

dotnet-counters monitor -n WebMetric --counters Contoso.Web

다음과 비슷한 출력이 표시됩니다.

Press p to pause, r to resume, q to quit.
    Status: Running

[Contoso.Web]
    contoso.product.sold (Count / 1 sec)
        contoso.product.name=Eggs            12    
        contoso.product.name=Milk            0    

OpenTelemetry 및 Prometheus를 사용하여 Grafana에서 메트릭 보기

개요

OpenTelemetry:

  • Cloud Native Computing Foundation에서 지원하는 공급업체 중립적 오픈 소스 프로젝트입니다.
  • 클라우드 기반 소프트웨어에 대한 원격 분석 생성 및 수집을 표준화합니다.
  • .NET 메트릭 API를 사용하여 .NET에서 작동합니다.
  • Azure Monitor 및 많은 APM 공급업체의 보증을 받았습니다.

이 자습서에서는 OSS PrometheusGrafana 프로젝트를 사용하여 OpenTelemetry 메트릭에 사용할 수 있는 통합 중 하나를 보여 줍니다. 메트릭 데이터 흐름:

  1. ASP.NET Core 메트릭 API는 예제 앱의 측정값을 기록합니다.

  2. 앱에서 실행되는 OpenTelemetry .NET 라이브러리는 측정값을 집계합니다.

  3. Prometheus exporter 라이브러리는 HTTP 메트릭 엔드포인트를 통해 집계된 데이터를 사용할 수 있게 합니다. 'Exporter'는 OpenTelemetry가 공급업체별 백 엔드에 원격 분석을 전송하는 라이브러리라고 부르는 것입니다.

  4. Prometheus 서버:

    • 메트릭 엔드포인트를 폴링합니다.
    • 데이터를 읽습니다.
    • 장기간 지속성을 위해 데이터를 데이터베이스에 저장합니다. Prometheus는 엔드포인트를 스크래핑하는 것으로 데이터를 읽고 저장하는 것을 말합니다.
    • 다른 컴퓨터에서 실행 가능
  5. Grafana 서버:

    • Prometheus에 저장된 데이터를 쿼리하여 웹 기반 모니터링 대시보드에 표시합니다.
    • 다른 컴퓨터에서 실행할 수 있습니다.

샘플 앱에서 메트릭 보기

샘플 앱으로 이동합니다. 브라우저는 현재 DateTime.Ticks의 마지막 3자리 자릿수를 3digits 표시 Hello OpenTelemetry! ticks:<3digits> 합니다.

URL에 추가하여 /metrics 메트릭 엔드포인트를 봅니다. 브라우저에 수집되는 메트릭이 표시됩니다.

메트릭 2

Prometheus 설정 및 구성

Prometheus 첫 번째 단계에 따라 Prometheus 서버를 설정하고 작동 중인지 확인합니다.

Prometheus가 예제 앱이 노출하는 메트릭 엔드포인트를 스크랩하도록 prometheus.yml 구성 파일을 수정합니다. scrape_configs 섹션에 다음 강조 표시된 텍스트를 추가합니다.

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]

  - job_name: 'MyASPNETApp'
    scrape_interval: 5s # Poll every 5 seconds for a more responsive demo.
    static_configs:
      - targets: ["localhost:5045"]  ## Enter the HTTP port number of the demo app.

앞에서 강조 표시된 YAML에서 예제 앱이 실행 중인 포트 번호로 바꿉 5045 다.

Prometheus 시작

  1. 구성을 다시 로드하거나 Prometheus 서버를 다시 시작합니다.
  2. Prometheus 웹 포털의 상태>대상 페이지에서 OpenTelemetryTest가 UP 상태인지 확인합니다.

프로메테우스 상태

메트릭 탐색기 열기 아이콘을 선택하여 사용 가능한 메트릭을 확인합니다.

프로메테우스 open_metric_exp

입력 상자와 같은 http_ 카운터 범주를 입력하여 사용 가능한 메트릭을 확인합니다.

사용 가능한 메트릭

또는 식 입력 상자와 같은 kestrel 카운터 범주를 입력하여 사용 가능한 메트릭을 확인합니다.

Prometheus kestrel

Grafana 대시보드에 메트릭 표시

dashboard-screenshot2

ASP.NET Core 앱에서 메트릭 테스트

ASP.NET Core 앱에서 메트릭을 테스트할 수 있습니다. 이 작업을 수행하는 한 가지 방법은 ASP.NET Core 통합 테스트에서 메트릭 값을 수집하고 어설션하는 것입니다MetricCollector<T>.

public class BasicTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;
    public BasicTests(WebApplicationFactory<Program> factory) => _factory = factory;

    [Fact]
    public async Task Get_RequestCounterIncreased()
    {
        // Arrange
        var client = _factory.CreateClient();
        var meterFactory = _factory.Services.GetRequiredService<IMeterFactory>();
        var collector = new MetricCollector<double>(meterFactory,
            "Microsoft.AspNetCore.Hosting", "http.server.request.duration");

        // Act
        var response = await client.GetAsync("/");

        // Assert
        Assert.Contains("Hello OpenTelemetry!", await response.Content.ReadAsStringAsync());

        await collector.WaitForMeasurementsAsync(minCount: 1).WaitAsync(TimeSpan.FromSeconds(5));
        Assert.Collection(collector.GetMeasurementSnapshot(),
            measurement =>
            {
                Assert.Equal("http", measurement.Tags["url.scheme"]);
                Assert.Equal("GET", measurement.Tags["http.request.method"]);
                Assert.Equal("/", measurement.Tags["http.route"]);
            });
    }
}

진행 테스트:

  • 를 사용하여 메모리 WebApplicationFactory<TEntryPoint>에 웹앱을 부트스트랩합니다. Program 팩터리의 제네릭 인수에서 웹앱을 지정합니다.
  • 를 사용하여 메트릭 값을 수집합니다. MetricCollector<T>
    • 에 대한 패키지 참조가 필요합니다. Microsoft.Extensions.Diagnostics.Testing
    • MetricCollector<T>IMeterFactory의 .를 사용하여 만들어집니다. 이렇게 하면 수집기에서 테스트에 의해 기록된 메트릭 값만 보고할 수 있습니다.
    • 수집할 미터 이름 Microsoft.AspNetCore.Hosting및 카운터 이름을 http.server.request.duration 포함합니다.
  • 웹앱에 대한 HTTP 요청을 만듭니다.
  • 메트릭 수집기의 결과를 사용하여 테스트를 어설션합니다.

ASP.NET Core 미터 및 카운터

ASP.NET Core 미터 및 카운터 목록은 ASP.NET Core 메트릭을 참조하세요.