pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/system/info_memory_linux.go (about) 1 package system 2 3 // ////////////////////////////////////////////////////////////////////////////////// // 4 // // 5 // Copyright (c) 2022 ESSENTIAL KAOS // 6 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 7 // // 8 // ////////////////////////////////////////////////////////////////////////////////// // 9 10 import ( 11 "bufio" 12 "errors" 13 14 "pkg.re/essentialkaos/ek.v12/strutil" 15 ) 16 17 // ////////////////////////////////////////////////////////////////////////////////// // 18 19 // Path to file with memory info in procfs 20 var procMemInfoFile = "/proc/meminfo" 21 22 // ////////////////////////////////////////////////////////////////////////////////// // 23 24 // GetMemUsage returns memory usage info 25 func GetMemUsage() (*MemUsage, error) { 26 s, closer, err := getFileScanner(procMemInfoFile) 27 28 if err != nil { 29 return nil, err 30 } 31 32 defer closer() 33 34 return parseMemUsage(s) 35 } 36 37 // ////////////////////////////////////////////////////////////////////////////////// // 38 39 // codebeat:disable[LOC,ABC] 40 41 // parseMemUsage parses memory usage info 42 func parseMemUsage(s *bufio.Scanner) (*MemUsage, error) { 43 var err error 44 45 mem := &MemUsage{} 46 47 for s.Scan() { 48 text := s.Text() 49 50 switch strutil.ReadField(text, 0, true) { 51 case "MemTotal:": 52 mem.MemTotal, err = parseSize(strutil.ReadField(text, 1, true)) 53 case "MemFree:": 54 mem.MemFree, err = parseSize(strutil.ReadField(text, 1, true)) 55 case "Buffers:": 56 mem.Buffers, err = parseSize(strutil.ReadField(text, 1, true)) 57 case "Cached:": 58 mem.Cached, err = parseSize(strutil.ReadField(text, 1, true)) 59 case "SwapCached:": 60 mem.SwapCached, err = parseSize(strutil.ReadField(text, 1, true)) 61 case "Active:": 62 mem.Active, err = parseSize(strutil.ReadField(text, 1, true)) 63 case "Inactive:": 64 mem.Inactive, err = parseSize(strutil.ReadField(text, 1, true)) 65 case "SwapTotal:": 66 mem.SwapTotal, err = parseSize(strutil.ReadField(text, 1, true)) 67 case "SwapFree:": 68 mem.SwapFree, err = parseSize(strutil.ReadField(text, 1, true)) 69 case "Dirty:": 70 mem.Dirty, err = parseSize(strutil.ReadField(text, 1, true)) 71 case "Shmem:": 72 mem.Shmem, err = parseSize(strutil.ReadField(text, 1, true)) 73 case "Slab:": 74 mem.Slab, err = parseSize(strutil.ReadField(text, 1, true)) 75 case "SReclaimable:": 76 mem.SReclaimable, err = parseSize(strutil.ReadField(text, 1, true)) 77 } 78 79 if err != nil { 80 return nil, errors.New("Can't parse file " + procMemInfoFile) 81 } 82 } 83 84 if mem.MemTotal == 0 { 85 return nil, errors.New("Can't parse file " + procMemInfoFile) 86 } 87 88 mem.MemFree += (mem.Cached + mem.Buffers + mem.SReclaimable) - mem.Shmem 89 mem.MemUsed = mem.MemTotal - mem.MemFree 90 mem.SwapUsed = mem.SwapTotal - mem.SwapFree 91 92 return mem, nil 93 } 94 95 // codebeat:enable[LOC,ABC]