Мониторинг приложений C# (.NET): Полный гайд по OpenTelemetry и Prometheus
Современные .NET-приложения требуют постоянного наблюдения за производительностью, ошибками и состоянием. Без мониторинга вы рискуете потерять контроль над продакшеном. В этой статье мы разберем, как настроить эффективный мониторинг C# (.NET) приложений с использованием связки OpenTelemetry (сбор телеметрии) и Prometheus + Grafana (визуализация и алертинг).
Почему именно OpenTelemetry?
OpenTelemetry (OTel) — это индустриальный стандарт для сбора метрик, трейсов (трассировок) и логов. Для .NET он предоставляет официальные SDK и автоматическую инструментацию популярных библиотек (ASP.NET Core, gRPC, Entity Framework).
Установка и настройка OpenTelemetry в проекте C#
Добавьте NuGet-пакеты в ваш проект:
dotnet add package OpenTelemetry
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore
Базовая конфигурация в Program.cs
Настройте сбор метрик и экспорт в Prometheus:
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
.AddService("MyApp", serviceVersion: "1.0.0"))
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddMeter("Microsoft.AspNetCore.Hosting")
.AddMeter("Microsoft.AspNetCore.Server.Kestrel")
.AddPrometheusExporter());
var app = builder.Build();
// Эндпоинт для Prometheus (по умолчанию /metrics)
app.MapPrometheusScrapingEndpoint();
app.Run();
Создание пользовательских метрик
Вы можете добавить свои счетчики, гистограммы и датчики:
using System.Diagnostics.Metrics;
public class OrderMetrics
{
private readonly Counter<int> _ordersCreated;
private readonly Histogram<double> _orderProcessingTime;
public OrderMetrics(IMeterFactory meterFactory)
{
var meter = meterFactory.Create("MyApp.Orders");
_ordersCreated = meter.CreateCounter<int>("orders.created", description: "Количество созданных заказов");
_orderProcessingTime = meter.CreateHistogram<double>("orders.processing_time", unit: "ms");
}
public void RecordOrderCreated() => _ordersCreated.Add(1);
public void RecordProcessingTime(double ms) => _orderProcessingTime.Record(ms);
}
Трассировка запросов (Distributed Tracing)
Для отслеживания цепочек вызовов добавьте трейсинг:
using OpenTelemetry.Trace;
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddEntityFrameworkCoreInstrumentation()
.AddConsoleExporter()); // Для отладки, в продакшене — Jaeger или Zipkin
Логирование через OpenTelemetry
Подключите логгер к OTel:
using OpenTelemetry.Logs;
builder.Logging.AddOpenTelemetry(logging => logging
.AddConsoleExporter()
.AddOtlpExporter(options => options.Endpoint = new Uri("http://localhost:4317")));
Настройка Prometheus для сбора метрик
В файле prometheus.yml укажите ваш эндпоинт:
scrape_configs:
- job_name: 'dotnet-app'
scrape_interval: 5s
static_configs:
- targets: ['localhost:5000'] # Порт вашего приложения
Визуализация в Grafana
После подключения Prometheus к Grafana создайте дашборд с ключевыми метриками:
- http_server_duration_ms — время ответа сервера
- process_cpu_seconds_total — загрузка CPU
- dotnet_total_memory_bytes — потребление памяти
- kestrel_active_connections — активные соединения
Алертинг и оповещения
Настройте правила в Prometheus для критических ситуаций:
groups:
- name: dotnet-alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_failed_total[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Высокий уровень ошибок ({{ $value }}%)"