feat(instance): метрики всей машины вторым рядом дашборда
Дашборд показывал только контейнер (лимиты профиля), поэтому не было видно, сколько ресурсов у хоста всего. - `sysinfo.NewHostSampler` и `ReadHostMemory` всегда читают `/proc/stat` и `/proc/meminfo`, игнорируя cgroup; - в ответе метрик появились `host_cpu` и `host_memory` (`source: host`); - недоступные источники попадают в проверку `metrics`, а не ломают ручку.
This commit is contained in:
@@ -57,16 +57,26 @@ type CPUSample struct {
|
||||
// дают нагрузку за последнюю секунду, редкие вызовы — среднее за паузу.
|
||||
type Sampler struct {
|
||||
paths Paths
|
||||
// host заставляет считать нагрузку всей машины (/proc/stat), даже когда
|
||||
// у контейнера есть лимиты: дашборд показывает оба ряда.
|
||||
host bool
|
||||
|
||||
mu sync.Mutex
|
||||
last *CPUSample
|
||||
}
|
||||
|
||||
// NewSampler создаёт сэмплер процессорного времени.
|
||||
// NewSampler создаёт сэмплер процессорного времени: cgroup контейнера, а при
|
||||
// отсутствии лимитов — вся машина.
|
||||
func NewSampler(paths Paths) *Sampler {
|
||||
return &Sampler{paths: paths}
|
||||
}
|
||||
|
||||
// NewHostSampler создаёт сэмплер нагрузки всей машины: нужен для второго ряда
|
||||
// дашборда, когда контейнер ограничен профилем.
|
||||
func NewHostSampler(paths Paths) *Sampler {
|
||||
return &Sampler{paths: paths, host: true}
|
||||
}
|
||||
|
||||
// CPUPercent возвращает загрузку в процентах от доступного времени и число
|
||||
// ядер. Первый вызов без предыдущего снимка возвращает 0: дельты ещё нет.
|
||||
func (s *Sampler) CPUPercent() (percent float64, cores float64, source string, err error) {
|
||||
@@ -109,8 +119,10 @@ func (s *Sampler) CPUPercent() (percent float64, cores float64, source string, e
|
||||
// readCPU предпочитает cgroup v2: он показывает нагрузку контейнера и его
|
||||
// лимит, а /proc/stat — всю машину целиком.
|
||||
func (s *Sampler) readCPU() (CPUSample, float64, string, error) {
|
||||
if sample, cores, ok := s.readCgroupCPU(); ok {
|
||||
return sample, cores, "cgroup", nil
|
||||
if !s.host {
|
||||
if sample, cores, ok := s.readCgroupCPU(); ok {
|
||||
return sample, cores, "cgroup", nil
|
||||
}
|
||||
}
|
||||
sample, cores, err := s.readProcStat()
|
||||
if err != nil {
|
||||
@@ -234,6 +246,12 @@ func ReadMemory(paths Paths) (Memory, error) {
|
||||
return readMemInfo(paths.MemInfo)
|
||||
}
|
||||
|
||||
// ReadHostMemory всегда читает память всей машины (/proc/meminfo): второй ряд
|
||||
// дашборда показывает хост даже при лимитах контейнера.
|
||||
func ReadHostMemory(paths Paths) (Memory, error) {
|
||||
return readMemInfo(paths.MemInfo)
|
||||
}
|
||||
|
||||
func readCgroupMemory(dir string) (Memory, bool) {
|
||||
current, err := readInt(filepath.Join(dir, "memory.current"))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user