Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[BUG] github.com/shirou/gopsutil/v4/mem not correctly working WITHIN a docker container. #1758

Open
1 task done
the-hotmann opened this issue Dec 19, 2024 · 1 comment

Comments

@the-hotmann
Copy link

the-hotmann commented Dec 19, 2024

Describe the bug
When my golang application runs in a container, it does read the limits from the Host and not from the current container it resides in.

To Reproduce

  1. docker-compose.yml:
[...]
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: '6'
func GetTotalRAMInMB() string {

	memory, err := mem.VirtualMemory()
	if err != nil {
		return "unknown"
	}

	return fmt.Sprintf("%d MB", memory.Available/1024/1024)
}

it results in "131072 MB" ca. 128GB. The problem is: the container is limited to 4G and can not get more than this!

Expected behavior
Since I can easily read/get the actual total available memory (within a container) by reading this file: /sys/fs/cgroup/memory.max (available within a container!) I think the tool shall report back what actually is available to the container (if within a container) as the host does not really matter. If the host has 12GB, 128GB or 1TB RAM does not matter to the container. For within a container solely its available memory is relevant.

Environment (please complete the following information):

  • docker scratch container. Sorry nothing to grep here ..

Additional context
I did not cross compile. I am still using Linux (Debian Testing) under the hood. Here the /etc/os-release from the host.

/etc/os-release

PRETTY_NAME="Debian GNU/Linux trixie/sid"
NAME="Debian GNU/Linux"
VERSION_CODENAME=trixie
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Some time ago I already encountered this issue and now, since it is the second time, I thought maybe opening an issue is worth it ;)
Feel free to convert this to a feature request if you like to.

Also, in the meantime I made my own little function that gets me what I want, so I wanted to share it, maybe it can be implemented in the package ;)

func GetAvailableRAMInMB() string {

	const (
		maxMemoryFile = "/sys/fs/cgroup/memory.max"
	)

	data, err := os.ReadFile(maxMemoryFile)
	if err != nil {
		fmt.Println(fmt.Errorf("failed to read %s: %w", maxMemoryFile, err))
		return "unknown"
	}

	memoryLimitInBytes, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
	if err != nil {
		fmt.Println(fmt.Errorf("failed to parse %s: %w", maxMemoryFile, err))
		return "unknown"
	}

	return fmt.Sprintf("%d MB", memoryLimitInBytes/1024/1024)

}

since your tool does not give back MBs this version probably would be better for you:

func GetAvailableRAM() uint64, error {

	const (
		maxMemoryFile = "/sys/fs/cgroup/memory.max"
	)

	data, err := os.ReadFile(maxMemoryFile)
	if err != nil {
		fmt.Println(fmt.Errorf("failed to read %s: %w", maxMemoryFile, err))
		return 0, err
	}

	memoryLimitInBytes, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
	if err != nil {
		fmt.Println(fmt.Errorf("failed to parse %s: %w", maxMemoryFile, err))
		return 0, err
	}

	return memoryLimitInBytes, nil

}
@shirou
Copy link
Owner

shirou commented Dec 21, 2024

Sorry, but gopsutil does not currently support cgroups. As a result, it only references information under the proc directory, not cgroup limitations.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants