meminfo_linux.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package system
  2. import (
  3. "bufio"
  4. "io"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "github.com/docker/go-units"
  9. )
  10. // ReadMemInfo retrieves memory statistics of the host system and returns a
  11. // MemInfo type.
  12. func ReadMemInfo() (*MemInfo, error) {
  13. file, err := os.Open("/proc/meminfo")
  14. if err != nil {
  15. return nil, err
  16. }
  17. defer file.Close()
  18. return parseMemInfo(file)
  19. }
  20. // parseMemInfo parses the /proc/meminfo file into
  21. // a MemInfo object given an io.Reader to the file.
  22. // Throws error if there are problems reading from the file
  23. func parseMemInfo(reader io.Reader) (*MemInfo, error) {
  24. meminfo := &MemInfo{}
  25. scanner := bufio.NewScanner(reader)
  26. for scanner.Scan() {
  27. // Expected format: ["MemTotal:", "1234", "kB"]
  28. parts := strings.Fields(scanner.Text())
  29. // Sanity checks: Skip malformed entries.
  30. if len(parts) < 3 || parts[2] != "kB" {
  31. continue
  32. }
  33. // Convert to bytes.
  34. size, err := strconv.Atoi(parts[1])
  35. if err != nil {
  36. continue
  37. }
  38. bytes := int64(size) * units.KiB
  39. switch parts[0] {
  40. case "MemTotal:":
  41. meminfo.MemTotal = bytes
  42. case "MemFree:":
  43. meminfo.MemFree = bytes
  44. case "SwapTotal:":
  45. meminfo.SwapTotal = bytes
  46. case "SwapFree:":
  47. meminfo.SwapFree = bytes
  48. }
  49. }
  50. // Handle errors that may have occurred during the reading of the file.
  51. if err := scanner.Err(); err != nil {
  52. return nil, err
  53. }
  54. return meminfo, nil
  55. }