feat(instance): метрики всей машины вторым рядом дашборда
Дашборд показывал только контейнер (лимиты профиля), поэтому не было видно, сколько ресурсов у хоста всего. - `sysinfo.NewHostSampler` и `ReadHostMemory` всегда читают `/proc/stat` и `/proc/meminfo`, игнорируя cgroup; - в ответе метрик появились `host_cpu` и `host_memory` (`source: host`); - недоступные источники попадают в проверку `metrics`, а не ломают ручку.
This commit is contained in:
@@ -87,6 +87,53 @@ func TestCPUPercentFallsBackToProcStat(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHostSamplerIgnoresCgroup(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// cgroup показывает нагрузку контейнера, /proc/stat — всей машины.
|
||||
writeFile(t, dir, "cpu.max", "200000 100000\n")
|
||||
writeFile(t, dir, "cpu.stat", "usage_usec 1000000\n")
|
||||
statPath := writeFile(t, dir, "stat", "cpu 100 0 100 800 0 0 0 0 0 0\n")
|
||||
|
||||
now := time.Unix(1_700_000_000, 0)
|
||||
paths := sysinfo.Paths{
|
||||
ProcStat: statPath,
|
||||
MemInfo: filepath.Join(dir, "meminfo"),
|
||||
CgroupDir: dir,
|
||||
WallClock: func() time.Time { return now },
|
||||
}
|
||||
|
||||
host := sysinfo.NewHostSampler(paths)
|
||||
if _, cores, source, err := host.CPUPercent(); err != nil || source != "host" || cores < 1 {
|
||||
t.Fatalf("хост-сэмплер: источник=%s ядер=%v err=%v", source, cores, err)
|
||||
}
|
||||
container := sysinfo.NewSampler(paths)
|
||||
if _, cores, source, err := container.CPUPercent(); err != nil || source != "cgroup" || cores != 2 {
|
||||
t.Fatalf("контейнерный сэмплер: источник=%s ядер=%v err=%v", source, cores, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadHostMemoryIgnoresCgroupLimit(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
writeFile(t, dir, "memory.current", "15728640\n")
|
||||
writeFile(t, dir, "memory.max", "805306368\n")
|
||||
writeFile(t, dir, "meminfo", "MemTotal: 3479592 kB\nMemAvailable: 1000000 kB\n")
|
||||
|
||||
memory, err := sysinfo.ReadHostMemory(sysinfo.Paths{
|
||||
MemInfo: filepath.Join(dir, "meminfo"),
|
||||
CgroupDir: dir,
|
||||
ProcStat: filepath.Join(dir, "stat"),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("память хоста: %v", err)
|
||||
}
|
||||
if memory.Source != "host" || memory.TotalBytes != 3479592*1024 {
|
||||
t.Fatalf("память хоста = %+v", memory)
|
||||
}
|
||||
if memory.UsedBytes != (3479592-1000000)*1024 {
|
||||
t.Fatalf("занято = %d", memory.UsedBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadMemoryPrefersCgroupLimit(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
writeFile(t, dir, "memory.current", "15728640\n")
|
||||
|
||||
Reference in New Issue
Block a user