# Observability Review — 2026-05-31

**Tool:** SigNoz (`https://signoz.chatindex.app`)
**Period:** последние 7 дней (168 ч)

## Key Metrics

| Метрика | Значение | vs предыдущий период |
|---|---|---|
| Всего span'ов | 57 255 | — |
| Ошибки (hasError=true) | 1 596 | — |
| Error rate | 2.81% | — |
| p99 латентность (медленнейший HTTP) | ~710 ms (cron/refresh-tokens) | — |
| Медленные DB-запросы (>50 ms) | 0 | — |
| Объём запросов | 57 255 span'ов / 7 дней | — |

## Findings

### Ошибки

| Тип span'а | Кол-во ошибок | Доля от total |
|---|---|---|
| POST (MCP tool calls) | 1 421 | 89.0% |
| refresh_connection (OAuth) | 175 | 11.0% |

**POST-ошибки (1 421):** Исторические, произошли до фикса issue #61/#62 (30 мая). В последние 24 часа POST-ошибки не фиксируются — фикс работает.

**refresh_connection (175):** Ошибки OAuth refresh persist'ятся. После фикса #62 (invalid_grant → статус revoked) часть ошибок должна была исчезнуть, однако 175 ошибок за 7 дней (~25/день) всё ещё наблюдаются. Возможные причины: другие OAuth-ошибки (не invalid_grant), retry-петля на уже revoked-соединениях, или span'ы отражают нормальный первый сбой до установки статуса revoked.

### Латентность

| Endpoint / Span | p99 | Оценка |
|---|---|---|
| GET /api/mcp/[apiKey] | ~2 660 s | ℹ️ SSE-поток (ожидаемо) |
| GET (generic) | ~532 s | ℹ️ SSE-поток (ожидаемо) |
| POST /api/cron/refresh-tokens | ~710 ms | 🟡 Медленно (внешние API) |
| POST (generic MCP tools) | ~527 ms | 🟡 Медленно |
| fetch LinkedIn API | ~435 ms | 🟡 Внешний API |
| fetch Google OAuth token | n/a | ✅ |
| GET /login | ~278 ms | 🟢 Норм |

> `GET /api/mcp/[apiKey]` — это SSE-соединение (Server-Sent Events). Большая «латентность» отражает длину сессии, а не реальную задержку ответа. Не является проблемой.

### Database

Все DB-запросы в пределах нормы:

| Тип | p99 |
|---|---|
| pg.connect | 28.6 ms ✅ |
| pg-pool.connect | 20.0 ms ✅ |
| pg.query:UPDATE | 16.9 ms ✅ |
| pg.query:SELECT | 14.7 ms ✅ |
| pg.query:INSERT | 6.2 ms ✅ |

Медленных запросов нет. N+1 не обнаружено.

### Интеграции

- Google OAuth: 3 160 вызовов `fetch POST https://oauth2.googleapis.com/token` за 7 дней — инструментация работает.
- LinkedIn API: зафиксированы span'ы с нормальными latency (~435 ms).
- Twitter/X API: зафиксированы span'ы (~267 ms).

## Recurring Issues

- **refresh_connection ошибки** — появляются в данном снэпшоте (1-й раз как отдельное наблюдение после фикса #62). Будет отслеживаться в следующих снэпшотах.

## Hypotheses

- POST-ошибки (1 421) полностью принадлежат периоду до фикса (30 мая). Вероятно, закроются сами по мере вытеснения старых span'ов из 7-дневного окна.
- Cron-job `/api/cron/refresh-tokens` на 710 ms p99 — нормально при множественных OAuth API вызовах, не требует оптимизации.

## Recommendations

1. **Мониторить refresh_connection ошибки** — через 24–48 часов проверить, снизилось ли число до 0 после фикса #62. Если нет — исследовать error types кроме invalid_grant.
2. **Добавить circuit breaker для OAuth refresh** — если соединение получает ошибку N раз подряд (любого типа), деактивировать его без дальнейших попыток до ручного reauth пользователем. Снизит шум в логах и нагрузку на внешние API.
3. **Рассмотреть инструментацию custom DB span'ов** — сейчас видны только pg.query без полного SQL-текста. Добавление `db.statement` в атрибуты позволит видеть конкретные запросы.
