Files
techircd/health.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
}