This is a .NET library for instrumenting your applications and exporting metrics to Prometheus.
The library targets .NET Standard 2.0 which supports the following runtimes (and newer):
- .NET Framework 4.6.1
- .NET Core 2.0
- Mono 5.4
Nuget package for general use and metrics export via HttpListener or to Pushgateway: prometheus-net
Install-Package prometheus-net
Nuget package for ASP.NET Core middleware and stand-alone Kestrel metrics server: prometheus-net.AspNetCore
Install-Package prometheus-net.AspNetCore
To make the library easier to maintain and deliver, version 2.0 introduces some breaking changes:
- Target .NET Standard 2.0 and runtimes that support it - .NET Core 2.0 and .NET Framework 4.6.1. Older runtimes are no longer supported.
- Some classes have been renamed. For example, MetricServer used to be Kestrel-based on .NET Core and HttpListener-based on .NET Framework but in 2.0 it always uses HttpListener, with KestrelHttpServer being a Kestrel-specific server.
- Minor breaking API changes to tidy up confusing parts of the API surface and make it easier to integrate the library.
- Removed dependency on Reactive Extensions. Builtin async/await/Task mechanics are now used.
- Removed PerfCounterCollector as it was mostly obsolete and the removal simplifies maintenance work.
If you are migrating from version 1.x, you may need to make minor changes to your code to adjust for these changes.
Four types of metric are offered: Counter, Gauge, Summary and Histogram. See the documentation on metric types and instrumentation best practices on how to use them.
Counters go up, and reset when the process restarts.
var counter = Metrics.CreateCounter("myCounter", "some help about this");
counter.Inc(5.5);
Gauges can go up and down.
var gauge = Metrics.CreateGauge("gauge", "help text");
gauge.Inc(3.4);
gauge.Dec(2.1);
gauge.Set(5.3);
Summaries track the size and number of events.
var summary = Metrics.CreateSummary("mySummary", "help text");
summary.Observe(5.3);
Histograms track the size and number of events in buckets. This allows for aggregatable calculation of quantiles.
var hist = Metrics.CreateHistogram("my_histogram", "help text", new HistogramConfiguration
{
Buckets = new[] { 0, 0.2, 0.4, 0.6, 0.8, 0.9 }
});
hist.Observe(0.4);
The default buckets (used when you do not specify your own) are intended to cover a typical web/rpc request from milliseconds to seconds.
All metrics can have labels, allowing grouping of related time series.
See the best practices on naming and labels.
Taking a counter as an example:
var counter = Metrics.CreateCounter("myCounter", "help text", new CounterConfiguration
{
LabelNames = new[] { "method", "endpoint" }
});
counter.WithLabels("GET", "/").Inc();
counter.WithLabels("POST", "/cancel").Inc();
Metrics without labels are published immediately. Metrics that use labels are published when you provide the label values.
Sometimes you want to delay publishing a metric until you have loaded some data and have a meaningful value to supply for it. The API allows you to suppress publishing of the initial value until you decide the time is right.
var gauge = Metrics.CreateGauge("logged_in_users ", "help text", new GaugeConfiguration
{
SuppressInitialValue = true
});
// After setting the value, the metric becomes published.
gauge.Set(LoadSessions().Count);
You can also use .Publish()
on a metric to mark it as ready to be published without modifying the initial value.
Metrics are usually exposed over HTTP, to be read by the Prometheus server. The default metric server uses HttpListener to open up an HTTP API for metrics export.
var metricServer = new MetricServer(port: 1234);
metricServer.Start();
The default configuration will publish metrics on the /metrics URL.
MetricServer.Start()
may throw an access denied exception on Windows if your user does not have the right to open a web server on the specified port. You can use the netsh command to grant yourself the required permissions:
netsh http add urlacl url=http://+:1234/metrics user=DOMAIN\user
Metrics can be posted to a Pushgateway server over HTTP.
var metricServer = new MetricPusher(endpoint: "http://pushgateway.example.org:9091/metrics", job: "some_job");
metricServer.Start();
For projects built with ASP.NET Core, a middleware plugin is provided.
If you use the default Visual Studio project template, modify Startup.cs as follows:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseMetricServer();
app.Run(async (context) =>
{
// ...
});
}
Alternatively, if you use a custom project startup cycle, you can add this directly to the WebHostBuilder instance:
WebHost.CreateDefaultBuilder()
.Configure(app => app.UseMetricServer())
.Build()
.Run();
The default configuration will publish metrics on the /metrics URL.
This functionality is delivered in the prometheus-net.AspNetCore
NuGet package.
You may wish to restrict access to the metrics export URL. This can be accomplished using any ASP.NET Core authentication mechanism, as prometheus-net integrates directly into the composable ASP.NET Core request processing pipeline.
For a simple example we can take BasicAuthMiddleware by Johan Boström which can be integrated by replacing the app.UseMetricServer()
line with the following code block:
app.Map("/metrics", metricsApp =>
{
metricsApp.UseMiddleware<BasicAuthMiddleware>("Contoso Corporation");
// We already specified URL prefix in .Map() above, no need to specify it again here.
metricsApp.UseMetricServer("");
});
In some situation, you may theoretically wish to start a stand-alone metric server using Kestrel instead of HttpListener.
var metricServer = new KestrelMetricServer(port: 1234);
metricServer.Start();
The default configuration will publish metrics on the /metrics URL.
This functionality is delivered in the prometheus-net.AspNetCore
NuGet package.
The library provides some sample metrics about the current process out of the box. If these are not desirable you may suppress them by calling DefaultCollectorRegistry.Instance.Clear()
before registering any of your own metrics.
In some scenarios you may want to only collect data when it is requested by Prometheus. To easily implement this scenario prometheus-net provides you the ability to perform on-demand collection by implementing the IOnDemandCollector interface.
Objects that implement this interface are informed before every collection, allowing you to perform any data updates that are relevant. To register on-demand collectors, use DefaultCollectorRegistry.Instance.RegisterOnDemandCollectors()
.
For an example implementation, see OnDemandCollection.cs.
For even more fine-grained control over exported data you should implement a custom collector (see below).
The built-in collectors created via the Metrics
class helper methods provide a simple way to export basic metric types to Prometheus. To implement more advanced metric collection scenarios you can implement the ICollector
interface yourself.
For an example, see ExternalDataCollector.cs.