2018-06-27 15:14:59 +00:00
|
|
|
package metrics
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
|
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/application"
|
|
|
|
"github.com/struCoder/pidusage"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
reportFile = "serverMonitorReport.txt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Monitors is a package of metrics for a Cwtch Server including message count, CPU, Mem, and conns
|
|
|
|
type Monitors struct {
|
|
|
|
MessageCounter Counter
|
|
|
|
Messages MonitorHistory
|
|
|
|
CPU MonitorHistory
|
|
|
|
Memory MonitorHistory
|
|
|
|
ClientConns MonitorHistory
|
|
|
|
starttime time.Time
|
|
|
|
breakChannel chan bool
|
2018-06-28 17:28:39 +00:00
|
|
|
log bool
|
2018-06-27 15:14:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start initializes a Monitors's monitors
|
2018-06-28 17:28:39 +00:00
|
|
|
func (mp *Monitors) Start(ra *application.RicochetApplication, log bool) {
|
|
|
|
mp.log = log
|
2018-06-27 15:14:59 +00:00
|
|
|
mp.starttime = time.Now()
|
|
|
|
mp.breakChannel = make(chan bool)
|
|
|
|
mp.MessageCounter = NewCounter()
|
2018-06-28 19:36:50 +00:00
|
|
|
mp.Messages = NewMonitorHistory(Count, Cumulative, func() (c float64) { c = float64(mp.MessageCounter.Count()); mp.MessageCounter.Reset(); return })
|
|
|
|
mp.CPU = NewMonitorHistory(Percent, Average, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.CPU) })
|
|
|
|
mp.Memory = NewMonitorHistory(MegaBytes, Average, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.Memory) })
|
|
|
|
mp.ClientConns = NewMonitorHistory(Count, Average, func() float64 { return float64(ra.ConnectionCount()) })
|
2018-06-27 15:14:59 +00:00
|
|
|
|
2018-06-28 17:28:39 +00:00
|
|
|
if mp.log {
|
|
|
|
go mp.run()
|
|
|
|
}
|
2018-06-27 15:14:59 +00:00
|
|
|
}
|
|
|
|
|
2018-06-28 17:28:39 +00:00
|
|
|
func (mp *Monitors) run() {
|
2018-06-27 15:14:59 +00:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-time.After(time.Minute):
|
|
|
|
mp.report()
|
|
|
|
case <-mp.breakChannel:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *Monitors) report() {
|
|
|
|
f, err := os.Create(reportFile)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("ERROR: Could not open monitor reporting file: ", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
w := bufio.NewWriter(f)
|
|
|
|
|
2018-06-28 19:36:50 +00:00
|
|
|
fmt.Fprintf(w, "Uptime: %v\n\n", time.Now().Sub(mp.starttime))
|
2018-06-27 15:14:59 +00:00
|
|
|
|
|
|
|
fmt.Fprintln(w, "Messages:")
|
|
|
|
mp.Messages.Report(w)
|
|
|
|
|
|
|
|
fmt.Fprintln(w, "\nClient Connections:")
|
|
|
|
mp.ClientConns.Report(w)
|
|
|
|
|
|
|
|
fmt.Fprintln(w, "\nCPU:")
|
|
|
|
mp.CPU.Report(w)
|
|
|
|
|
|
|
|
fmt.Fprintln(w, "\nMemory:")
|
|
|
|
mp.Memory.Report(w)
|
|
|
|
|
|
|
|
w.Flush()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop stops all the monitors in a Monitors
|
|
|
|
func (mp *Monitors) Stop() {
|
2018-06-28 17:28:39 +00:00
|
|
|
if mp.log {
|
|
|
|
mp.breakChannel <- true
|
|
|
|
}
|
2018-06-27 15:14:59 +00:00
|
|
|
mp.Messages.Stop()
|
|
|
|
mp.CPU.Stop()
|
|
|
|
mp.Memory.Stop()
|
|
|
|
mp.ClientConns.Stop()
|
|
|
|
}
|