Monitoring C# (.NET) Applications: From Metrics to Alerting
Modern .NET applications require constant monitoring of performance, availability, and the state of internal processes. In this article, we will explore key tools for organizing monitoring: Prometheus for collecting metrics, OpenTelemetry for tracing, and Serilog for structured logging. You will learn how to implement observability in your C# application.
Why Monitor .NET Applications?
Lack of monitoring turns debugging into guesswork. Without metrics, you won't know about increased response times; without traces, you won't find the bottleneck in the call chain; without logs, you won't understand the cause of an error. Properly configured monitoring allows you to:
- Detect anomalies before they affect users.
- Analyze the performance of individual components (databases, APIs, cache).
- Collect business metrics (number of orders, active sessions).
- Automate incident alerts.
Tools for Monitoring .NET
We will use three main components:
- Prometheus — a system for collecting and storing metrics with a powerful PromQL query language.
- OpenTelemetry — a standard for collecting telemetry (traces, metrics, logs).
- Serilog — a structured logging library for .NET.
Step 1: Installing and Configuring Prometheus with .NET
To integrate Prometheus with C#, use the prometheus-net package. Install it via NuGet:
dotnet add package prometheus-netThen add middleware to your Program.cs:
using Prometheus;
var builder = WebApplication.CreateBuilder(args);var app = builder.Build();
// Enable the /metrics endpoint for Prometheusapp.UseHttpMetrics();app.MapMetrics();
app.MapGet("/", () => "Hello World!");app.Run();After starting the application, navigate to http://localhost:5000/metrics. You will see standard metrics: http_requests_total, http_request_duration_seconds, and others.
Step 2: Creating Custom Metrics
Often you need to track business indicators. For example, the number of processed orders:
using Prometheus;
public class OrderMetrics{ private static readonly Counter OrdersCounter = Metrics .CreateCounter("orders_processed_total", "Total number of processed orders");
public static void RecordOrder() { OrdersCounter.Inc(); }}
// Usage in a controller[ApiController][Route("api/orders")]public class OrdersController : ControllerBase{ [HttpPost] public IActionResult CreateOrder() { // ... order creation logic OrderMetrics.RecordOrder(); return Ok(); }}Now the /metrics endpoint will show the line orders_processed_total 1.
Step 3: Tracing with OpenTelemetry
Tracing helps understand how much time each stage of request processing takes. Install the packages:
dotnet add package OpenTelemetry.Extensions.Hostingdotnet add package OpenTelemetry.Instrumentation.AspNetCoredotnet add package OpenTelemetry.Exporter.ConsoleConfigure OpenTelemetry in Program.cs:
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry() .WithTracing(tracing => tracing .AddAspNetCoreInstrumentation() .AddConsoleExporter());
var app = builder.Build();app.Run();Now every HTTP request will automatically create a trace with execution time information. For export
Also in library
Authorization and Authentication in PHP: A Complete Guide with Examples
Working with S3 and Cloud Storage in C++: AWS SDK for C++ Library
Working with CSV in PHP: PhpSpreadsheet Library
Working with XML in PHP: Parsing, Creating, and Processing Data
Authorization and Authentication in C# (.NET) — Complete Guide