DEV Community

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

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

In the previous article, I already set up health checks in all 24 microservices, ready for Prometheus/Grafana.

But the client needed full metrics:

  • 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

Step 1: Advanced Prometheus metrics in .NET + SQL

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

Step 2: GitHub Actions CI/CD for 24 services

Single pipeline with matrix strategy:

name: CI/CD Microservices
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
steps:

  • 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"

build-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
strategy:
matrix:
service:

  • ApplicationService
  • JobService
  • 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

Step 3: Production stack (Windows services)

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:

targets:

'application-service:80'

'job-service:80'

... all 24 services
metrics_path: /metrics

job_name: 'mssql'
static_configs:

targets: ['sql_exporter:9187']

Grafana dashboards (SQL business metrics)

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

Evolution results

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)

Additional DevOps experience

🎯 New skills:

  • sql_exporter for MSSQL business metrics
  • Windows Services for Prometheus/Grafana
  • Grafana pie charts for KPI dashboards
  • GitHub Actions matrix (24 parallel builds)

✅ Worked perfectly:

  • app.UseHttpMetrics() — 2 lines of code
  • sql_exporter — ready-made SQL metrics out of the box

Code in repository

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)

Top comments (0)