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:
+20
-2
@@ -110,17 +110,35 @@ func (c *AdminClient) ListParticipants(ctx context.Context, room string) ([]Part
|
||||
return response.Participants, nil
|
||||
}
|
||||
|
||||
// Ping проверяет доступность RoomService: healthcheck дашборда заодно
|
||||
// убеждается, что ключи LiveKit валидны (их неверность ломает модерацию).
|
||||
func (c *AdminClient) Ping(ctx context.Context) error {
|
||||
if !c.Enabled() {
|
||||
return ErrDisabled
|
||||
}
|
||||
token, err := c.issuer.IssueRoomList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.callWithToken(ctx, token, "ListRooms", map[string]any{}, nil)
|
||||
}
|
||||
|
||||
// call выполняет запрос к Twirp-методу RoomService с административным токеном
|
||||
// этой комнаты: LiveKit принимает `roomAdmin` только вместе с именем комнаты.
|
||||
func (c *AdminClient) call(ctx context.Context, room, method string, body any, out any) error {
|
||||
if !c.Enabled() {
|
||||
return ErrDisabled
|
||||
}
|
||||
payload, err := json.Marshal(body)
|
||||
token, err := c.issuer.IssueAdmin(room)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
token, err := c.issuer.IssueAdmin(room)
|
||||
return c.callWithToken(ctx, token, method, body, out)
|
||||
}
|
||||
|
||||
// callWithToken выполняет запрос к Twirp-методу с готовым токеном.
|
||||
func (c *AdminClient) callWithToken(ctx context.Context, token, method string, body any, out any) error {
|
||||
payload, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user