Мониторинг C# приложений: метрики и алерты от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему мониторинг критичен для C# приложений

В современной разработке программного обеспечения написать код — это лишь половина дела. Чтобы приложение работало стабильно, быстро и предсказуемо, необходим постоянный мониторинг. Для C# (.NET) приложений, которые часто используются в высоконагруженных корпоративных системах, банковском секторе, e-commerce и облачных сервисах, мониторинг становится не просто опцией, а обязательным требованием.

Без мониторинга вы работаете вслепую: утечки памяти остаются незамеченными до падения сервера, медленные запросы накапливаются, а пользователи уходят к конкурентам. В этой статье мы разберем полный цикл настройки наблюдаемости (observability) для C# приложений: от сбора базовых метрик до настройки умных алертов в реальном времени.

1. Основы мониторинга: какие метрики собирать в .NET

Прежде чем настраивать инструменты, важно понять, какие метрики действительно важны для C# приложений. Мы разделим их на три группы:

1.1. Системные метрики (уровень инфраструктуры)

  • CPU и Memory — загрузка процессора и потребление оперативной памяти процессом dotnet.
  • GC (Garbage Collection) — частота и длительность сборок мусора, размер куч (Gen0, Gen1, Gen2, LOH).
  • Thread Pool — количество активных, свободных и ожидающих потоков.
  • Disk I/O и Network — чтение/запись на диск, сетевые подключения.

1.2. Бизнес-метрики (уровень приложения)

  • Request Rate — количество запросов в секунду (RPS).
  • Latency — время ответа (p50, p95, p99 перцентили).
  • Error Rate — процент 4xx и 5xx ошибок.
  • Active Users — количество одновременно работающих пользователей.

1.3. Метрики .NET Runtime

  • JIT Compilation — время компиляции методов.
  • Assembly Loading — количество загруженных сборок.
  • Exceptions — количество выброшенных исключений в секунду.

Для сбора этих метрик в .NET используется мощный инструмент — System.Diagnostics.Metrics (встроенный API с .NET 6+) и библиотека OpenTelemetry.

2. Настройка сбора метрик с помощью OpenTelemetry и Prometheus

Лучший способ организовать мониторинг C# приложения — использовать связку OpenTelemetry (сбор метрик) + Prometheus (хранение) + Grafana (визуализация). Рассмотрим пошаговую настройку.

2.1. Установка пакетов NuGet

Добавьте в проект следующие пакеты:

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

2.2. Конфигурация в Program.cs

Настройте OpenTelemetry для автоматического сбора метрик ASP.NET Core и .NET Runtime:

using OpenTelemetry.Metrics;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation() // метрики HTTP запросов
        .AddRuntimeInstrumentation()    // метрики GC, JIT, ThreadPool
        .AddPrometheusExporter());      // экспорт в Prometheus

var app = builder.Build();

app.UseOpenTelemetryPrometheusScrapingEndpoint(); // эндпоинт /metrics

app.Run();

Теперь по адресу http://localhost:5000/metrics будет доступен эндпоинт с метриками в формате Prometheus.

2.3. Создание пользовательских метрик

Добавим бизнес-метрику — счетчик обработанных заказов:

public class OrderMetrics
{
    private readonly Counter<int> _ordersProcessed;
    
    public OrderMetrics(IMeterFactory meterFactory)
    {
        var meter = meterFactory.Create("MyApp.Orders");
        _ordersProcessed = meter.CreateCounter<int>("orders.processed");
    }
    
    public void OrderProcessed(string status)
    {
        _ordersProcessed.Add(1, new KeyValuePair<string, object?>("status", status));
    }
}

// В контроллере:
public class OrderController : ControllerBase
{
    private readonly OrderMetrics _metrics;
    
    [HttpPost]
    public IActionResult CreateOrder()
    {
        // ... бизнес-логика
        _metrics.OrderProcessed("success");
        return Ok();
    }
}

3. Настройка алертов: от простых правил до умных порогов

Метрики бесполезны без алертов. Рассмотрим настройку оповещений на примере Prometheus Alertmanager и встроенных Health Checks в .NET.

3.1. Базовые алерты в Prometheus

Пример правил для файла alerts.yml:

groups:
  - name: dotnet_alerts
    rules:
      - alert: HighMemoryUsage
        expr: process_runtime_dotnet_memory_working_set > 500 * 1024 * 1024
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High memory usage ({{ $value }} MB)"

      - alert: HighErrorRate
        expr: rate(http_server_duration_seconds_count{status_code=~"5.."}[5m]) > 0.05
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Error rate above 5%"

      - alert: GarbageCollectionPause
        expr: rate(dotnet_gc_pause_time_ticks[1m]) > 1000000
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "GC pause time too high"

3.2. Health Checks в .NET

Встроенный механизм Health Checks позволяет проверять зависимости приложения (БД, кэш, внешние API):

// Program.cs
builder.Services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>()
    .AddUrlGroup(new Uri("https://api.example.com"), "External API");

app                

Блоги

Рекомендаций по книгам