mirror of
https://github.com/gofiber/fiber.git
synced 2025-02-21 20:13:22 +00:00
130 lines
2.9 KiB
Go
130 lines
2.9 KiB
Go
package monitor
|
|
|
|
import (
|
|
"os"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
"github.com/gofiber/fiber/v3/internal/gopsutil/cpu"
|
|
"github.com/gofiber/fiber/v3/internal/gopsutil/load"
|
|
"github.com/gofiber/fiber/v3/internal/gopsutil/mem"
|
|
"github.com/gofiber/fiber/v3/internal/gopsutil/net"
|
|
"github.com/gofiber/fiber/v3/internal/gopsutil/process"
|
|
)
|
|
|
|
type stats struct {
|
|
PID statsPID `json:"pid"`
|
|
OS statsOS `json:"os"`
|
|
}
|
|
|
|
type statsPID struct {
|
|
CPU float64 `json:"cpu"`
|
|
RAM uint64 `json:"ram"`
|
|
Conns int `json:"conns"`
|
|
}
|
|
|
|
type statsOS struct {
|
|
CPU float64 `json:"cpu"`
|
|
RAM uint64 `json:"ram"`
|
|
TotalRAM uint64 `json:"total_ram"`
|
|
LoadAvg float64 `json:"load_avg"`
|
|
Conns int `json:"conns"`
|
|
}
|
|
|
|
var (
|
|
monitPidCpu atomic.Value
|
|
monitPidRam atomic.Value
|
|
monitPidConns atomic.Value
|
|
|
|
monitOsCpu atomic.Value
|
|
monitOsRam atomic.Value
|
|
monitOsTotalRam atomic.Value
|
|
monitOsLoadAvg atomic.Value
|
|
monitOsConns atomic.Value
|
|
)
|
|
|
|
var (
|
|
mutex sync.RWMutex
|
|
once sync.Once
|
|
data = &stats{}
|
|
)
|
|
|
|
// New creates a new middleware handler
|
|
func New(config ...Config) fiber.Handler {
|
|
// Set default config
|
|
cfg := configDefault(config...)
|
|
|
|
// Start routine to update statistics
|
|
once.Do(func() {
|
|
p, _ := process.NewProcess(int32(os.Getpid()))
|
|
|
|
updateStatistics(p)
|
|
|
|
go func() {
|
|
for {
|
|
time.Sleep(cfg.Refresh)
|
|
|
|
updateStatistics(p)
|
|
}
|
|
}()
|
|
})
|
|
|
|
// Return new handler
|
|
return func(c *fiber.Ctx) error {
|
|
// Don't execute middleware if Next returns true
|
|
if cfg.Next != nil && cfg.Next(c) {
|
|
return c.Next()
|
|
}
|
|
|
|
if c.Method() != fiber.MethodGet {
|
|
return fiber.ErrMethodNotAllowed
|
|
}
|
|
if c.Get(fiber.HeaderAccept) == fiber.MIMEApplicationJSON || cfg.APIOnly {
|
|
mutex.Lock()
|
|
data.PID.CPU = monitPidCpu.Load().(float64)
|
|
data.PID.RAM = monitPidRam.Load().(uint64)
|
|
data.PID.Conns = monitPidConns.Load().(int)
|
|
|
|
data.OS.CPU = monitOsCpu.Load().(float64)
|
|
data.OS.RAM = monitOsRam.Load().(uint64)
|
|
data.OS.TotalRAM = monitOsTotalRam.Load().(uint64)
|
|
data.OS.LoadAvg = monitOsLoadAvg.Load().(float64)
|
|
data.OS.Conns = monitOsConns.Load().(int)
|
|
mutex.Unlock()
|
|
return c.Status(fiber.StatusOK).JSON(data)
|
|
}
|
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
|
|
return c.Status(fiber.StatusOK).SendString(cfg.index)
|
|
}
|
|
}
|
|
|
|
func updateStatistics(p *process.Process) {
|
|
pidCpu, _ := p.CPUPercent()
|
|
monitPidCpu.Store(pidCpu / 10)
|
|
|
|
if osCpu, _ := cpu.Percent(0, false); len(osCpu) > 0 {
|
|
monitOsCpu.Store(osCpu[0])
|
|
}
|
|
|
|
if pidMem, _ := p.MemoryInfo(); pidMem != nil {
|
|
monitPidRam.Store(pidMem.RSS)
|
|
}
|
|
|
|
if osMem, _ := mem.VirtualMemory(); osMem != nil {
|
|
monitOsRam.Store(osMem.Used)
|
|
monitOsTotalRam.Store(osMem.Total)
|
|
}
|
|
|
|
if loadAvg, _ := load.Avg(); loadAvg != nil {
|
|
monitOsLoadAvg.Store(loadAvg.Load1)
|
|
}
|
|
|
|
pidConns, _ := net.ConnectionsPid("tcp", p.Pid)
|
|
monitPidConns.Store(len(pidConns))
|
|
|
|
osConns, _ := net.Connections("tcp")
|
|
monitOsConns.Store(len(osConns))
|
|
}
|