Official cwtch.im peer and server implementations. https://cwtch.im
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

108 řádky
2.4KB

  1. package metrics
  2. import (
  3. "bufio"
  4. "fmt"
  5. "git.openprivacy.ca/openprivacy/libricochet-go/application"
  6. "git.openprivacy.ca/openprivacy/libricochet-go/log"
  7. "github.com/struCoder/pidusage"
  8. "os"
  9. "path"
  10. "sync"
  11. "time"
  12. )
  13. const (
  14. reportFile = "serverMonitorReport.txt"
  15. )
  16. // Monitors is a package of metrics for a Cwtch Server including message count, CPU, Mem, and conns
  17. type Monitors struct {
  18. MessageCounter Counter
  19. Messages MonitorHistory
  20. CPU MonitorHistory
  21. Memory MonitorHistory
  22. ClientConns MonitorHistory
  23. starttime time.Time
  24. breakChannel chan bool
  25. log bool
  26. configDir string
  27. }
  28. // Start initializes a Monitors's monitors
  29. func (mp *Monitors) Start(ra *application.RicochetApplication, configDir string, log bool) {
  30. mp.log = log
  31. mp.configDir = configDir
  32. mp.starttime = time.Now()
  33. mp.breakChannel = make(chan bool)
  34. mp.MessageCounter = NewCounter()
  35. mp.Messages = NewMonitorHistory(Count, Cumulative, func() (c float64) { c = float64(mp.MessageCounter.Count()); mp.MessageCounter.Reset(); return })
  36. var pidUsageLock sync.Mutex
  37. mp.CPU = NewMonitorHistory(Percent, Average, func() float64 {
  38. pidUsageLock.Lock()
  39. defer pidUsageLock.Unlock()
  40. sysInfo, _ := pidusage.GetStat(os.Getpid())
  41. return float64(sysInfo.CPU)
  42. })
  43. mp.Memory = NewMonitorHistory(MegaBytes, Average, func() float64 {
  44. pidUsageLock.Lock()
  45. defer pidUsageLock.Unlock()
  46. sysInfo, _ := pidusage.GetStat(os.Getpid())
  47. return float64(sysInfo.Memory)
  48. })
  49. mp.ClientConns = NewMonitorHistory(Count, Average, func() float64 { return float64(ra.ConnectionCount()) })
  50. if mp.log {
  51. go mp.run()
  52. }
  53. }
  54. func (mp *Monitors) run() {
  55. for {
  56. select {
  57. case <-time.After(time.Minute):
  58. mp.report()
  59. case <-mp.breakChannel:
  60. return
  61. }
  62. }
  63. }
  64. func (mp *Monitors) report() {
  65. f, err := os.Create(path.Join(mp.configDir, reportFile))
  66. if err != nil {
  67. log.Errorf("Could not open monitor reporting file: %v", err)
  68. return
  69. }
  70. defer f.Close()
  71. w := bufio.NewWriter(f)
  72. fmt.Fprintf(w, "Uptime: %v\n\n", time.Now().Sub(mp.starttime))
  73. fmt.Fprintln(w, "messages:")
  74. mp.Messages.Report(w)
  75. fmt.Fprintln(w, "\nClient Connections:")
  76. mp.ClientConns.Report(w)
  77. fmt.Fprintln(w, "\nCPU:")
  78. mp.CPU.Report(w)
  79. fmt.Fprintln(w, "\nMemory:")
  80. mp.Memory.Report(w)
  81. w.Flush()
  82. }
  83. // Stop stops all the monitors in a Monitors
  84. func (mp *Monitors) Stop() {
  85. if mp.log {
  86. mp.breakChannel <- true
  87. }
  88. mp.Messages.Stop()
  89. mp.CPU.Stop()
  90. mp.Memory.Stop()
  91. mp.ClientConns.Stop()
  92. }