feat(instance): метрики и healthcheck инстанса для дашборда
Раздел «Инстанс» получает живые показатели сервера (AGENT.md 7.19). - `internal/sysinfo`: загрузка процессора по cgroup v2 (`cpu.stat`/`cpu.max`) с откатом на `/proc/stat`, память по лимиту контейнера либо `/proc/meminfo`, место на разделе данных и размер базы вместе с журналом WAL; - `GET /api/v1/instance/metrics` (только администратор инстанса): метрики, состояние (`ok|warn|failed`), проверки app/database/disk/storage/voice/ gateway, версия и время работы; недоступные источники не ломают ответ, а попадают в проверку `metrics`; - тяжёлые проверки (БД, SFU, запись) кэшируются на 5 секунд: ручку можно опрашивать раз в секунду; - `voice.IssueRoomList` и `AdminClient.Ping` проверяют доступность RoomService и валидность ключей LiveKit (та же связка, что ломала модерацию); - у метрик свой лимит частоты, они исключены из общего лимита API (`RateLimiter.MiddlewareExcept`), иначе открытый раздел съедал бы половину бюджета запросов; - тесты: `internal/sysinfo` (cgroup, /proc, память, диск, размеры файлов) и `internal/server/api_metrics_test.go` (доступ, состав метрик, кэш, 429).
This commit is contained in:
@@ -124,6 +124,27 @@ func (l *RateLimiter) Middleware(keyFn func(*http.Request) string) Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
// MiddlewareExcept ограничивает частоту запросов везде, кроме перечисленных
|
||||
// путей: у живого дашборда инстанса свой лимит, иначе опрос раз в секунду
|
||||
// съедал бы половину общего бюджета API (AGENT.md 8.6).
|
||||
func (l *RateLimiter) MiddlewareExcept(keyFn func(*http.Request) string, except ...string) Middleware {
|
||||
skip := make(map[string]struct{}, len(except))
|
||||
for _, path := range except {
|
||||
skip[path] = struct{}{}
|
||||
}
|
||||
limited := l.Middleware(keyFn)
|
||||
return func(next http.Handler) http.Handler {
|
||||
handler := limited(next)
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if _, ok := skip[r.URL.Path]; ok {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
handler.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WriteRateLimited отдаёт 429 в конверте API с подсказкой по паузе (§8.5, §8.6).
|
||||
func WriteRateLimited(w http.ResponseWriter, retryAfter time.Duration) {
|
||||
milliseconds := retryAfter.Milliseconds()
|
||||
|
||||
Reference in New Issue
Block a user