Dec 29, 2025 programming

Track Spotify Metrics: Use Docker with Prometheus and Grafana

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 · atahanceylan/WinamptoSpotifyWeb@7bc4056 and opentelemetry and metrics added · atahanceylan/WinamptoSpotifyWeb@7373176 commits.

SHARE NOW

Leave a Reply

Your email address will not be published. Required fields are marked *