共用方式為


ASP.NET Core 指標

度量是隨時間報告的數值測量。 它們通常用來監視應用程式的健康情況,並產生警示。 例如,Web 服務可能會追蹤以下計量:

  • 每秒收到的請求數。
  • 回應所耗費的毫秒數。
  • 回應發送時發生錯誤。

這些指標可以定期地回報給監控系統。 可以設定儀表板來檢視建立的計量和警示,以通知人員相關的問題。 如果 Web 服務預期在 400 毫秒內回應要求,但在 600 毫秒內開始回應,則監視系統可以通知作業人員應用程式回應速度比正常慢。

如需所有檢測及其屬性的完整清單,請參閱 ASP.NET Core 計量

使用計量

使用計量牽涉到下列事項:

  • 檢測:.NET 程式庫中的程式碼會採用度量,並將這些度量與計量名稱產生關聯。 .NET 和 ASP.NET Core 包含許多內建計量。
  • 收集和儲存:.NET 應用程式會設定要從應用程式傳輸的命名指標,以進行外部儲存和分析。 某些工具可能會使用設定檔或 UI 工具,在應用程式外部執行設定。
  • 可視化: 工具,可顯示人類可讀取格式的計量。 例如 ,GrafanaPrometheus
  • 提醒: 當計量超過閾值時提供通知的工具。 例如,如果 Web 服務的平均響應時間超過 400 毫秒,可以將警示傳送給作業人員。
  • 分析: 一種工具,可以隨時間分析指標。 這通常是 Web 型儀錶板,可自定義以顯示特定應用程式最重要的計量。

檢測的程式碼可以記錄數值度量,但度量需要經過彙總、傳輸和儲存,以建立實用的監視計量。 彙總、傳輸和儲存資料的此程序稱為收集。 本教學課程示範收集及顯示計量的數個範例:

測量也可以與稱為標籤的索引鍵/值組相關聯,以便將資料分類以供分析。 如需詳細資訊,請參閱多維度計量

建立入門應用程式

使用下列命令來建立新的 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 應用程式的即時計量。 它不需要設定,因此適合臨機操作調查,或驗證計量檢測可正常運作。 其適用於 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-counters

強化 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 請求指標。
  • IHttpMetricsTagsFeature 取得 HttpContext。 只有當有人正在監聽該指標時,該功能才會出現在背景中。 使用之前,請先驗證 IHttpMetricsTagsFeature 不是 null
  • 將包含要求行銷來源的自訂標記新增至 http.server.request.duration 計量。
    • 標記具有名稱 mkt_medium,其值基於 utm_medium 查詢字串的值。 utm_medium 值會解析為已知的值範圍。
    • 標記會允許依行銷媒體類型分類要求,這在分析 Web 應用程式流量時會很有用。

Note

使用自訂標記擴充時,請遵循多維度計量最佳做法。 太多或具有未系結範圍的標記會建立許多標籤組合,進而產生高維度。 收集工具對計數器支援的維度有限制,而且可能會篩選結果以防止記憶體過多使用。

在特定端點與要求退出 HTTP 計量

選擇不記錄指標對於經常被自動化系統呼叫的端點(例如健康檢查)是有益的。 這些要求通常不需要記錄計量。 不必要的遙測會耗用資源來進行收集和儲存,並且可能會扭曲遙測儀錶板中顯示的結果。

使用 DisableHttpMetrics 屬性或 DisableHttpMetrics 方法,即可從計量中排除對端點的 HTTP 要求:

  • Disable Natrics 屬性新增至 Web API 控制器、 SignalR 中樞或 gRPC 服務。
  • 在應用程式啟動時,進行端點對應時呼叫 DisableHttpMetrics
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();

var app = builder.Build();
app.MapHealthChecks("/healthz").DisableHttpMetrics();
app.Run();

或者,已為下列項目新增 IHttpMetricsTagsFeature.MetricsDisabled 屬性:

  • 用於要求未對應至端點的進階案例。
  • 動態停用特定 HTTP 要求的計量集合。
// Middleware that conditionally opts-out HTTP requests.
app.Use(async (context, next) =>
{
    var metricsFeature = context.Features.Get<IHttpMetricsTagsFeature>();
    if (metricsFeature != null &&
        context.Request.Headers.ContainsKey("x-disable-metrics"))
    {
        metricsFeature.MetricsDisabled = true;
    }

    await next(context);
});

建立自訂計量

計量是使用 System.Diagnostics.Metrics 命名空間中的 API 來建立。 如需建立自訂計量的相關資訊,請參閱建立自訂計量

使用 IMeterFactory 在 ASP.NET Core 應用程式中建立計量

我們建議在 ASP.NET Core 應用程式中使用 Meter 來建立 IMeterFactory 執行個體。

依預設,ASP.NET Core 會在相依性插入 (DI) 中註冊 IMeterFactory。 計量工廠將計量與 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));
    }
}

Program.cs 中向 DI 註冊計量型別:

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 中的計量

Overview

OpenTelemetry:

