prometheus-net
115 строк · 5.3 Кб
1using Microsoft.AspNetCore.Http.Extensions;2using Prometheus;3using Prometheus.HttpMetrics;4
5// This sample demonstrates how to integrate prometheus-net into a web app.
6//
7// NuGet packages required:
8// * prometheus-net.AspNetCore
9
10// Let's suppress the default metrics that are built-in, to more easily see the changing metrics output.
11Metrics.SuppressDefaultMetrics();12
13var builder = WebApplication.CreateBuilder(args);14
15builder.Services.AddRazorPages();16
17var app = builder.Build();18
19if (!app.Environment.IsDevelopment())20{
21app.UseExceptionHandler("/Error");22}
23app.UseStaticFiles();24
25app.UseRouting();26
27// Use an auto-expiring variant for all the demo metrics here - they get automatically deleted if not used in the last 60 seconds.
28var expiringMetricFactory = Metrics.WithManagedLifetime(expiresAfter: TimeSpan.FromSeconds(60));29
30// OPTION 1: metric lifetime can be managed by leases, to ensure they do not go away during potentially
31// long-running operations but go away quickly when the operation is not running anymore (e.g. "in progress" type metrics).
32_ = Task.Run(async delegate33{
34var inProgress = expiringMetricFactory.CreateGauge("long_running_operations_in_progress", "Number of long running operations in progress.", labelNames: new[] { "operation_type" });35
36// The metric will not be deleted as long as this lease is kept.37await inProgress.WithLeaseAsync(async inProgressInstance =>38{39// Long-running operation, which we track via the "in progress" gauge.40using (inProgressInstance.TrackInProgress())41await Task.Delay(TimeSpan.FromSeconds(30));42}, "VeryLongOperation");43
44// Just to let you know when to look at it.45Console.WriteLine("Long-running operation has finished.");46
47// Done! Now the metric lease will be released and soon, the metric will expire and be removed.48});49
50// OPTION 2: metrics can auto-extend lifetime whenever their values are updated.
51app.UseHttpMetrics(options =>52{
53// Here we do something that is typically a no-no in terms of best practices (and GDPR?): we record every unique URL!54// We use metric expiration to keep the set of metrics in-memory limited to only recently used URLs, which limits the likelihood55// of our web server getting DoSed. We will still need a very very beefy metrics database to actually handle so much data,56// so this is not a good idea even if we manage to bypass the most obvious stumbling block of running out of memory!57options.AddCustomLabel("url", context => context.Request.GetDisplayUrl());58
59options.InProgress.Gauge = expiringMetricFactory.CreateGauge(60"http_requests_in_progress",61"The number of requests currently in progress in the ASP.NET Core pipeline. One series without controller/action label values counts all in-progress requests, with separate series existing for each controller-action pair.",62// Let's say that we have all the labels present, as automatic label set selection does not work if we use a custom metric.63labelNames: HttpRequestLabelNames.All64// ... except for "Code" which is only possible to identify after the request is already finished.65.Except(new[] { "code" })66// ... plus the custom "url" label that we defined above.67.Concat(new[] { "url" })68.ToArray())69.WithExtendLifetimeOnUse();70
71options.RequestCount.Counter = expiringMetricFactory.CreateCounter(72"http_requests_received_total",73"Provides the count of HTTP requests that have been processed by the ASP.NET Core pipeline.",74// Let's say that we have all the labels present, as automatic label set selection does not work if we use a custom metric.75labelNames: HttpRequestLabelNames.All76// ... plus the custom "url" label that we defined above.77.Concat(new[] { "url" })78.ToArray())79.WithExtendLifetimeOnUse();80
81options.RequestDuration.Histogram = expiringMetricFactory.CreateHistogram(82"http_request_duration_seconds",83"The duration of HTTP requests processed by an ASP.NET Core application.",84// Let's say that we have all the labels present, as automatic label set selection does not work if we use a custom metric.85labelNames: HttpRequestLabelNames.All86// ... plus the custom "url" label that we defined above.87.Concat(new[] { "url" })88.ToArray(),89new HistogramConfiguration90{91// 1 ms to 32K ms buckets92Buckets = Histogram.ExponentialBuckets(0.001, 2, 16)93})94.WithExtendLifetimeOnUse();95});96
97app.UseAuthorization();98
99app.MapRazorPages();100
101app.UseEndpoints(endpoints =>102{
103// Enable the /metrics page to export Prometheus metrics.104// Open http://localhost:5283/metrics to see the metrics.105//106// Metrics published in this sample:107// * metrics about requests handled by the web app (configured above)108// * custom metrics about long-running operations, defined above109//110// To try out the expiration feature, navigate to different pages of the app (e.g. between Home and Privacy) and111// observe how the metrics for accessed URLs disappear a minute after the URL was last used.112endpoints.MapMetrics();113});114
115app.Run();116