Skip to main content

Introducing Prometheus

The .NET Aspire Dashboard is decent if you are just getting started, but it is not storing any data on disk. All the .NET Aspire Dashboard's data is stored in memory and when the memory is refreshed all the data is lost. We also can't do any alerting or very complex dashboards with the built in interface. That's why we will introduce two tools into our system. Prometheus and Grafana. Let's start with Prometheus.

Prometheus is an open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.

We could install it locally, but we will leverage .NET Aspire's capabilities to run it on demand.

First create a folder called prometheus on the root level of your repository. Then create a file called prometheus.yml and paste the following code in it:

global:
scrape_interval: 1s # For the love of god don't set it that low in production. We are just using it for demo purposes

scrape_configs:
- job_name: 'dometrain-api'
metrics_path: '/metrics'
static_configs:
- targets: ['host.docker.internal:5148'] # hard-coded port matches launchSettings.json

This is the configuration we will use for Prometheus. In order for Aspire to expose those metrics to Prometheus we need to configure it in the ServiceDefaults project.

First we need to add the Nuget package OpenTelemetry.Exporter.Prometheus.AspNetCore.

Then we need to uncomment the following lines in Extensions.cs:

// AddOpenTelemetryExporters
builder.Services.AddOpenTelemetry().WithMetrics(metrics => metrics.AddPrometheusExporter());


// MapDefaultEndpoints
app.MapPrometheusScrapingEndpoint();

Now, there is a bit of a bug with the Prometheus exporter which we have to fix but adding a bit of configuration:

// AddOpenTelemetryExporters
builder.Services.AddOpenTelemetry().WithMetrics(metrics =>
metrics.AddPrometheusExporter(options => options.DisableTotalNameSuffixForCounters = true));

Once we add these lines we also need to add the prometheus container in the AppHost. We can do that like this:

builder.AddContainer("prometheus", "prom/prometheus")
.WithBindMount("../../prometheus", "/etc/prometheus", isReadOnly: true)
.WithHttpEndpoint(port: 9090, targetPort: 9090);

And that's it. We can now run our app and access the /metrics endpoint to see the exposed metrics.

But metrics are not good without a way to visualize them. That's where Grafana comes in!