1// Copyright 2018 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package procfs 15 16import ( 17 "bytes" 18 "io/ioutil" 19 "os" 20 "strconv" 21 "strings" 22) 23 24// ProcStat provides status information about the process, 25// read from /proc/[pid]/stat. 26type ProcStatus struct { 27 // The process ID. 28 PID int 29 // The process name. 30 Name string 31 32 // Peak virtual memory size. 33 VmPeak uint64 34 // Virtual memory size. 35 VmSize uint64 36 // Locked memory size. 37 VmLck uint64 38 // Pinned memory size. 39 VmPin uint64 40 // Peak resident set size. 41 VmHWM uint64 42 // Resident set size (sum of RssAnnon RssFile and RssShmem). 43 VmRSS uint64 44 // Size of resident anonymous memory. 45 RssAnon uint64 46 // Size of resident file mappings. 47 RssFile uint64 48 // Size of resident shared memory. 49 RssShmem uint64 50 // Size of data segments. 51 VmData uint64 52 // Size of stack segments. 53 VmStk uint64 54 // Size of text segments. 55 VmExe uint64 56 // Shared library code size. 57 VmLib uint64 58 // Page table entries size. 59 VmPTE uint64 60 // Size of second-level page tables. 61 VmPMD uint64 62 // Swapped-out virtual memory size by anonymous private. 63 VmSwap uint64 64 // Size of hugetlb memory portions 65 HugetlbPages uint64 66 67 // Number of voluntary context switches. 68 VoluntaryCtxtSwitches uint64 69 // Number of involuntary context switches. 70 NonVoluntaryCtxtSwitches uint64 71} 72 73// NewStatus returns the current status information of the process. 74func (p Proc) NewStatus() (ProcStatus, error) { 75 f, err := os.Open(p.path("status")) 76 if err != nil { 77 return ProcStatus{}, err 78 } 79 defer f.Close() 80 81 data, err := ioutil.ReadAll(f) 82 if err != nil { 83 return ProcStatus{}, err 84 } 85 86 s := ProcStatus{PID: p.PID} 87 88 lines := strings.Split(string(data), "\n") 89 for _, line := range lines { 90 if !bytes.Contains([]byte(line), []byte(":")) { 91 continue 92 } 93 94 kv := strings.SplitN(line, ":", 2) 95 96 // removes spaces 97 k := string(strings.TrimSpace(kv[0])) 98 v := string(strings.TrimSpace(kv[1])) 99 // removes "kB" 100 v = string(bytes.Trim([]byte(v), " kB")) 101 102 // value to int when possible 103 // we can skip error check here, 'cause vKBytes is not used when value is a string 104 vKBytes, _ := strconv.ParseUint(v, 10, 64) 105 // convert kB to B 106 vBytes := vKBytes * 1024 107 108 s.fillStatus(k, v, vKBytes, vBytes) 109 } 110 111 return s, nil 112} 113 114func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) { 115 switch k { 116 case "Name": 117 s.Name = vString 118 case "VmPeak": 119 s.VmPeak = vUintBytes 120 case "VmSize": 121 s.VmSize = vUintBytes 122 case "VmLck": 123 s.VmLck = vUintBytes 124 case "VmPin": 125 s.VmPin = vUintBytes 126 case "VmHWM": 127 s.VmHWM = vUintBytes 128 case "VmRSS": 129 s.VmRSS = vUintBytes 130 case "RssAnon": 131 s.RssAnon = vUintBytes 132 case "RssFile": 133 s.RssFile = vUintBytes 134 case "RssShmem": 135 s.RssShmem = vUintBytes 136 case "VmData": 137 s.VmData = vUintBytes 138 case "VmStk": 139 s.VmStk = vUintBytes 140 case "VmExe": 141 s.VmExe = vUintBytes 142 case "VmLib": 143 s.VmLib = vUintBytes 144 case "VmPTE": 145 s.VmPTE = vUintBytes 146 case "VmPMD": 147 s.VmPMD = vUintBytes 148 case "VmSwap": 149 s.VmSwap = vUintBytes 150 case "HugetlbPages": 151 s.HugetlbPages = vUintBytes 152 case "voluntary_ctxt_switches": 153 s.VoluntaryCtxtSwitches = vUint 154 case "nonvoluntary_ctxt_switches": 155 s.NonVoluntaryCtxtSwitches = vUint 156 } 157} 158 159// TotalCtxtSwitches returns the total context switch. 160func (s ProcStatus) TotalCtxtSwitches() uint64 { 161 return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches 162} 163