Introduction: Why Monitoring C# Applications is an Art
In modern C# (.NET) development, monitoring has ceased to be just an option. It is a mandatory element of a production environment that allows not only to record failures but also to predict them. At an advanced level, monitoring turns into an early warning system: you don't just look at dashboards, but configure alerts based on complex metrics.
In this article, we will look at how to go beyond standard CPU and memory counters. You will learn how to collect custom business metrics, configure alerts using Prometheus and Alertmanager, and use OpenTelemetry for tracing. All examples will be in C#.
1. Advanced Instrumentation: App Metrics and Prometheus
1.1. Connecting Prometheus to ASP.NET Core
Basic monitoring in .NET is often limited to the built-in PerformanceCounter. However, for a microservice architecture, Prometheus has become the standard. Install the package:
dotnet add package prometheus-net.AspNetCoreThen add the middleware in Program.cs:
using Prometheus;
var builder = WebApplication.CreateBuilder(args);var app = builder.Build();
// Enable the metrics endpointapp.UseHttpMetrics();app.UseRouting();app.MapMetrics(); // /metrics
app.Run();This will give you basic metrics: request count, duration, errors. But for an advanced level, this is not enough.
1.2. Custom Business Metrics
Suppose you want to track the number of created orders or the execution time of a critical business operation. Use Counter and Histogram:
using Prometheus;
public class OrderMetrics{ private static readonly Counter OrdersCreated = Metrics .CreateCounter("orders_created_total", "Total number of created orders");
private static readonly Histogram OrderProcessingTime = Metrics .CreateHistogram("order_processing_seconds", "Histogram of order processing time");
public void RecordOrderCreation(double elapsedSeconds) { OrdersCreated.Inc(); OrderProcessingTime.Observe(elapsedSeconds); }}Now in any service you can inject OrderMetrics and record data. This will allow you to build dashboards in Grafana with second-level precision.
2. Alerts: From Simple Triggers to SLO-Oriented Rules
2.1. Configuring Alertmanager for C# Metrics
Collecting metrics is half the battle. The other half is alerts. Create a rule for Prometheus (alerts.yml):
groups: - name: csharp_app_alerts rules: - alert: HighErrorRate expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05 for: 2m labels: severity: critical annotations: summary: "High error rate in C# app" description: "Error rate is {{ $value }} for the last 5 minutes"This is a basic example. At an advanced level, you should add SLO alerts. For example, if 99% of requests do not fit within 200 ms, it's a reason to panic.
2.2. Alerts Based on Business Metrics
Use the custom counters from the previous section. If the number of orders has dropped sharply, it means something is broken:
- alert: OrdersStopped expr: rate(orders_created_total[10m]) == 0 for: 5m labels: severity: warning annotations: summary: "No orders created in last 10 minutes"Such an alert cannot be obtained from standard OS metrics — it requires a deep understanding of business logic.
3. OpenTelemetry: Distributed Tracing in C#
3.1. Integrating the OpenTelemetry SDK
When you have 10 microservices in C#, individual metrics won't help. You need tracing. Inst