meminfo_linux.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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 a io.Reader to the file.
  22. //
  23. // Throws error if there are problems reading from the file
  24. func parseMemInfo(reader io.Reader) (*MemInfo, error) {
  25. meminfo := &MemInfo{}
  26. scanner := bufio.NewScanner(reader)
  27. for scanner.Scan() {
  28. // Expected format: ["MemTotal:", "1234", "kB"]
  29. parts := strings.Fields(scanner.Text())
  30. // Sanity checks: Skip malformed entries.
  31. if len(parts) < 3 || parts[2] != "kB" {
  32. continue
  33. }
  34. // Convert to bytes.
  35. size, err := strconv.Atoi(parts[1])
  36. if err != nil {
  37. continue
  38. }
  39. bytes := int64(size) * units.KiB
  40. switch parts[0] {
  41. case "MemTotal:":
  42. meminfo.MemTotal = bytes
  43. case "MemFree:":
  44. meminfo.MemFree = bytes
  45. case "SwapTotal:":
  46. meminfo.SwapTotal = bytes
  47. case "SwapFree:":
  48. meminfo.SwapFree = bytes
  49. }
  50. }
  51. // Handle errors that may have occurred during the reading of the file.
  52. if err := scanner.Err(); err != nil {
  53. return nil, err
  54. }
  55. return meminfo, nil
  56. }