perf: добавли энвы для управления скорость профилирования sentry
Create and publish a Docker image / Publish image (push) Successful in 8m31s

This commit is contained in:
2026-08-05 15:55:10 +03:00
parent 1974f36b24
commit 03560b0dc8
5 changed files with 59 additions and 28 deletions
+20 -16
View File
@@ -167,19 +167,21 @@ MVC-контроллеры из плагинов тоже подключаютс
### Ключевые переменные приложения
| Переменная | Обязательность | Значение по умолчанию | Где используется | Назначение |
| ------------------------- | --------------------------------------- | ------------------------------------------ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MODEUS_URL` | Нет | `https://sfedu.modeus.org/` | код | Базовый URL`Modeus` |
| `TOKEN` | Условно обязательна | нет | код | Готовый JWT для`Modeus`; если не задан, приложение попытается получить токен через `AUTH_URL` |
| `AUTH_URL` | Условно обязательна | `http://msauth:8080/auth/ms` | код | URL сервиса, который возвращает новый JWT |
| `AUTH_API_KEY` | Нет | пусто | код | API key для вызова`AUTH_URL`, передаётся как `X-API-Key` |
| `API_KEY` | Условно обязательна | нет | код | Ключ для маршрутов, защищённых схемой`ApiKey` |
| `UPDATE_JWT_CRON` | Нет | `0 0 4 ? * *` | код | Cron для фонового обновления JWT |
| `UPDATE_EMPLOYEES_CRON` | Нет | `0 0 6 ? * *` | код | Cron для фонового обновления индекса сотрудников |
| `PERMIT_LIMIT` | Нет | `40` | код | Лимит запросов в окне rate limiter |
| `TIME_LIMIT` | Нет | `10` | код | Длина окна rate limiter в секундах |
| `TZ` | Нет | `Europe/Moscow` | код | Таймзона для запросов к`Modeus` и генерации `ICS` |
| `Sentry:Dsn` | Нет | пустая строка | код | DSN для Sentry |
| Переменная | Обязательность | Значение по умолчанию | Где используется | Назначение |
| ----------------------------- | ------------------- | ---------------------------- | ---------------- | --------------------------------------------------------------------------------------------- |
| `MODEUS_URL` | Нет | `https://sfedu.modeus.org/` | код | Базовый URL`Modeus` |
| `TOKEN` | Условно обязательна | нет | код | Готовый JWT для`Modeus`; если не задан, приложение попытается получить токен через `AUTH_URL` |
| `AUTH_URL` | Условно обязательна | `http://msauth:8080/auth/ms` | код | URL сервиса, который возвращает новый JWT |
| `AUTH_API_KEY` | Нет | пусто | код | API key для вызова`AUTH_URL`, передаётся как `X-API-Key` |
| `API_KEY` | Условно обязательна | нет | код | Ключ для маршрутов, защищённых схемой`ApiKey` |
| `UPDATE_JWT_CRON` | Нет | `0 0 4 ? * *` | код | Cron для фонового обновления JWT |
| `UPDATE_EMPLOYEES_CRON` | Нет | `0 0 6 ? * *` | код | Cron для фонового обновления индекса сотрудников |
| `PERMIT_LIMIT` | Нет | `40` | код | Лимит запросов в окне rate limiter |
| `TIME_LIMIT` | Нет | `10` | код | Длина окна rate limiter в секундах |
| `TZ` | Нет | `Europe/Moscow` | код | Таймзона для запросов к`Modeus` и генерации `ICS` |
| `Sentry:Dsn` | Нет | пустая строка | код | DSN для Sentry |
| `SENTRY_TRACES_SAMPLE_RATE` | Нет | `1` | код | Доля трассировок Sentry от `0` до `1` |
| `SENTRY_PROFILES_SAMPLE_RATE` | Нет | `1` | код | Доля профилируемых трассировок от `0` до `1`; при `0` profiling-интеграция не запускается |
### Переменные для Microsoft / Azure AD
@@ -200,9 +202,9 @@ MVC-контроллеры из плагинов тоже подключаютс
### Переменные из docker-compose
| Переменная | Обязательность | Значение по умолчанию | Назначение |
| --------------------------------------- | ------------------------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `ASPNETCORE_FORWARDEDHEADERS_ENABLED` | Нет | нет | В compose выставляется в`true`, чтобы приложение корректнее работало за reverse proxy |
| Переменная | Обязательность | Значение по умолчанию | Назначение |
| ------------------------------------- | -------------- | --------------------- | ------------------------------------------------------------------------------------- |
| `ASPNETCORE_FORWARDEDHEADERS_ENABLED` | Нет | нет | В compose выставляется в`true`, чтобы приложение корректнее работало за reverse proxy |
### Что значит "условно обязательна"
@@ -236,6 +238,8 @@ TG_CHAT_ID=
TG_TOKEN=
SENTRY_DSN=
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0
AzureAd:Instance=https://login.microsoftonline.com/
AzureAd:TenantId=sfedu.ru
+6 -2
View File
@@ -13,7 +13,11 @@ public static class AppConsts
// RateLimiter
public const string PermitLimitEnv = "PERMIT_LIMIT";
public const string TimeLimitEnv = "TIME_LIMIT";
public const string TimeLimitEnv = "TIME_LIMIT";
// Sentry
public const string SentryTracesSampleRateEnv = "SENTRY_TRACES_SAMPLE_RATE";
public const string SentryProfilesSampleRateEnv = "SENTRY_PROFILES_SAMPLE_RATE";
// MS Auth
public const string AuthUrlEnv = "AUTH_URL";
@@ -23,4 +27,4 @@ public static class AppConsts
public const string JwtFileName = "jwt.txt";
public const string EmployeesFileName = "employees.json";
public const string DataFolderName = "data";
}
}
+23 -4
View File
@@ -1,6 +1,7 @@
using System.Net;
using System.Reflection;
using System.Threading.RateLimiting;
using System.Globalization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.DataProtection;
@@ -33,6 +34,8 @@ configuration["TZ"] ??= "Europe/Moscow";
var permitLimit = int.TryParse(configuration[AppConsts.PermitLimitEnv], out var parsedPermitLimit) ? parsedPermitLimit : 40;
var timeLimit = int.TryParse(configuration[AppConsts.TimeLimitEnv], out var parsedTimeLimit) ? parsedTimeLimit : 10;
var sentryTracesSampleRate = GetSampleRate(configuration, AppConsts.SentryTracesSampleRateEnv, 1.0);
var sentryProfilesSampleRate = GetSampleRate(configuration, AppConsts.SentryProfilesSampleRateEnv, 1.0);
#endregion
@@ -64,9 +67,11 @@ builder.WebHost.UseSentry(options =>
{
options.Dsn = configuration["Sentry:Dsn"] ?? "";
options.EnableLogs = true;
options.TracesSampleRate = 1.0;
options.ProfilesSampleRate = 1.0;
options.AddProfilingIntegration();
options.TracesSampleRate = sentryTracesSampleRate;
options.ProfilesSampleRate = sentryProfilesSampleRate;
if (sentryProfilesSampleRate > 0)
options.AddProfilingIntegration();
});
// Включаем MVC контроллеры
@@ -334,4 +339,18 @@ app.MapMetrics();
// Маршруты Minimal API из плагинов
foreach (var p in loadedPlugins) p.Instance.MapEndpoints(app);
app.Run();
app.Run();
static double GetSampleRate(IConfiguration configuration, string key, double defaultValue)
{
var rawValue = configuration[key];
if (string.IsNullOrWhiteSpace(rawValue))
return defaultValue;
if (double.TryParse(rawValue, NumberStyles.Float, CultureInfo.InvariantCulture, out var sampleRate) &&
sampleRate is >= 0 and <= 1)
return sampleRate;
throw new InvalidOperationException(
$"Переменная окружения {key} должна быть числом от 0 до 1 (получено: '{rawValue}').");
}
+5 -3
View File
@@ -14,12 +14,14 @@ services:
- API_KEY=${API_KEY}
# - TOKEN=${TOKEN}
- AUTH_URL=${AUTH_URL}
- AUTH_API_KEY=${AUTH_API_KEY}
- Sentry:Dsn=${SENTRY_DSN:-}
- AUTH_API_KEY=${AUTH_API_KEY}
- Sentry:Dsn=${SENTRY_DSN:-}
- SENTRY_TRACES_SAMPLE_RATE=${SENTRY_TRACES_SAMPLE_RATE:-1}
- SENTRY_PROFILES_SAMPLE_RATE=${SENTRY_PROFILES_SAMPLE_RATE:-1}
volumes:
- data:/app/data
restart: always
image: git.zetcraft.ru/serega404/sfeduschedule:main
volumes:
data:
data:
+5 -3
View File
@@ -13,11 +13,13 @@ services:
- AzureAd:CallbackPath=/signin-oidc
- API_KEY=${API_KEY}
# - TOKEN=${TOKEN}
- AUTH_URL=${AUTH_URL}
- AUTH_API_KEY=${AUTH_API_KEY}
- AUTH_URL=${AUTH_URL}
- AUTH_API_KEY=${AUTH_API_KEY}
- SENTRY_TRACES_SAMPLE_RATE=${SENTRY_TRACES_SAMPLE_RATE:-1}
- SENTRY_PROFILES_SAMPLE_RATE=${SENTRY_PROFILES_SAMPLE_RATE:-1}
volumes:
- ./data:/app/data
restart: unless-stopped
build:
context: ./SfeduSchedule
dockerfile: Dockerfile
dockerfile: Dockerfile