Мониторинг приложений C# (.NET): от метрик до алертинга
Современные .NET-приложения требуют постоянного наблюдения за производительностью, доступностью и состоянием внутренних процессов. В этой статье мы рассмотрим ключевые инструменты для организации мониторинга: Prometheus для сбора метрик, OpenTelemetry для трассировки и Serilog для структурированного логирования. Вы узнаете, как внедрить observability (наблюдаемость) в ваше C#-приложение.
Зачем нужен мониторинг .NET-приложений?
Отсутствие мониторинга превращает отладку в гадание. Без метрик вы не узнаете о росте времени ответа, без трейсов — не найдете узкое место в цепочке вызовов, без логов — не поймете причину ошибки. Правильно настроенный мониторинг позволяет:
- Обнаруживать аномалии до того, как они повлияют на пользователей.
- Анализировать производительность отдельных компонентов (базы данных, API, кэш).
- Собирать бизнес-метрики (количество заказов, активные сессии).
- Автоматизировать оповещения об инцидентах.
Инструменты для мониторинга .NET
Мы будем использовать три основных компонента:
- Prometheus — система сбора и хранения метрик с мощным языком запросов PromQL.
- OpenTelemetry — стандарт для сбора телеметрии (трейсы, метрики, логи).
- Serilog — библиотека структурированного логирования для .NET.
Шаг 1: Установка и настройка Prometheus с .NET
Для интеграции Prometheus с C# используйте пакет prometheus-net. Установите его через NuGet:
dotnet add package prometheus-net
Затем добавьте middleware в ваш Program.cs:
using Prometheus;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Включаем эндпоинт /metrics для Prometheus
app.UseHttpMetrics();
app.MapMetrics();
app.MapGet("/", () => "Hello World!");
app.Run();
После запуска приложения перейдите по адресу http://localhost:5000/metrics. Вы увидите стандартные метрики: http_requests_total, http_request_duration_seconds и другие.
Шаг 2: Создание пользовательских метрик
Часто нужно отслеживать бизнес-показатели. Например, количество обработанных заказов:
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();
}
}
// Использование в контроллере
[ApiController]
[Route("api/orders")]
public class OrdersController : ControllerBase
{
[HttpPost]
public IActionResult CreateOrder()
{
// ... логика создания заказа
OrderMetrics.RecordOrder();
return Ok();
}
}
Теперь в /metrics появится строка orders_processed_total 1.
Шаг 3: Трассировка с OpenTelemetry
Трассировка помогает понять, сколько времени занимает каждый этап обработки запроса. Установите пакеты:
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Exporter.Console
Настройте OpenTelemetry в Program.cs:
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation()
.AddConsoleExporter());
var app = builder.Build();
app.Run();
Теперь каждый HTTP-запрос будет автоматически создавать трейс с информацией о времени выполнения. Для экспорта в более мощные системы (Jaeger, Zipkin) замените AddConsoleExporter на соответствующий экспортер.
Шаг 4: Структурированное логирование с Serilog
Serilog позволяет писать логи в формате JSON, что упрощает их анализ через Elasticsearch или Logstash. Установите:
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
Конфигурация в Program.cs:
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console(new Serilog.Formatting.Compact.RenderedCompactJsonFormatter())
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host