DEV Community

Cover image for Track Spotify Metrics: Use Docker with Prometheus and Grafana
Atahan C.
Atahan C.

Posted on

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");

Enter fullscreen mode Exit fullscreen mode

// 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);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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");        
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

winamptospotifyweb.spotifyservice.totaltracksadded metric exported to Aspire Dashboard, Prometheus and Grafana.

Aspire Dashboard

Prometheus

Grafana

Code changes can be found dotnet aspire added and opentelemetry and metrics added commits.

Top comments (0)