package netstat import ( "log" "sync" "time" "wartank/pkg/types" ) /* Сетевая статистика для сетевого соединения */ // NetStat -- статистика сетевого соединения type NetStat struct { botNet types.ИБотСеть countByteInterval int // Счётчик байтов в текущем интервале totalByte int // Сколько всего байт передано totalMinut int // Сколько всего минут работала передача countRequestInterval int // Число запросов countErr int // Число зафиксированных ошибок chTick chan int // Сигналы времени 1 раз в 5 минут block sync.Mutex } // NewNetStat -- возвращает новый *NetStat func NewNetStat(botNet types.ИБотСеть) *NetStat { sf := &NetStat{ botNet: botNet, chTick: make(chan int, 2), } go sf.run() go sf.makeTick() return sf } // Тикер меток времени 1 раз в 5 минут func (sf *NetStat) makeTick() { defer close(sf.chTick) for { select { case <-sf.botNet.Кнт().Done(): return default: time.Sleep(time.Second * 5 * 60) sf.chTick <- 1 } } } // Главный цикл работы статистики func (sf *NetStat) run() { fnCalc := func() { sf.block.Lock() defer sf.block.Unlock() sf.totalMinut += 5 mbyte := float32(sf.totalByte) / float32(sf.totalMinut*60) * (3600 * 24 * 30.5) / (1024 * 1024) log.Printf("INFO NetStat.run().fnCalc(): запросы=%0.2f/сек\tтраф0=%0.2f бит/сек\tтраф1=%0.2f МБ/мес\tошибки=%v\n", float32(sf.countRequestInterval)/300, float32(sf.countByteInterval*8)/300, mbyte, sf.countErr) sf.countByteInterval = 0 sf.countRequestInterval = 0 } for range sf.chTick { select { case <-sf.botNet.Кнт().Done(): return case <-sf.chTick: fnCalc() } } } // IncErr -- добавляет ошибку в статистику func (sf *NetStat) IncErr() { sf.block.Lock() defer sf.block.Unlock() sf.countErr++ } // AddByte -- увеличивает счётчик запросов и байтов на передачу/приём func (sf *NetStat) AddByte(val int) { sf.block.Lock() defer sf.block.Unlock() sf.countByteInterval += val sf.totalByte += val sf.countRequestInterval++ }