- pulse-lets-go-agent: collects metrics from PBX nodes via ESL (FreeSWITCH) or AMI (Asterisk) - AMI client (raw TCP) for Asterisk Manager Interface - Collector interface: collect, connect, subscribe hangup events, close - FreeSWITCH collector: show channels, max_sessions, idle_cpu - Asterisk collector: CoreShowChannels, CoreSettings - System collector: /proc/loadavg, /proc/stat (CPU idle) - Failure tracker: sliding window for call_failure_rate - NATS publisher: pulse.metrics.<node_id> every 5 seconds - Graceful shutdown, retry logic (5 failures → status=down) - Template configs for UC nodes (Asterisk) and ses-sip (FreeSWITCH)
58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package agent
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
|
|
natsgo "github.com/nats-io/nats.go"
|
|
|
|
"github.com/pulse-lets-go/internal/models"
|
|
)
|
|
|
|
// Publisher публикует метрики в NATS.
|
|
type Publisher struct {
|
|
nc *natsgo.Conn
|
|
nodeID string
|
|
}
|
|
|
|
// NewPublisher создаёт NATS publisher.
|
|
func NewPublisher(natsURL, user, password, nodeID string) (*Publisher, error) {
|
|
opts := []natsgo.Option{
|
|
natsgo.ReconnectWait(natsgo.DefaultReconnectWait),
|
|
natsgo.MaxReconnects(-1),
|
|
}
|
|
if user != "" && password != "" {
|
|
opts = append(opts, natsgo.UserInfo(user, password))
|
|
}
|
|
|
|
nc, err := natsgo.Connect(natsURL, opts...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("nats connect: %w", err)
|
|
}
|
|
|
|
log.Printf("[publisher] NATS подключён к %s", natsURL)
|
|
return &Publisher{nc: nc, nodeID: nodeID}, nil
|
|
}
|
|
|
|
// Publish отправляет метрику в NATS: pulse.metrics.<node_id>.
|
|
func (p *Publisher) Publish(m *models.NodeMetric) error {
|
|
subject := fmt.Sprintf("pulse.metrics.%s", p.nodeID)
|
|
data, err := json.Marshal(m)
|
|
if err != nil {
|
|
return fmt.Errorf("marshal metric: %w", err)
|
|
}
|
|
|
|
if err := p.nc.Publish(subject, data); err != nil {
|
|
return fmt.Errorf("publish: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Close закрывает NATS-соединение.
|
|
func (p *Publisher) Close() {
|
|
if p.nc != nil {
|
|
p.nc.Close()
|
|
}
|
|
}
|