- Create docs/ with 7 focused files: architecture, api, scoring, agent, deployment, freeswitch, development - Rewrite README.md as concise overview with links to docs/ - Remove AGENTS.md (content merged into docs/ and README)
155 lines
5.6 KiB
Markdown
155 lines
5.6 KiB
Markdown
# Pulse Lets Go
|
||
|
||
[](https://go.dev)
|
||
[](LICENSE)
|
||
[](https://nats.io)
|
||
[](https://kit.svelte.dev)
|
||
|
||
**pulse-lets-go** — балансировщик телефонной нагрузки на базе FreeSWITCH + NATS.
|
||
|
||
Агенты PBX отправляют метрики в NATS каждые 5 секунд. Балансировщик вычисляет weighted score готовности каждой ноды, кэширует лучшую и отдаёт её FreeSWITCH через `/api/route` для следующего звонка.
|
||
|
||
---
|
||
|
||
## Features
|
||
|
||
- **pulse-lets-go-agent** — агент сбора метрик для FreeSWITCH (ESL) и Asterisk (AMI)
|
||
- **Scoring engine** — lethal checks + weighted score (call, load, idle, fail) с конфигурируемыми весами
|
||
- **NATS шина** — асинхронный сбор метрик через `pulse.metrics.<node_id>`
|
||
- **REST API** — JWT (access + refresh), роли admin/viewer, rate limiting, CORS
|
||
- **WebSocket** — real-time трансляция метрик на SvelteKit дашборд
|
||
- **FreeSWITCH ESL** — управление Sofia-шлюзами через raw TCP ESL
|
||
- **Monitoring** — Prometheus и Zabbix эндпоинты с отдельным API-key
|
||
- **SvelteKit UI** — дашборд, таблицы нод, транков, пользователей
|
||
- **Graceful shutdown** с таймаутом 10 с
|
||
- **systemd ready** с изоляцией (NoNewPrivileges, ProtectSystem, PrivateTmp)
|
||
|
||
---
|
||
|
||
## Quick Start
|
||
|
||
### Requirements
|
||
|
||
- Go 1.26+
|
||
- Node.js 22+
|
||
- NATS Server (`make nats` скачивает автоматически)
|
||
|
||
### Build & Run
|
||
|
||
```bash
|
||
git clone git@git.totmin.ru:en2zmax/pulse-lets-go.git
|
||
cd pulse-lets-go
|
||
make build
|
||
```
|
||
|
||
```bash
|
||
# Terminal 1: NATS
|
||
make nats
|
||
|
||
# Terminal 2: balancer
|
||
./bin/pulse-lets-go
|
||
|
||
# Terminal 3: emulator (3 healthy nodes)
|
||
make emulate-normal
|
||
```
|
||
|
||
### Check
|
||
|
||
```bash
|
||
# Route (no auth)
|
||
curl 'http://localhost:8080/api/route?caller_id=123&dest=456&ingress_trunk=trk-001'
|
||
|
||
# Login
|
||
curl -X POST http://localhost:8080/api/auth/login \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"username":"admin","password":"admin"}'
|
||
```
|
||
|
||
---
|
||
|
||
## Documentation
|
||
|
||
| Document | Content |
|
||
|----------|---------|
|
||
| [docs/architecture.md](docs/architecture.md) | Архитектура, диаграмма потоков данных, стек, структура проекта |
|
||
| [docs/api.md](docs/api.md) | Полная справка REST API + WebSocket: auth, route, nodes, trunks, users, monitoring, примеры |
|
||
| [docs/scoring.md](docs/scoring.md) | Scoring engine: lethal-условия, weighted score, пример расчёта, кэширование |
|
||
| [docs/agent.md](docs/agent.md) | pulse-lets-go-agent: collectors, конфигурация, деплой, troubleshooting |
|
||
| [docs/deployment.md](docs/deployment.md) | Production деплой (8 шагов), systemd unit, security, rollback |
|
||
| [docs/freeswitch.md](docs/freeswitch.md) | Интеграция с FreeSWITCH: route.lua, dialplan, ESL, предварительные проверки |
|
||
| [docs/development.md](docs/development.md) | Команды Makefile, code style, добавление эндпоинта, PR process |
|
||
| [CHANGELOG.md](CHANGELOG.md) | История изменений (Keep a Changelog) |
|
||
| [CONTRIBUTING.md](CONTRIBUTING.md) | Code style, conventional commits, процесс PR |
|
||
|
||
---
|
||
|
||
## Configuration
|
||
|
||
При первом запуске `config.json` создаётся автоматически в `data/` (или `$PULSE_DATA_DIR`). JWT-секрет и API-key генерируются случайно.
|
||
|
||
### config.json
|
||
|
||
```json
|
||
{
|
||
"nats_url": "nats://localhost:4222",
|
||
"nats_user": "",
|
||
"nats_password": "",
|
||
"listen_addr": ":8080",
|
||
"jwt_secret": "auto-generated-32-byte-hex",
|
||
"monitoring_api_key": "auto-generated-32-byte-hex",
|
||
"stale_threshold_sec": 20,
|
||
"scoring": {
|
||
"idle_cpu_min": 5,
|
||
"call_failure_rate_lethal": 15.0,
|
||
"weights": {
|
||
"call_score": 0.40,
|
||
"load_score": 0.30,
|
||
"idle_score": 0.20,
|
||
"fail_score": 0.10
|
||
}
|
||
},
|
||
"tls": {
|
||
"enabled": false,
|
||
"cert_file": "",
|
||
"key_file": ""
|
||
},
|
||
"rate_limit": {
|
||
"enabled": true,
|
||
"route_per_sec": 5000,
|
||
"api_per_sec": 100
|
||
},
|
||
"log": {
|
||
"level": "info",
|
||
"format": "text"
|
||
},
|
||
"esl": {
|
||
"host": "",
|
||
"port": 8021,
|
||
"password": "",
|
||
"password_env": "",
|
||
"sofia_profile": "external",
|
||
"gateway_prefix": "pulse"
|
||
}
|
||
}
|
||
```
|
||
|
||
### Key Parameters
|
||
|
||
| Parameter | Default | Description |
|
||
|-----------|---------|-------------|
|
||
| `nats_url` | `nats://localhost:4222` | NATS server URL |
|
||
| `listen_addr` | `:8080` | HTTP server address |
|
||
| `stale_threshold_sec` | `20` | Seconds without metrics before node is stale |
|
||
| `scoring.idle_cpu_min` | `5` | Minimum idle CPU. Below — lethal |
|
||
| `scoring.call_failure_rate_lethal` | `15.0` | Maximum failure rate. Above — lethal |
|
||
| `rate_limit.route_per_sec` | `5000` | `/api/route` per-IP limit |
|
||
| `rate_limit.api_per_sec` | `100` | `/api/*` per-IP limit |
|
||
| `log.level` | `info` | `debug`, `info`, `warn`, `error` |
|
||
| `esl.host` | `""` | FS ESL host. Empty — ESL disabled |
|
||
|
||
---
|
||
## Прочее
|
||
|
||
AGENTS.md содержит только этот файл — структура и связь рабочих элементов.
|
||
see docs/development.md — план реализации и стек.
|