Files
go-sip/internal/health/sample.go
T

81 lines
2.2 KiB
Go

package health
import (
"context"
"os"
"strings"
"time"
agentpb "git.ipao.vip/rogee/go-sip/gen/agent"
"github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/disk"
"github.com/shirou/gopsutil/v4/mem"
"github.com/shirou/gopsutil/v4/process"
)
// Sampler uses gopsutil for host/process observations. Unsupported or
// unconfigured dimensions stay explicitly unknown instead of being reported as
// zero capacity.
type Sampler struct {
Now func() time.Time
}
func (s Sampler) Sample(ctx context.Context, spoolRoot string) *agentpb.ResourceSample {
now := time.Now
if s.Now != nil {
now = s.Now
}
sample := &agentpb.ResourceSample{
ObservedAtUnixMs: now().UnixMilli(),
SampleFresh: true,
}
var missing []string
if values, err := cpu.PercentWithContext(ctx, 0, false); err != nil || len(values) == 0 {
missing = append(missing, "cpu")
} else {
sample.CpuUsedRatio = values[0] / 100
}
if value, err := mem.VirtualMemoryWithContext(ctx); err != nil {
missing = append(missing, "memory")
} else {
sample.MemoryAvailableBytes = int64(value.Available)
}
if spoolRoot == "" {
missing = append(missing, "spool")
} else if value, err := disk.UsageWithContext(ctx, spoolRoot); err != nil {
missing = append(missing, "spool")
} else {
sample.SpoolUsedBytes = int64(value.Used)
sample.SpoolCapacityBytes = int64(value.Total)
}
proc, err := process.NewProcess(int32(os.Getpid()))
if err != nil {
missing = append(missing, "fd")
} else if limits, limitErr := proc.RlimitUsageWithContext(ctx, true); limitErr != nil {
missing = append(missing, "fd")
} else {
found := false
for _, limit := range limits {
if limit.Resource == process.RLIMIT_NOFILE {
sample.FdUsed = int64(limit.Used)
sample.FdLimit = int64(limit.Soft)
found = true
break
}
}
if !found {
missing = append(missing, "fd")
}
}
// Media-port and AI-provider quotas are owned by the Cell/Dispatcher, not
// this host sampler. Keep them unknown until those sources are connected.
missing = append(missing, "media_ports", "ai_quota")
if len(missing) != 0 {
sample.SampleFresh = false
sample.MissingReason = strings.Join(missing, ",")
}
return sample
}