Monitoring C# Applications: Metrics and Alerts from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Monitoring is Critical for C# Applications

\n\n

In modern software development, writing code is only half the battle. For an application to run stably, quickly, and predictably, constant monitoring is necessary. For C# (.NET) applications, which are often used in high-load enterprise systems, the banking sector, e-commerce, and cloud services, monitoring becomes not just an option, but a mandatory requirement.

\n\n

Without monitoring, you are working blindly: memory leaks go unnoticed until the server crashes, slow requests accumulate, and users leave for competitors. In this article, we will cover the full cycle of setting up observability for C# applications: from collecting basic metrics to configuring smart alerts in real time.

\n\n

1. Monitoring Basics: Which Metrics to Collect in .NET

\n\n

Before setting up tools, it is important to understand which metrics are truly important for C# applications. We will divide them into three groups:

\n\n

1.1. System Metrics (Infrastructure Level)

\n
    \n
  • CPU and Memory — processor load and RAM consumption of the dotnet process.
  • \n
  • GC (Garbage Collection) — frequency and duration of garbage collections, heap sizes (Gen0, Gen1, Gen2, LOH).
  • \n
  • Thread Pool — number of active, idle, and waiting threads.
  • \n
  • Disk I/O and Network — disk read/write, network connections.
  • \n
\n\n

1.2. Business Metrics (Application Level)

\n
    \n
  • Request Rate — number of requests per second (RPS).
  • \n
  • Latency — response time (p50, p95, p99 percentiles).
  • \n
  • Error Rate — percentage of 4xx and 5xx errors.
  • \n
  • Active Users — number of concurrently active users.
  • \n
\n\n

1.3. .NET Runtime Metrics

\n
    \n
  • JIT Compilation — method compilation time.
  • \n
  • Assembly Loading — number of loaded assemblies.
  • \n
  • Exceptions — number of thrown exceptions per second.
  • \n
\n\n

To collect these metrics in .NET, a powerful tool is used — System.Diagnostics.Metrics (built-in API since .NET 6+) and the OpenTelemetry library.

\n\n

2. Setting Up Metric Collection with OpenTelemetry and Prometheus

\n\n

The best way to organize monitoring for a C# application is to use the combination of OpenTelemetry (metric collection) + Prometheus (storage) + Grafana (visualization). Let's look at the step-by-step setup.

\n\n

2.1. Installing NuGet Packages

\n

Add the following packages to your project:

\n
dotnet add package OpenTelemetry.Extensions.Hosting\ndotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore\ndotnet add package OpenTelemetry.Instrumentation.AspNetCore\ndotnet add package OpenTelemetry.Instrumentation.Runtime
\n\n

2.2. Configuration in Program.cs

\n

Configure OpenTelemetry to automatically collect metrics from ASP.NET Core and .NET Runtime:

\n
using OpenTelemetry.Metrics;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddOpenTelemetry()\n    .WithMetrics(metrics => metrics\n        .AddAspNetCoreInstrumentation() // HTTP request metrics\n        .AddRuntimeInstrumentation()    // GC, JIT, ThreadPool metrics\n        .AddPrometheusExporter());      // export to Prometheus\n\nvar app = builder.Build();\n\napp.UseOpenTelemetryPrometheusScrapingEndpoint(); // /metrics endpoint\n\napp.Run();
\n\n

Now, at http://localhost:5000/metrics, an endpoint with metrics in Prometheus format will be available.

\n\n

2.3. Creating Custom Metrics

\n

Let's add a business metric — a counter for processed orders:

\n
public class OrderMetrics\                

Blogs

Book Recommendations