100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"runtime"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// HealthMonitor tracks server health metrics
|
|
type HealthMonitor struct {
|
|
server *Server
|
|
totalClients int64
|
|
totalMessages int64
|
|
startTime time.Time
|
|
ticker *time.Ticker
|
|
shutdown chan bool
|
|
}
|
|
|
|
func NewHealthMonitor(server *Server) *HealthMonitor {
|
|
return &HealthMonitor{
|
|
server: server,
|
|
startTime: time.Now(),
|
|
shutdown: make(chan bool),
|
|
}
|
|
}
|
|
|
|
func (h *HealthMonitor) Start() {
|
|
h.ticker = time.NewTicker(5 * time.Minute) // Log stats every 5 minutes
|
|
go h.monitor()
|
|
}
|
|
|
|
func (h *HealthMonitor) Stop() {
|
|
if h.ticker != nil {
|
|
h.ticker.Stop()
|
|
}
|
|
close(h.shutdown)
|
|
}
|
|
|
|
func (h *HealthMonitor) IncrementClients() {
|
|
atomic.AddInt64(&h.totalClients, 1)
|
|
}
|
|
|
|
func (h *HealthMonitor) DecrementClients() {
|
|
atomic.AddInt64(&h.totalClients, -1)
|
|
}
|
|
|
|
func (h *HealthMonitor) IncrementMessages() {
|
|
atomic.AddInt64(&h.totalMessages, 1)
|
|
}
|
|
|
|
func (h *HealthMonitor) monitor() {
|
|
for {
|
|
select {
|
|
case <-h.ticker.C:
|
|
h.logHealthStats()
|
|
case <-h.shutdown:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (h *HealthMonitor) logHealthStats() {
|
|
var m runtime.MemStats
|
|
runtime.ReadMemStats(&m)
|
|
|
|
h.server.mu.RLock()
|
|
clientCount := len(h.server.clients)
|
|
channelCount := len(h.server.channels)
|
|
h.server.mu.RUnlock()
|
|
|
|
totalClients := atomic.LoadInt64(&h.totalClients)
|
|
totalMessages := atomic.LoadInt64(&h.totalMessages)
|
|
uptime := time.Since(h.startTime)
|
|
|
|
log.Printf("Health Stats - Uptime: %v, Clients: %d, Channels: %d, Total Clients: %d, Total Messages: %d",
|
|
uptime.Round(time.Second), clientCount, channelCount, totalClients, totalMessages)
|
|
|
|
log.Printf("Memory Stats - Alloc: %d KB, Sys: %d KB, NumGC: %d, Goroutines: %d",
|
|
bToKb(m.Alloc), bToKb(m.Sys), m.NumGC, runtime.NumGoroutine())
|
|
|
|
// Alert if memory usage is high
|
|
if m.Alloc > 100*1024*1024 { // 100MB
|
|
log.Printf("WARNING: High memory usage detected: %d MB", bToMb(m.Alloc))
|
|
}
|
|
|
|
// Alert if too many goroutines
|
|
if runtime.NumGoroutine() > 1000 {
|
|
log.Printf("WARNING: High goroutine count: %d", runtime.NumGoroutine())
|
|
}
|
|
}
|
|
|
|
func bToKb(b uint64) uint64 {
|
|
return b / 1024
|
|
}
|
|
|
|
func bToMb(b uint64) uint64 {
|
|
return b / 1024 / 1024
|
|
}
|