After adding .Net Aspire Service Defaults and .Net Aspire AppHost to WinampToSpotify project I have added following code to run Prometheus and Grafana on local with Docker Desktop. Docker Desktop is required to run to start code below.
// Prometheus container scraping the app
var prometheus = builder.AddContainer("prometheus", "prom/prometheus")
.WithBindMount("./prometheus/prometheus.yml", "/etc/prometheus/prometheus.yml")
.WithEndpoint(port: 9090, targetPort: 9090)
.WithArgs("--config.file=/etc/prometheus/prometheus.yml",
"--web.enable-otlp-receiver");
// Grafana container using Prometheus as data source
var grafana = builder.AddContainer("grafana", "grafana/grafana")
.WithVolume("grafana-storage", "/var/lib/grafana") // Persists dashboards, users, DB
.WithVolume("grafana-provisioning", "/etc/grafana/provisioning", isReadOnly: true) // Optional: Provisioning YAML/JSON
.WithEndpoint(port: 3000, targetPort: 3000);
prometheus.yml is the default prometheus configuration
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "otel-collector"
static_configs:
- targets: ["localhost:9090"] # Adjust if using Docker, e.g., host.docker.internal:9464
metrics_path: /metrics
I created OpenTelemetryLib project and created ServiceCollection extension method which configures OTEL export endpoints. OpenTelemetry, OpenTelemetry.Exporter.Console, OpenTelemetry.Exporter.OpenTelemetryProtocol, OpenTelemetry.Exporter.Prometheus.HttpListener, OpenTelemetry.Instrumentation.Process nuget packages installed.
var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(
ResourceBuilder.CreateDefault().AddService("winamptospotifyweb", serviceVersion: "1.0.0"))
.AddMeter(WinamptoSpotifyMetricsManager.MeterName)
.AddOtlpExporter((options, metricReader) =>
{
options.Protocol = OtlpExportProtocol.Grpc; // 4317 as the grpc port.
options.ExportProcessorType = ExportProcessorType.Batch;
options.Endpoint = endpoint;
metricReader.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 60000; // 1 minute
metricReader.PeriodicExportingMetricReaderOptions.ExportTimeoutMilliseconds = 30000; // half a minute
}) //Aspire Dashboard export
.AddOtlpExporter((exporterOptions, metricReaderOptions) =>
{
exporterOptions.Endpoint = new Uri("http://localhost:9090/api/v1/otlp/v1/metrics");
exporterOptions.Protocol = OtlpExportProtocol.HttpProtobuf;
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000;
}); //Prometheus export
Spotify metrics class created to register spotify service related metrics. I started to keep track number of total tracks added by each folder.
public class SpotifyServiceMetrics : IWinampToSpotifyWebMetrics
{
private readonly ISpotifyService _spotifyService;
public SpotifyServiceMetrics(ISpotifyService spotifyService)
{
_spotifyService = spotifyService;
}
public void RegisterMetrics(Meter meter)
{
var tracksAddedMetric = meter.CreateObservableGauge("winamptospotifyweb.spotifyservice.totaltracksadded", () => _spotifyService.GetPlaylistSummary().TotalTracksAdded,
"unitless", "Number of tracks added");
}
}
WinamptoSpotifyMetricsManager class helps to register metrics which uses IMeterFactory to register.
public WinamptoSpotifyMetricsManager(IEnumerable<IWinampToSpotifyWebMetrics> metrics, IMeterFactory meterFactory)
{
_metrics = metrics.ToImmutableList();
_meter = meterFactory.Create(new MeterOptions(MeterName));
}`
`/// <summary>
/// Registers all custom metrics contained within the WinampToSpotify instance.
/// </summary>
public void Start()
{
foreach (var metric in _metrics)
{
metric.RegisterMetrics(_meter);
}
}
winamptospotifyweb.spotifyservice.totaltracksadded metric exported to Aspire Dashboard, Prometheus and Grafana.
Code changes can be found dotnet aspire added and opentelemetry and metrics added commits.



Top comments (0)