aboutsummaryrefslogtreecommitdiff
path: root/resources_controller.go
diff options
context:
space:
mode:
Diffstat (limited to 'resources_controller.go')
-rw-r--r--resources_controller.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/resources_controller.go b/resources_controller.go
new file mode 100644
index 0000000..050157a
--- /dev/null
+++ b/resources_controller.go
@@ -0,0 +1,91 @@
+package main
+
+import (
+ "context"
+ "github.com/gin-gonic/gin"
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/mem"
+ log "github.com/sirupsen/logrus"
+ "sync"
+ "time"
+)
+
+const (
+ averageCPUPercentAlertThreshold = 90.0
+ averageCPUPercentAlertMinInterval = 120.0
+)
+
+type SystemStats struct {
+ VirtualMemory *mem.VirtualMemoryStat `json:"virtual_memory"`
+ CPUTimes []cpu.TimesStat `json:"cpu_times"`
+ CPUPercents []float64 `json:"cpu_percents"`
+ DiskUsage *disk.UsageStat `json:"disk_usage"`
+}
+
+type ResourcesController struct {
+ notificationController *NotificationController
+ lastCPUPercent []float64
+ mutex sync.Mutex
+}
+
+func NewResourcesController(notificationController *NotificationController) *ResourcesController {
+ return &ResourcesController{
+ notificationController: notificationController,
+ }
+}
+
+func (csc *ResourcesController) GetProcessStats(c context.Context) interface{} {
+ return nil
+}
+
+func (csc *ResourcesController) GetSystemStats(c context.Context) SystemStats {
+ virtualMemory, err := mem.VirtualMemoryWithContext(c)
+ if err != nil {
+ log.WithError(err).Panic("failed to retrieve virtual memory")
+ }
+ cpuTimes, err := cpu.TimesWithContext(c, true)
+ if err != nil {
+ log.WithError(err).Panic("failed to retrieve cpu times")
+ }
+ diskUsage, err := disk.UsageWithContext(c, "/")
+ if err != nil {
+ log.WithError(err).Panic("failed to retrieve disk usage")
+ }
+
+ defer csc.mutex.Unlock()
+ csc.mutex.Lock()
+
+ return SystemStats{
+ VirtualMemory: virtualMemory,
+ CPUTimes: cpuTimes,
+ DiskUsage: diskUsage,
+ CPUPercents: csc.lastCPUPercent,
+ }
+}
+
+func (csc *ResourcesController) Run() {
+ interval, _ := time.ParseDuration("3s")
+ var lastAlertTime time.Time
+
+ for {
+ cpuPercent, err := cpu.Percent(interval, true)
+ if err != nil {
+ log.WithError(err).Error("failed to retrieve cpu percent")
+ return
+ }
+
+ csc.mutex.Lock()
+ csc.lastCPUPercent = cpuPercent
+ csc.mutex.Unlock()
+
+ avg := Average(cpuPercent)
+ if avg > averageCPUPercentAlertThreshold && time.Now().Sub(lastAlertTime).Seconds() > averageCPUPercentAlertMinInterval {
+ csc.notificationController.Notify("resources.cpu_alert", "alert", gin.H{
+ "cpu_percent": cpuPercent,
+ })
+ log.WithField("cpu_percent", cpuPercent).Warn("cpu percent usage has exceeded the limit threshold")
+ lastAlertTime = time.Now()
+ }
+ }
+}