度量是隨時間報告的數值測量。 利用它們來監控應用程式的健康狀況並產生警示。 例如,Web 服務可能會追蹤以下計量:
- 每秒收到的請求數。
- 回應只需毫秒。
- 它傳送的回應有誤。
定期向監控系統回報這些指標。 設定儀表板來檢視指標,並建立警示,以便在發生問題時通知相關人員。 如果 Web 服務預期在 400 毫秒內回應要求,但在 600 毫秒內開始回應,則監視系統可以通知作業人員應用程式回應速度比正常慢。
所有工具及其屬性的完整清單,皆在 ASP.NET Core 內建指標中描述。
使用計量
使用計量牽涉到下列事項:
- 檢測:.NET 程式庫中的程式碼會採用度量,並將這些度量與計量名稱產生關聯。 .NET 和 ASP.NET Core 包含許多內建計量。
- 收集和儲存:.NET 應用程式會設定要從應用程式傳輸的命名指標,以進行外部儲存和分析。 有些工具可能會透過設定檔或介面工具,在應用程式外進行設定。
- 可視化: 工具,可顯示人類可讀取格式的計量。 例如 ,Grafana 和 Prometheus。
- 提醒: 當計量超過閾值時提供通知的工具。 例如,如果 Web 服務的平均響應時間超過 400 毫秒,可以將警示傳送給作業人員。
- 分析: 一種工具,可以隨時間分析指標。 這個工具通常是基於網頁的儀表板,可以自訂以顯示特定應用程式最重要的指標。
儀器化程式碼可以記錄數值測量,但要建立有用的監控指標,你需要彙整、傳輸並儲存這些測量數據。 匯總、傳輸和儲存數據的程序稱為收集。 本教學課程示範收集及顯示計量的數個範例:
- 使用 OpenTelemetry 和 Prometheus 在 Grafana 中填入計量。
- 使用
dotnet-counters即時檢視計量
你也可以將測量值與稱為標籤的鍵值對關聯,方便你將資料分類分析。 如需詳細資訊,請參閱多維度計量。
建立入門應用程式
使用下列命令來建立新的 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 應用程式流量時會很有用。
- 標記具有名稱
備註
使用自訂標記擴充時,請遵循多維度計量最佳做法。 太多或具有未系結範圍的標記會建立許多標籤組合,進而產生高維度。 收集工具對計數器支援的維度有限制,並可能過濾結果以防止過度使用記憶體。
針對特定端點和請求停用 HTTP 指標
對於經常被自動化系統呼叫的端點(例如健康檢查),選擇不紀錄計量資料可帶來益處。 通常不需要為這些要求記錄指標。 不必要的遙測會耗用資源來進行收集和儲存,並且可能會扭曲遙測儀錶板中顯示的結果。
你可以加入中繼資料,使用 DisableHttpMetrics 屬性或 DisableHttpMetrics 方法,將傳送至端點的 HTTP 要求排除在計量之外:
- 將 DisableHttpMetrics 屬性加入 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);
});
建立自訂計量
你可以透過在命名空間中使用 API System.Diagnostics.Metrics 來建立指標。 相關資訊請參見 「建立自訂指標」。
使用 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
- 這是 Cloud Native Computing Foundation 所支援的廠商中性開放原始碼專案。
- 標準化為雲端原生軟體產生和收集遙測資料。
- 使用 .NET 計量 API 進行操作。
- 由 Azure 監視器 和許多 APM(應用程式效能管理)廠商支持。
自 ASP.NET Core 11 起,框架內建的 HTTP 伺服器度量與追蹤符符符合 OpenTelemetry HTTP 伺服器語意慣例的必要部分。 HTTP 伺服器請求活動預設會發出這些屬性,與內建的指標相符。 因此, OpenTelemetry.Instrumentation.AspNetCore NuGet 套件在收集 HTTP 伺服器指標與追蹤時是可選的。 本文範例僅使用內建的電表(Microsoft.AspNetCore.Hosting 和 Microsoft.AspNetCore.Server.Kestrel),並未參考儀器套件。 關於內建工具及其屬性的清單,請參見 ASP.NET Core 內建 HTTP 指標。
雖然此套件是選配項目,但它並不是內建檢測機制的可直接替換等效項。 內建的儀器僅涵蓋語意慣例 所需的 部分。 在取出包裝前,請考慮以下差異:
- 某些 推薦 的 HTTP 伺服器屬性並非由內建儀器所產生,例如某些用戶端與網路屬性(例如
client.address)。 對 條件要求url.query屬性(包括遮蔽)的完整支援仍在進行中。 如果你需要依賴這些屬性,請保留這個套件。 更多資訊請參見 dotnet/aspnetcore#65873。 - 此套件也可讓您輕鬆啟用 HTTP 伺服器以外的遙測,包括 Blazor 和 SignalR。 在追蹤時,它會登錄額外的活動來源(SignalR
Microsoft.AspNetCore.SignalR.Server在 .NET 9 及以後版本)和 Blazor (Microsoft.AspNetCore.ComponentsMicrosoft.AspNetCore.Components.Server.Circuits在 .NET 10 及以後版本)。 對於度量,它啟用了相關的內建計量器(例如Microsoft.AspNetCore.Components)。 沒有套件的話,將來源AddSource和儀表都註冊給AddMeter自己,這樣就能收集相同的遙測數據。
當你在只需要 HTTP 伺服器指標和追蹤的應用程式中加入遙測時,你可以依賴內建的儀器,省略這個套件。 當您將已參考該套件的現有應用程式從 .NET 10 升級至 .NET 11 時,如果您相依於前述清單中所述的屬性、來源或計量器,請保留該套件。 移除該套件會在無任何提示的情況下遺失該遙測資料。
重要
當你啟用 OpenTelemetry 追蹤 (除了指標外)而不使用 OpenTelemetry.Instrumentation.AspNetCore 套件時,請註冊框架的 HTTP 伺服器 ActivitySource ,以便記錄請求活動。 ASP.NET Core 的 HTTP 伺服器活動來源名為 Microsoft.AspNetCore,而且該架構會為每個要求建立一個名為 Microsoft.AspNetCore.Hosting.HttpRequestIn 的請求活動,以傳播追蹤上下文。 如果 Microsoft.AspNetCore 來源沒有在 OpenTelemetry SDK 註冊,請求活動就不會被記錄,預設 ParentBased 取樣器會靜默地丟棄請求期間開始的自訂子區段。
在現有的追蹤流程中,明確註冊來源:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource("Microsoft.AspNetCore")
.AddSource("MyApp"));
在前述範例中:
-
AddSource("Microsoft.AspNetCore")註冊 ASP.NET Core 的 HTTP 伺服器活動來源,以便記錄請求活動。 -
AddSource("MyApp")註冊應用程式自己的 ActivitySource。 用你應用程式使用的名稱來取代MyApp。 - 沒有顯示出口商。 這個例子假設你的追蹤管線中已經設定了匯出器。
或者,從AddAspNetCoreInstrumentation()OpenTelemetry.Instrumentation.AspNetCore套件呼叫,套件會幫你註冊來源。
本教程展示如何使用 OSS Prometheus 和 Grafana 專案來整合 OpenTelemetry 度量。 計量數據流:
ASP.NET Core 計量 API 會記錄來自範例應用程式的度量。
在應用程式中執行的 OpenTelemetry .NET 程式庫會彙總度量。
Prometheus 匯出工具程式庫會透過 HTTP 計量端點提供經彙總的資料。 'Exporter' 是 OpenTelemetry 中用來將遙測數據傳輸到廠商特定後端的程式庫。
Prometheus 伺服器:
- 輪詢指標端點。
- 讀取資料。
- 將數據儲存在資料庫中以供長期保存。 Prometheus 是指將數據讀取和儲存為 擷取 端點。
- 可以在不同的電腦上執行。
Grafana 伺服器:
- 查詢儲存在 Prometheus 中的資料,並將其顯示在 Web 型監視儀表板上。
- 可以在不同的電腦上執行。
從範例應用程式檢視計量
去試用版應用程式看看。 瀏覽器會顯示Hello OpenTelemetry! ticks:<3digits>目前 DateTime.Ticks 的最後三位數字在哪裡3digits。
附加 /metrics 至 URL 以檢視計量端點。 瀏覽器會顯示正在收集的計量:
設置和配置 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
- 重載設定或重新啟動 Prometheus 伺服器。
- 確認 OpenTelemetryTest 在 Prometheus 入口網站的 [ 狀態>目標 ] 頁面中處於 UP 狀態。
選取 [開啟計量總管] 圖示以查看可用的計量:
在 運算式 輸入方塊中輸入計數器類別,例如 http_,即可查看可用的計量:
或者,在 運算式 輸入框中輸入計數器類別(例如 kestrel),以查看可用的指標:
在 Grafana 儀錶板上顯示計量
遵循安裝指示來安裝 Grafana,並將其連線到 Prometheus 資料來源。
遵循建立 Prometheus 圖形的指示。 或者,.NET 計量的預先建置儀表板可在 .NET 小組儀表板 @ grafana.com 下載。 下載的儀表板 JSON 就可以 匯入至 Grafana。
在 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> 啟動記憶體中的 Web 應用程式。 處理站泛型引數中的
Program會指定 Web 應用程式。 - 使用 MetricCollector<T> 收集計量值
- 需要一個套件參照
Microsoft.Extensions.Diagnostics.Testing。 -
MetricCollector<T>是使用 Web 應用程式的 IMeterFactory 建立。 這讓收集器僅報告測試記錄的計量值。 - 包含要收集的計量名稱
Microsoft.AspNetCore.Hosting和計數器名稱http.server.request.duration。
- 需要一個套件參照
- 對 Web 應用程式提出 HTTP 要求。
- 使用指標收集器的結果來驗證測試。
ASP.NET Core 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 指標。 在 ASP.NET Core 11 及之後版本中,內建的 HTTP 伺服器計量器(例如 Microsoft.AspNetCore.Hosting 和 Microsoft.AspNetCore.Server.Kestrel)會輸出符合 OpenTelemetry HTTP 伺服器語意慣例所需部分的資料。 你無須使用 OpenTelemetry.Instrumentation.AspNetCore 套件,也可以透過 OpenTelemetry SDK 取用這些儀表。