Report memory stats using the same logic that docker uses for stats output; avoid extreme differences in output

This commit is contained in:
Dane Everitt 2020-05-08 22:06:26 -07:00
parent a6645aa741
commit 483b652087
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
2 changed files with 27 additions and 4 deletions

View File

@ -501,7 +501,7 @@ func (d *DockerEnvironment) EnableResourcePolling() error {
} }
s.Resources.CpuAbsolute = s.Resources.CalculateAbsoluteCpu(&v.PreCPUStats, &v.CPUStats) s.Resources.CpuAbsolute = s.Resources.CalculateAbsoluteCpu(&v.PreCPUStats, &v.CPUStats)
s.Resources.Memory = v.MemoryStats.Usage s.Resources.Memory = s.Resources.CalculateDockerMemory(v.MemoryStats)
s.Resources.MemoryLimit = v.MemoryStats.Limit s.Resources.MemoryLimit = v.MemoryStats.Limit
// Why you ask? This already has the logic for caching disk space in use and then // Why you ask? This already has the logic for caching disk space in use and then
@ -827,7 +827,6 @@ func (d *DockerEnvironment) exposedPorts() nat.PortSet {
return out return out
} }
// Formats the resources available to a server instance in such as way that Docker will // Formats the resources available to a server instance in such as way that Docker will
// generate a matching environment in the container. // generate a matching environment in the container.
// //

View File

@ -9,7 +9,10 @@ import (
// should obviously expect memory and CPU usage to be 0. However, disk will always be returned // should obviously expect memory and CPU usage to be 0. However, disk will always be returned
// since that is not dependent on the server being running to collect that data. // since that is not dependent on the server being running to collect that data.
type ResourceUsage struct { type ResourceUsage struct {
// The total amount of memory, in bytes, that this server instance is consuming. // The total amount of memory, in bytes, that this server instance is consuming. This is
// calculated slightly differently than just using the raw Memory field that the stats
// return from the container, so please check the code setting this value for how that
// is calculated.
Memory uint64 `json:"memory_bytes"` Memory uint64 `json:"memory_bytes"`
// The total amount of memory this container or resource can use. Inside Docker this is // The total amount of memory this container or resource can use. Inside Docker this is
// going to be higher than you'd expect because we're automatically allocating overhead // going to be higher than you'd expect because we're automatically allocating overhead
@ -28,6 +31,27 @@ type ResourceUsage struct {
} `json:"network"` } `json:"network"`
} }
// The "docker stats" CLI call does not return the same value as the types.MemoryStats.Usage
// value which can be rather confusing to people trying to compare panel usage to
// their stats output.
//
// This math is straight up lifted from their CLI repository in order to show the same
// values to avoid people bothering me about it. It should also reflect a slightly more
// correct memory value anyways.
//
// @see https://github.com/docker/cli/blob/96e1d1d6/cli/command/container/stats_helpers.go#L227-L249
func (ru *ResourceUsage) CalculateDockerMemory(stats types.MemoryStats) uint64 {
if v, ok := stats.Stats["total_inactive_file"]; ok && v < stats.Usage {
return stats.Usage - v
}
if v := stats.Stats["inactive_file"]; v < stats.Usage {
return stats.Usage - v
}
return stats.Usage
}
// Calculates the absolute CPU usage used by the server process on the system, not constrained // Calculates the absolute CPU usage used by the server process on the system, not constrained
// by the defined CPU limits on the container. // by the defined CPU limits on the container.
// //