# Pulse Lets Go **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.` - **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 — план реализации и стек.