DevOps for 24 .NET Microservices: Prometheus Metrics + GitHub Actions CI/CD

DevOps for 24 .NET Microservices: Prometheus Metrics + GitHub Actions CI/CD

Source: Dev.to

How I set up advanced Prometheus metrics for 24 .NET microservices, automated CI/CD via GitHub Actions. From health checks to full observability. ## From health checks to full observability ## Step 1: Advanced Prometheus metrics in .NET + SQL ## Step 2: GitHub Actions CI/CD for 24 services ## Step 3: Production stack (Windows services) ## Grafana dashboards (SQL business metrics) ## Evolution results ## Additional DevOps experience ## Code in repository In the previous article, I already set up health checks in all 24 microservices, ready for Prometheus/Grafana. But the client needed full metrics: Added prometheus-net.AspNetCore NuGet to each microservice: // Program.cs of each microservice (.NET 8) var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddHealthChecks(); builder.Services.AddHttpClientMetrics(); var app = builder.Build(); app.UseRouting(); app.MapControllers(); app.MapHealthChecks("/health"); // Advanced HTTP metrics app.UseHttpMetrics(); app.MapMetrics("/metrics"); // Prometheus scrapes here Key metrics exposed on /metrics: HTTP metrics (automatic) http_requests_total_total{method="GET", endpoint="/api/applications", status="200"} http_request_duration_seconds{quantile="0.95"} .NET runtime dotnet_total_memory_bytes SQL metrics (via sql_exporter) mssql_locks_wait_count_total mssql_query_stats_total_duration_ms mssql_database_size_bytes sql_exporter for specific MSSQL business metrics: prometheus.yml scrape_configs: job_name: 'mssql' static_configs: targets: ['sql_exporter:9187'] metrics_path: /metrics Single pipeline with matrix strategy: name: CI/CD Microservices on: push: branches: [ main ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: build-push: needs: test runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' strategy: matrix: service: Prometheus + Grafana configured as Windows services — auto-start on server reboot: ✅ Prometheus (Windows Service) — scrapes /metrics from all 24 services + sql_exporter ✅ Grafana (Windows Service) — dashboards with auto-login for client ✅ Nginx (Windows Service) — reverse proxy ✅ MSSQL + sql_exporter — SQL business metrics prometheus.yml (full scraping): scrape_configs: job_name: 'microservices' static_configs: 'application-service:80' ... all 24 services metrics_path: /metrics job_name: 'mssql' static_configs: targets: ['sql_exporter:9187'] SQL metrics visualization in Grafana: 📊 HTTP Overview ├── Requests/sec by services ├── P95 latency └── Error rates 📊 SQL Business Metrics (sql_exporter) ├── Database size (line chart) ├── Lock wait times (gauge) ├── Query duration TOP-10 (table) └── Business KPIs (pie charts): ├─ Jobs completed today ├─ Active sessions by status └─ Queue processing distribution ✅ Health checks → Full metrics — HTTP + .NET + SQL ✅ Automated CI/CD — 24 services in 5 minutes ✅ Production services — Prometheus/Grafana auto-start ✅ SQL business metrics — sql_exporter + pie charts in Grafana Health Checks → HTTP Metrics → sql_exporter → Grafana Pie Charts ↓ GitHub Actions → Docker → Windows Services (Prometheus + Grafana) https://github.com/belochka1-04/WebApi_microservices/tree/main/ 📁 devops/ ├── prometheus.yml (24 services + sql_exporter) ├── .github/workflows/ci-cd.yml ├── docker-compose.prod.yml └── windows-services/ (Prometheus + Grafana setup) Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse - request counts by endpoints and status codes - P95/P99 response times - memory/CPU usage per service - specific SQL metrics for internal business processes - automated CI/CD pipeline - uses: actions/checkout@v4 - name: Setup .NET 8 uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - name: Test All Services run: | dotnet restore dotnet test --no-restore --collect:"XPlat Code Coverage" - ApplicationService - AuthService # ... remaining 21 services steps: - uses: actions/checkout@v4 - name: Build & Push Docker uses: docker/build-push-action@v5 with: context: ./src/${{ matrix.service }} push: true tags: myregistry/${{ matrix.service }}:latest - sql_exporter for MSSQL business metrics - Windows Services for Prometheus/Grafana - Grafana pie charts for KPI dashboards - GitHub Actions matrix (24 parallel builds) - app.UseHttpMetrics() — 2 lines of code - sql_exporter — ready-made SQL metrics out of the box