Compartilhar via


Geração de origem de métrica em tempo de compilação

. A infraestrutura de medição do NET foi projetada para fornecer uma solução de medição de alto desempenho e altamente utilizável para aplicativos .NET modernos.

Para usar a medição gerada pela origem, crie uma classe que defina os nomes e dimensões das métricas que seu código pode produzir. Em seguida, crie a classe com assinatura do método partial.

O gerador de origem gera automaticamente o código, que expõe tipos de medição fortemente tipados e métodos que você pode invocar para registrar valores de métrica. Os métodos gerados são implementados em uma forma altamente eficiente, o que reduz a sobrecarga de computação em comparação com as soluções de medição tradicionais.

Introdução

Para começar, instale o 📦 pacote NuGet Microsoft.Extensions.Telemetry.Abstractions :

dotnet add package Microsoft.Extensions.Telemetry.Abstractions

Para obter mais informações, consulte dotnet add package ou Gerenciar dependências de pacotes em aplicativos .NET.

Atributos genéricos

Atributos genéricos exigem C# 11 ou posterior. Para C# 10 ou anterior, use atributos nãogenericos.

O exemplo a seguir mostra uma classe que declara três métricas. Os métodos são marcados com um atributo e são declarados como static e partial. O gerador de código é executado no momento de compilação e fornece uma implementação desses métodos, juntamente com os tipos associados.

internal class MetricConstants
{
    public const string EnvironmentName = "env";
    public const string Region = "region";
    public const string RequestName = "requestName";
    public const string RequestStatus = "requestStatus";
}

O código a seguir demonstra como usar o gerador com tipos primitivos:

using System.Diagnostics.Metrics;
using Microsoft.Extensions.Diagnostics.Metrics;

namespace MetricsGen;

internal static partial class Metric
{
    // an explicit metric name is given
    [Histogram<long>("requestName", "duration", Name = "MyCustomMetricName")]
    public static partial Latency CreateLatency(Meter meter);

    // no explicit metric name given, it is auto-generated from the method name
    [Counter<int>(
        MetricConstants.EnvironmentName,
        MetricConstants.Region,
        MetricConstants.RequestName,
        MetricConstants.RequestStatus)]
    public static partial TotalCount CreateTotalCount(Meter meter);

    [Counter<int>]
    public static partial TotalFailures CreateTotalFailures(this Meter meter);
}

Especificando unidades

A partir do .NET 10.2, opcionalmente, você pode especificar uma unidade de medida para suas métricas usando o Unit parâmetro. Isso ajuda a fornecer contexto sobre o que a métrica mede (por exemplo, "segundos", "bytes" e "solicitações"). A unidade é passada para o elemento subjacente Meter ao criar o instrumento.

O código a seguir demonstra como usar o gerador com tipos primitivos com unidades especificadas:

internal static partial class Metric
{
    [Histogram<long>("requestName", "duration", Name = "MyCustomMetricName", Unit = "ms")]
    public static partial Latency CreateLatency(Meter meter);

    [Counter<int>(
        MetricConstants.EnvironmentName,
        MetricConstants.Region,
        MetricConstants.RequestName,
        MetricConstants.RequestStatus,
        Unit = "requests")]
    public static partial TotalCount CreateTotalCount(Meter meter);

    [Counter<int>(Unit = "failures")]
    public static partial TotalFailures CreateTotalFailures(this Meter meter);
}

A declaração anterior retorna automaticamente o seguinte:

  • Latency classe com um Record método
  • TotalCount classe com um Add método
  • TotalFailures classe com um método Add.

Os atributos indicam o conjunto de dimensões que cada métrica usa. A assinatura dos tipos gerados tem esta aparência:

internal class TotalCount
{
    public void Add(int value, object? env, object? region, object? requestName, object? requestStatus)
}

internal class TotalFailures
{
    public void Add(int value)
}

internal class Latency
{
    public void Record(long value, object? requestName, object? duration);
}

As dimensões especificadas nos atributos foram transformadas em argumentos para os métodos Add e Record. Em seguida, use os métodos gerados para criar instâncias desses tipos. Com as instâncias criadas, você pode chamar Add e Record registrar valores de métrica, conforme mostrado no exemplo a seguir:

internal class MyClass
{
    // these variable are for example purposes, the dimensions values should depend on your business logic.
    private string envName = "envValue";
    private string regionName = "regionValue";
    private string requestName = "requestNameValue";
    private string status = "requestStatusValue";
    private string duration = "1:00:00";

    private readonly Latency _latencyMetric;
    private readonly TotalCount _totalCountMetric;
    private readonly TotalFailures _totalFailuresMetric;

    public MyClass(Meter meter)
    {
        // Create metric instances using the source-generated factory methods
        _latencyMetric = Metric.CreateLatency(meter);
        _totalCountMetric = Metric.CreateTotalCount(meter);
        // This syntax is available since `CreateTotalFailures` is defined as an extension method
        _totalFailuresMetric = meter.CreateTotalFailures();
    }

    public void ReportSampleRequestCount()
    {
        // method logic ...

        // Invoke Add on the counter and pass the dimension values you need.
        _totalCountMetric.Add(1, envName, regionName, requestName, status);
    }

    public void ReportSampleLatency()
    {
        // method logic ...

        // Invoke Record on the histogram and pass the dimension values you need.
        _latencyMetric.Record(1, requestName, duration);
    }

    public void ReportSampleFailuresCount()
    {
        // method logic ...

        // Invoke Add on the counter and pass the dimension values you need.
        _totalFailuresMetric.Add(1);
    }
}

Requisitos de métodos de medição

Os métodos de métrica são restritos ao seguinte:

  • Eles devem ser public static partial.
  • O tipo de retorno deve ser exclusivo.
  • Seus nomes não devem começar com um sublinhado.
  • Seus nomes de parâmetro não devem começar com um sublinhado.
  • O primeiro parâmetro deve ser do tipo Meter.

Consulte também

Para obter mais informações sobre as métricas com suporte, consulte Tipos de instrumentos para saber como escolher qual instrumento usar em diferentes situações.