Практическое руководство по настройке мониторинга приложения в Azure с Application Insights, Serilog и KQL.
Настройка Application Insights
Подключение к ASP.NET Core
// Program.cs
builder.Services.AddApplicationInsightsTelemetry();
// appsettings.json
{
"ApplicationInsights": {
"ConnectionString": "InstrumentationKey=xxx;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/"
}
}
Что собирается автоматически
После подключения Application Insights автоматически фиксирует:
- Все HTTP-запросы к вашему API (URL, время ответа, код статуса)
- Зависимости (SQL-запросы, HTTP-вызовы, Redis-операции)
- Необработанные исключения
- Метрики производительности (CPU, память)
- Связи между запросами (distributed tracing)
Structured Logging с Serilog
Serilog -- библиотека для структурированного логирования, интегрированная с Application Insights:
// Program.cs
builder.Host.UseSerilog((context, configuration) =>
{
configuration
.ReadFrom.Configuration(context.Configuration)
.WriteTo.Console()
.WriteTo.ApplicationInsights(
TelemetryConfiguration.Active,
TelemetryConverter.Traces)
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", "OrderManagement");
});
Правильное использование
// ПРАВИЛЬНО: structured logging с параметрами
_logger.LogInformation(
"Creating order for customer {CustomerId} with {ItemCount} items",
command.CustomerId,
command.Items.Count);
// НЕПРАВИЛЬНО: строковая конкатенация (теряются метаданные)
_logger.LogInformation(
$"Creating order for customer {command.CustomerId} with {command.Items.Count} items");
Structured logging сохраняет CustomerId и ItemCount как отдельные свойства, по которым можно фильтровать в KQL.
KQL-запросы для мониторинга
Производительность
// Топ-10 самых медленных API endpoints (P95)
requests
| where timestamp > ago(24h)
| summarize
avgDuration = avg(duration),
p95Duration = percentile(duration, 95),
requestCount = count()
by name
| order by p95Duration desc
| take 10
// Зависимости -- время отклика SQL и Redis
dependencies
| where timestamp > ago(1h)
| summarize
avg(duration),
percentile(duration, 95),
count()
by target, type
| order by avg_duration desc
Ошибки
// Ошибки за последние 24 часа по типам
exceptions
| where timestamp > ago(24h)
| summarize count() by type, outerMessage
| order by count_ desc
// Процент ошибок по эндпоинтам
requests
| where timestamp > ago(1h)
| summarize
total = count(),
failed = countif(success == false)
by name
| extend errorRate = round(100.0 * failed / total, 2)
| where errorRate > 0
| order by errorRate desc
Бизнес-метрики
// Количество заказов в час
customEvents
| where name == "OrderCreated" and timestamp > ago(24h)
| summarize orderCount = count() by bin(timestamp, 1h)
| render timechart
// End-to-end трассировка запроса
let operationId = "abc123";
union requests, dependencies, exceptions, traces
| where operation_Id == operationId
| order by timestamp asc
| project timestamp, itemType, name, duration, success, message
Настройка алертов
# Алерт: > 10 ошибок 5xx за 5 минут
az monitor metrics alert create \
--name "HighErrorRate" \
--resource-group rg-orderapp-dev \
--scopes "/subscriptions/{sub}/resourceGroups/rg-orderapp-dev/providers/Microsoft.Web/sites/orderapp-dev-app" \
--condition "count requests/failed > 10" \
--window-size 5m \
--evaluation-frequency 1m \
--severity 1 \
--action "/subscriptions/{sub}/resourceGroups/rg-orderapp-dev/providers/microsoft.insights/actionGroups/team-alerts"
# Алерт: среднее время ответа > 3 секунды
az monitor metrics alert create \
--name "HighLatency" \
--resource-group rg-orderapp-dev \
--scopes "..." \
--condition "avg requests/duration > 3000" \
--window-size 5m
Availability Tests
Проверка доступности вашего приложения из нескольких точек мира:
az monitor app-insights web-test create \
--resource-group rg-orderapp-dev \
--app-insights-name orderapp-dev-insights \
--web-test-name "Health Check" \
--location "West Europe" \
--url "https://orderapp-dev-app.azurewebsites.net/health" \
--frequency 300 \
--timeout 30
Health Checks
Endpoint /health проверяет все зависимости вашего приложения:
builder.Services.AddHealthChecks()
.AddSqlServer(connectionString, name: "sql")
.AddAzureBlobStorage(blobConnectionString, name: "blob")
.AddRedis(redisConnectionString, name: "redis");
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
Dashboard
Создание мониторинг-панели в Azure Portal:
- Azure Portal -> Dashboard -> New Dashboard
- Добавить виджеты:
- Application Map -- визуальная карта зависимостей
- Request Rate & Duration -- количество и время запросов
- Failed Requests -- количество ошибок
- Server Response Time -- время ответа сервера
- Dependencies Duration -- время зависимостей (SQL, Redis)
- Custom Metrics -- бизнес-метрики (OrderCreated count)
Рекомендации для production
- Structured Logging -- всегда параметры через
{Placeholder}, не строковая конкатенация - Distributed Tracing -- включите W3C Trace Context для отслеживания запросов между сервисами
- Sampling -- настройте сэмплирование для снижения объема данных и стоимости
- Retention -- по умолчанию 90 дней, настройте под ваши требования
- Alerts -- настройте алерты на ключевые метрики ДО появления проблем
- Health Checks -- endpoint
/healthс проверкой всех зависимостей