package handlers
import (
"sync"
"sync/atomic"
"time"
)
type TrafficMonitor struct {
bytesRead atomic.Int64
bytesWritten atomic.Int64
mu sync.RWMutex
lastCheckTime time.Time
lastBytesRead int64
lastBytesWritten int64
currentReadRate float64
currentWriteRate float64
peakReadRate float64
peakWriteRate float64
totalBytesRead int64
totalBytesWritten int64
startTime time.Time
}
func NewTrafficMonitor() *TrafficMonitor {
now := time.Now()
tm := &TrafficMonitor{
lastCheckTime: now,
startTime: now,
}
go tm.updateRates()
return tm
}
func (tm *TrafficMonitor) RecordRead(bytes int64) {
tm.bytesRead.Add(bytes)
}
func (tm *TrafficMonitor) RecordWrite(bytes int64) {
tm.bytesWritten.Add(bytes)
}
func (tm *TrafficMonitor) updateRates() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for range ticker.C {
tm.calculateRates()
}
}
func (tm *TrafficMonitor) calculateRates() {
tm.mu.Lock()
defer tm.mu.Unlock()
now := time.Now()
elapsed := now.Sub(tm.lastCheckTime).Seconds()
if elapsed <= 0 {
return
}
currentRead := tm.bytesRead.Load()
currentWrite := tm.bytesWritten.Load()
readDelta := currentRead - tm.lastBytesRead
writeDelta := currentWrite - tm.lastBytesWritten
tm.currentReadRate = float64(readDelta) / elapsed
tm.currentWriteRate = float64(writeDelta) / elapsed
if tm.currentReadRate > tm.peakReadRate {
tm.peakReadRate = tm.currentReadRate
}
if tm.currentWriteRate > tm.peakWriteRate {
tm.peakWriteRate = tm.currentWriteRate
}
tm.totalBytesRead += readDelta
tm.totalBytesWritten += writeDelta
tm.lastCheckTime = now
tm.lastBytesRead = currentRead
tm.lastBytesWritten = currentWrite
}
type TrafficStats struct {
DownstreamBps int64 `json:"downstream_bps"`
UpstreamBps int64 `json:"upstream_bps"`
PeakDownstreamBps int64 `json:"peak_downstream_bps"`
PeakUpstreamBps int64 `json:"peak_upstream_bps"`
TotalDownloadBytes int64 `json:"total_download_bytes"`
TotalUploadBytes int64 `json:"total_upload_bytes"`
UptimeSeconds int64 `json:"uptime_seconds"`
}
func (tm *TrafficMonitor) GetStats() interface{} {
tm.mu.RLock()
defer tm.mu.RUnlock()
return TrafficStats{
DownstreamBps: int64(tm.currentReadRate),
UpstreamBps: int64(tm.currentWriteRate),
PeakDownstreamBps: int64(tm.peakReadRate),
PeakUpstreamBps: int64(tm.peakWriteRate),
TotalDownloadBytes: tm.totalBytesRead,
TotalUploadBytes: tm.totalBytesWritten,
UptimeSeconds: int64(time.Since(tm.startTime).Seconds()),
}
}