github.com/elastic/gosigar@v0.14.3/cgroup/memory.go (about)

     1  package cgroup
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  	"path/filepath"
     7  )
     8  
     9  // MemorySubsystem contains the metrics and limits from the "memory" subsystem.
    10  type MemorySubsystem struct {
    11  	Metadata
    12  	Mem       MemoryData `json:"mem"`      // Memory usage by tasks in this cgroup.
    13  	MemSwap   MemoryData `json:"memsw"`    // Memory plus swap usage by tasks in this cgroup.
    14  	Kernel    MemoryData `json:"kmem"`     // Kernel memory used by tasks in this cgroup.
    15  	KernelTCP MemoryData `json:"kmem_tcp"` // Kernel TCP buffer memory used by tasks in this cgroup.
    16  	Stats     MemoryStat `json:"stats"`    // A wide range of memory statistics.
    17  }
    18  
    19  // MemoryData groups related memory usage metrics and limits.
    20  type MemoryData struct {
    21  	Usage     uint64 `json:"usage"`         // Usage in bytes.
    22  	MaxUsage  uint64 `json:"max_usage"`     // Max usage in bytes.
    23  	Limit     uint64 `json:"limit"`         // Limit in bytes.
    24  	FailCount uint64 `json:"failure_count"` // Number of times the memory limit has been reached.
    25  }
    26  
    27  // MemoryStat contains various memory statistics and accounting information
    28  // associated with a cgroup.
    29  type MemoryStat struct {
    30  	// Page cache, including tmpfs (shmem), in bytes.
    31  	Cache uint64 `json:"cache"`
    32  	// Anonymous and swap cache, not including tmpfs (shmem), in bytes.
    33  	RSS uint64 `json:"rss"`
    34  	// Anonymous transparent hugepages in bytes.
    35  	RSSHuge uint64 `json:"rss_huge"`
    36  	// Size of memory-mapped mapped files, including tmpfs (shmem), in bytes.
    37  	MappedFile uint64 `json:"mapped_file"`
    38  	// Number of pages paged into memory.
    39  	PagesIn uint64 `json:"pgpgin"`
    40  	// Number of pages paged out of memory.
    41  	PagesOut uint64 `json:"pgpgout"`
    42  	// Number of times a task in the cgroup triggered a page fault.
    43  	PageFaults uint64 `json:"pgfault"`
    44  	// Number of times a task in the cgroup triggered a major page fault.
    45  	MajorPageFaults uint64 `json:"pgmajfault"`
    46  	// Swap usage in bytes.
    47  	Swap uint64 `json:"swap"`
    48  	// Anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs (shmem), in bytes.
    49  	ActiveAnon uint64 `json:"active_anon"`
    50  	// Anonymous and swap cache on inactive LRU list, including tmpfs (shmem), in bytes.
    51  	InactiveAnon uint64 `json:"inactive_anon"`
    52  	// File-backed memory on active LRU list, in bytes.
    53  	ActiveFile uint64 `json:"active_file"`
    54  	// File-backed memory on inactive LRU list, in bytes.
    55  	InactiveFile uint64 `json:"inactive_file"`
    56  	// Memory that cannot be reclaimed, in bytes.
    57  	Unevictable uint64 `json:"unevictable"`
    58  	// Memory limit for the hierarchy that contains the memory cgroup, in bytes.
    59  	HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"`
    60  	// Memory plus swap limit for the hierarchy that contains the memory cgroup, in bytes.
    61  	HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit"`
    62  }
    63  
    64  // get reads metrics from the "memory" subsystem. path is the filepath to the
    65  // cgroup hierarchy to read.
    66  func (mem *MemorySubsystem) get(path string) error {
    67  	if err := memoryData(path, "memory", &mem.Mem); err != nil {
    68  		return err
    69  	}
    70  
    71  	if err := memoryData(path, "memory.memsw", &mem.MemSwap); err != nil {
    72  		return err
    73  	}
    74  
    75  	if err := memoryData(path, "memory.kmem", &mem.Kernel); err != nil {
    76  		return err
    77  	}
    78  
    79  	if err := memoryData(path, "memory.kmem.tcp", &mem.KernelTCP); err != nil {
    80  		return err
    81  	}
    82  
    83  	if err := memoryStats(path, mem); err != nil {
    84  		return err
    85  	}
    86  
    87  	return nil
    88  }
    89  
    90  func memoryData(path, prefix string, data *MemoryData) error {
    91  	var err error
    92  	data.Usage, err = parseUintFromFile(path, prefix+".usage_in_bytes")
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	data.MaxUsage, err = parseUintFromFile(path, prefix+".max_usage_in_bytes")
    98  	if err != nil {
    99  		return err
   100  	}
   101  
   102  	data.Limit, err = parseUintFromFile(path, prefix+".limit_in_bytes")
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	data.FailCount, err = parseUintFromFile(path, prefix+".failcnt")
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  func memoryStats(path string, mem *MemorySubsystem) error {
   116  	f, err := os.Open(filepath.Join(path, "memory.stat"))
   117  	if err != nil {
   118  		if os.IsNotExist(err) {
   119  			return nil
   120  		}
   121  		return err
   122  	}
   123  	defer f.Close()
   124  
   125  	sc := bufio.NewScanner(f)
   126  	for sc.Scan() {
   127  		t, v, err := parseCgroupParamKeyValue(sc.Text())
   128  		if err != nil {
   129  			return err
   130  		}
   131  		switch t {
   132  		case "cache":
   133  			mem.Stats.Cache = v
   134  		case "rss":
   135  			mem.Stats.RSS = v
   136  		case "rss_huge":
   137  			mem.Stats.RSSHuge = v
   138  		case "mapped_file":
   139  			mem.Stats.MappedFile = v
   140  		case "pgpgin":
   141  			mem.Stats.PagesIn = v
   142  		case "pgpgout":
   143  			mem.Stats.PagesOut = v
   144  		case "pgfault":
   145  			mem.Stats.PageFaults = v
   146  		case "pgmajfault":
   147  			mem.Stats.MajorPageFaults = v
   148  		case "swap":
   149  			mem.Stats.Swap = v
   150  		case "active_anon":
   151  			mem.Stats.ActiveAnon = v
   152  		case "inactive_anon":
   153  			mem.Stats.InactiveAnon = v
   154  		case "active_file":
   155  			mem.Stats.ActiveFile = v
   156  		case "inactive_file":
   157  			mem.Stats.InactiveFile = v
   158  		case "unevictable":
   159  			mem.Stats.Unevictable = v
   160  		case "hierarchical_memory_limit":
   161  			mem.Stats.HierarchicalMemoryLimit = v
   162  		case "hierarchical_memsw_limit":
   163  			mem.Stats.HierarchicalMemswLimit = v
   164  		}
   165  	}
   166  
   167  	return sc.Err()
   168  }