package servermetrics import ( "context" "log" "sync" "time" "github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/disk" "github.com/shirou/gopsutil/v4/mem" ) type Stats struct { CPUPercent float64 `json:"cpu_percent"` MemoryUsed uint64 `json:"memory_used"` MemoryTotal uint64 `json:"memory_total"` MemoryPct float64 `json:"memory_percent"` DiskUsed uint64 `json:"disk_used"` DiskTotal uint64 `json:"disk_total"` DiskPct float64 `json:"disk_percent"` } type Collector struct { mu sync.RWMutex last Stats diskPath string } func New(diskPath string) *Collector { return &Collector{diskPath: diskPath} } func (c *Collector) Start(ctx context.Context) { c.collectOnce(ctx, 500*time.Millisecond) ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() for { select { case <-ticker.C: c.collectOnce(ctx, 0) case <-ctx.Done(): return } } } func (c *Collector) collectOnce(ctx context.Context, cpuInterval time.Duration) { cpuPct, err := cpu.PercentWithContext(ctx, cpuInterval, false) if err != nil { log.Printf("[servermetrics] erro cpu: %v", err) return } memStat, err := mem.VirtualMemoryWithContext(ctx) if err != nil { log.Printf("[servermetrics] erro mem: %v", err) return } diskStat, err := disk.UsageWithContext(ctx, c.diskPath) if err != nil { log.Printf("[servermetrics] erro disk: %v", err) return } c.mu.Lock() c.last = Stats{ CPUPercent: cpuPct[0], MemoryUsed: memStat.Used, MemoryTotal: memStat.Total, MemoryPct: memStat.UsedPercent, DiskUsed: diskStat.Used, DiskTotal: diskStat.Total, DiskPct: diskStat.UsedPercent, } c.mu.Unlock() } func (c *Collector) Get() Stats { c.mu.RLock() defer c.mu.RUnlock() return c.last }