1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-24 06:28:42 +01:00

fix: fixes stats on windows (#2675)

This commit is contained in:
Amir Raminfar
2024-01-09 13:03:30 -08:00
committed by GitHub
parent da24ca249a
commit e1d38a3582
5 changed files with 72 additions and 19 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex gap-4" v-if="container.stat">
<stat-monitor :data="memoryData" label="mem" :stat-value="formatBytes(unref(container.stat).memoryUsage)" />
<stat-monitor :data="cpuData" label="load" :stat-value="Math.max(0, unref(container.stat).cpu) + '%'" />
<stat-monitor :data="cpuData" label="load" :stat-value="Math.max(0, unref(container.stat).cpu).toFixed(2) + '%'" />
</div>
</template>
@@ -15,7 +15,7 @@ const cpuData = computedWithControl(
const points: Point<unknown>[] = history.map((stat, i) => ({
x: i,
y: Math.max(0, stat.snapshot.cpu),
value: Math.max(0, stat.snapshot.cpu) + "%",
value: Math.max(0, stat.snapshot.cpu).toFixed(2) + "%",
}));
return points;
},

View File

@@ -7,7 +7,7 @@
<div class="stat-title">{{ $t("label.running") }} / {{ $t("label.total-containers") }}</div>
</div>
<div class="stat">
<div class="stat-value">{{ totalCpu }}%</div>
<div class="stat-value">{{ totalCpu.toFixed(0) }}%</div>
<div class="stat-title">{{ $t("label.total-cpu-usage") }}</div>
</div>
<div class="stat">

View File

@@ -15,3 +15,47 @@ func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 {
}
return float64(mem.Usage)
}
func calculateCPUPercentWindows(v *types.StatsJSON) float64 {
// Max number of 100ns intervals between the previous time read and now
possIntervals := uint64(v.Read.Sub(v.PreRead).Nanoseconds()) // Start with number of ns intervals
possIntervals /= 100 // Convert to number of 100ns intervals
possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors
// Intervals used
intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage
// Percentage avoiding divide-by-zero
if possIntervals > 0 {
return float64(intervalsUsed) / float64(possIntervals) * 100.0
}
return 0.00
}
func calculateMemPercentUnixNoCache(limit float64, usedNoCache float64) float64 {
// MemoryStats.Limit will never be 0 unless the container is not running and we haven't
// got any data from cgroup
if limit != 0 {
return usedNoCache / limit * 100.0
}
return 0
}
func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJSON) float64 {
var (
cpuPercent = 0.0
// calculate the change for the cpu usage of the container in between readings
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
// calculate the change for the entire system between readings
systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
onlineCPUs = float64(v.CPUStats.OnlineCPUs)
)
if onlineCPUs == 0.0 {
onlineCPUs = float64(len(v.CPUStats.CPUUsage.PercpuUsage))
}
if systemDelta > 0.0 && cpuDelta > 0.0 {
cpuPercent = (cpuDelta / systemDelta) * onlineCPUs * 100.0
}
return cpuPercent
}

View File

@@ -223,20 +223,29 @@ func (d *Client) ContainerStats(ctx context.Context, id string, stats chan<- Con
log.Errorf("decoder for stats api returned an unknown error %v", err)
}
ncpus := uint8(v.CPUStats.OnlineCPUs)
if ncpus == 0 {
ncpus = uint8(len(v.CPUStats.CPUUsage.PercpuUsage))
var (
memPercent, cpuPercent float64
mem, memLimit float64
previousCPU uint64
previousSystem uint64
)
daemonOSType := response.OSType
if daemonOSType != "windows" {
previousCPU = v.PreCPUStats.CPUUsage.TotalUsage
previousSystem = v.PreCPUStats.SystemUsage
cpuPercent = calculateCPUPercentUnix(previousCPU, previousSystem, v)
mem = calculateMemUsageUnixNoCache(v.MemoryStats)
memLimit = float64(v.MemoryStats.Limit)
memPercent = calculateMemPercentUnixNoCache(memLimit, mem)
} else {
cpuPercent = calculateCPUPercentWindows(v)
mem = float64(v.MemoryStats.PrivateWorkingSet)
}
var (
cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(v.PreCPUStats.CPUUsage.TotalUsage)
systemDelta = float64(v.CPUStats.SystemUsage) - float64(v.PreCPUStats.SystemUsage)
cpuPercent = int64((cpuDelta / systemDelta) * float64(ncpus) * 100)
memUsage = int64(calculateMemUsageUnixNoCache(v.MemoryStats))
memPercent = int64(float64(memUsage) / float64(v.MemoryStats.Limit) * 100)
)
log.Tracef("containerId = %s, cpuPercent = %f, memPercent = %f, memUsage = %f, daemonOSType = %s", id, cpuPercent, memPercent, mem, daemonOSType)
if cpuPercent > 0 || memUsage > 0 {
if cpuPercent > 0 || mem > 0 {
select {
case <-ctx.Done():
return
@@ -244,7 +253,7 @@ func (d *Client) ContainerStats(ctx context.Context, id string, stats chan<- Con
ID: id,
CPUPercent: cpuPercent,
MemoryPercent: memPercent,
MemoryUsage: memUsage,
MemoryUsage: mem,
}:
}
}

View File

@@ -23,10 +23,10 @@ type Container struct {
// ContainerStat represent stats instant for a container
type ContainerStat struct {
ID string `json:"id"`
CPUPercent int64 `json:"cpu"`
MemoryPercent int64 `json:"memory"`
MemoryUsage int64 `json:"memoryUsage"`
ID string `json:"id"`
CPUPercent float64 `json:"cpu"`
MemoryPercent float64 `json:"memory"`
MemoryUsage float64 `json:"memoryUsage"`
}
// ContainerEvent represents events that are triggered