Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Open
1 task done

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.

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

No branches or pull requests

2 participants