package agent import "github.com/pulse-lets-go/internal/models" // PBXResult — результат сбора метрик от PBX (FS или Asterisk). type PBXResult struct { ActiveCalls int // текущее количество звонков MaxCalls int // ёмкость (0 — не удалось получить) IdleCPU float64 // idle CPU из PBX (0 — не удалось, fallback на system) Status string // "ok" — PBX отвечает нормально SIPGateway string // авто-определённый SIP-адрес } // Collector — интерфейс сбора метрик с PBX. type Collector interface { // Type возвращает тип PBX: "freeswitch" или "asterisk". Type() string // Connect подключается к PBX (ESL auth / AMI login). Connect() error // Collect собирает метрики с PBX. // Возвращает PBXResult и ошибку, если сбор не удался. Collect() (*PBXResult, error) // ListenHangups подписывается на события завершения звонков // для расчёта call_failure_rate. ListenHangups(onHangup func(success bool)) // Close закрывает соединение с PBX. Close() } // HangupEvent — событие завершения звонка. type HangupEvent struct { Success bool // true — звонок успешен, false — ошибка Cause string // код причины (NORMAL_CLEARING, BUSY, и т.д.) } // ToMetric формирует models.NodeMetric из результатов сбора. func ToMetric(nodeID string, pbx *PBXResult, sys *SystemStats, failureRate float64, sipGateway string, maxCallsDefault int) *models.NodeMetric { // Определяем max_calls: приоритет PBX → конфиг maxCalls := pbx.MaxCalls if maxCalls <= 0 { maxCalls = maxCallsDefault } // Определяем idle_cpu: приоритет PBX → system idleCPU := pbx.IdleCPU if idleCPU <= 0 { idleCPU = sys.IdleCPU } // Определяем статус status := pbx.Status if pbx.Status == "ok" && sys.IdleCPU < 5 { status = "degraded" } return &models.NodeMetric{ NodeID: nodeID, TS: nowTS(), Status: status, ActiveCalls: pbx.ActiveCalls, MaxCalls: maxCalls, IdleCPU: idleCPU, LoadAvg: sys.Load1, CallFailureRate: failureRate, SIPGateway: sipGateway, } }