本教學課程展示了如何使用 OSS PrometheusGrafana 專案來整合一種 OpenTelemetry 指標。 計量資料流程:

  1. ASP.NET Core 計量 API 會記錄來自範例應用程式的度量。

  2. 在應用程式中執行的 OpenTelemetry .NET 程式庫會彙總度量。

  3. Prometheus 匯出工具程式庫會透過 HTTP 計量端點提供經彙總的資料。 「Exporter」是 OpenTelemetry 指定用來將遙測資料傳輸至特定廠商後端的程式庫。

  4. Prometheus 伺服器:

    • 輪詢計量端點
    • 讀取資料
    • 將資料儲存在資料庫中供長期保存。 Prometheus 將讀取並儲存資料稱為抓取端點。
    • 可以在不同的電腦上執行
  5. Grafana 伺服器:

    • 查詢儲存在 Prometheus 中的資料,並將其顯示在 Web 型監視儀表板上。
    • 可以在不同的電腦上執行。

從範例應用程式檢視計量

瀏覽至範例應用程式。 瀏覽器會顯示 Hello OpenTelemetry! ticks:<3digits>,其中的 3digits 為目前 DateTime.Ticks 的最後 3 位數。

附加 /metrics 至 URL 以檢視計量端點。 瀏覽器會顯示正在收集的計量:

計量指標 2

設置和配置 Prometheus

遵循 Prometheus first steps (英文) 來設定 Prometheus 伺服器,並確認其正常運作。

修改 prometheus.yml 設定檔,使得 Prometheus 會抓取範例應用程式公開的計量端點。 在 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. 確認 OpenTelemetryTest 在 Prometheus 入口網站的 [狀態]> [目標] 頁面中處於運作中狀態。

Prometheus 狀態

選取 [開啟計量總管] 圖示以查看可用的計量:

普羅米修斯open_metric_exp

http_ 輸入方塊中輸入計數器類別,例如 ,以查看可用的指標:

可用指標

或者,在 [運算式]kestrel 輸入方塊中輸入計數器類別,例如 ,以查看可用的計量:

普羅米修斯紅隼

在 Grafana 儀表板上顯示計量

dashboard-screenshot2

在 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> 啟動記憶體中的 Web 應用程式。 處理站泛型引數中的 Program 會指定 Web 應用程式。
  • 使用 MetricCollector<T> 收集計量值
    • 需要一個套件參照 Microsoft.Extensions.Diagnostics.Testing
    • MetricCollector<T> 是使用 Web 應用程式的 IMeterFactory 建立。 這讓收集器僅報告測試記錄的計量值。
    • 包含要收集的計量名稱 Microsoft.AspNetCore.Hosting 和計數器名稱 http.server.request.duration
  • 對 Web 應用程式提出 HTTP 要求。
  • 使用計量收集器的結果來驗證測試。

ASP.NET 核心 Identity 指標

ASP.NET Core Identity 可觀測性可協助您監控使用者管理活動和身份驗證流程。

度量以 Microsoft.AspNetCore.Identity 公尺為單位,並在下列各節中說明。

使用者管理指標

  • aspnetcore.identity.user.create.duration 測量使用者建立作業的持續時間。
  • aspnetcore.identity.user.update.duration 測量使用者更新作業的持續時間。
  • aspnetcore.identity.user.delete.duration 測量使用者刪除操作的持續時間
  • aspnetcore.identity.user.check_password_attempts 計算密碼驗證嘗試次數。
  • aspnetcore.identity.user.generated_tokens 計算為使用者產生的令牌,例如密碼重設令牌。
  • aspnetcore.identity.user.verify_token_attempts 計算令牌驗證嘗試。

驗證指標

  • aspnetcore.identity.sign_in.authenticate.duration 測量身份驗證操作的持續時間。
  • aspnetcore.identity.sign_in.check_password_attempts 計算登入期間的密碼檢查嘗試次數。
  • aspnetcore.identity.sign_in.sign_ins 計算成功的登入次數。
  • aspnetcore.identity.sign_in.sign_outs 計算登出次數。
  • aspnetcore.identity.sign_in.two_factor_clients_remembered 計算記住的雙因素身份驗證用戶端。
  • aspnetcore.identity.sign_in.two_factor_clients_forgotten 計算被遺忘的雙重驗證客戶端。

這些量度可用於:

  • 監控使用者註冊和管理。
  • 追蹤身份驗證模式和潛在的安全問題。
  • 衡量營運績效 Identity 。
  • 觀察雙因素身份驗證的使用情況。

檢視 Identity 指標

您可以使用來 dotnet-counters 檢視這些指標,以即時監控它們,或將它們匯出至 Prometheus,並使用本文稍早所述的技術在 Grafana 中視覺化它們。

例如,若要監控所有Identity 指標 以使用 dotnet-counters

dotnet-counters monitor -n YourAppName --counters Microsoft.AspNetCore.Identity

ASP.NET Core 計量和計數器

如需 ASP.NET Core 計量和計數器清單,請參閱 ASP.NET Core 計量