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]