...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package procfs
18
19 import (
20 "bufio"
21 "errors"
22 "fmt"
23 "os"
24 "regexp"
25 "strconv"
26 "strings"
27
28 "github.com/prometheus/procfs/internal/util"
29 )
30
31 var (
32
33 procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)
34 )
35
36 type ProcSMapsRollup struct {
37
38 Rss uint64
39
40 Pss uint64
41
42 SharedClean uint64
43
44 SharedDirty uint64
45
46 PrivateClean uint64
47
48 PrivateDirty uint64
49
50 Referenced uint64
51
52 Anonymous uint64
53
54 Swap uint64
55
56 SwapPss uint64
57 }
58
59
60
61
62
63
64 func (p Proc) ProcSMapsRollup() (ProcSMapsRollup, error) {
65 data, err := util.ReadFileNoStat(p.path("smaps_rollup"))
66 if err != nil && os.IsNotExist(err) {
67 return p.procSMapsRollupManual()
68 }
69 if err != nil {
70 return ProcSMapsRollup{}, err
71 }
72
73 lines := strings.Split(string(data), "\n")
74 smaps := ProcSMapsRollup{}
75
76
77 lines = lines[1:]
78 for _, line := range lines {
79 if line == "" {
80 continue
81 }
82
83 if err := smaps.parseLine(line); err != nil {
84 return ProcSMapsRollup{}, err
85 }
86 }
87
88 return smaps, nil
89 }
90
91
92 func (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) {
93 file, err := os.Open(p.path("smaps"))
94 if err != nil {
95 return ProcSMapsRollup{}, err
96 }
97 defer file.Close()
98
99 smaps := ProcSMapsRollup{}
100 scan := bufio.NewScanner(file)
101
102 for scan.Scan() {
103 line := scan.Text()
104
105 if procSMapsHeaderLine.MatchString(line) {
106 continue
107 }
108
109 if err := smaps.parseLine(line); err != nil {
110 return ProcSMapsRollup{}, err
111 }
112 }
113
114 return smaps, nil
115 }
116
117 func (s *ProcSMapsRollup) parseLine(line string) error {
118 kv := strings.SplitN(line, ":", 2)
119 if len(kv) != 2 {
120 fmt.Println(line)
121 return errors.New("invalid net/dev line, missing colon")
122 }
123
124 k := kv[0]
125 if k == "VmFlags" {
126 return nil
127 }
128
129 v := strings.TrimSpace(kv[1])
130 v = strings.TrimRight(v, " kB")
131
132 vKBytes, err := strconv.ParseUint(v, 10, 64)
133 if err != nil {
134 return err
135 }
136 vBytes := vKBytes * 1024
137
138 s.addValue(k, vBytes)
139
140 return nil
141 }
142
143 func (s *ProcSMapsRollup) addValue(k string, vUintBytes uint64) {
144 switch k {
145 case "Rss":
146 s.Rss += vUintBytes
147 case "Pss":
148 s.Pss += vUintBytes
149 case "Shared_Clean":
150 s.SharedClean += vUintBytes
151 case "Shared_Dirty":
152 s.SharedDirty += vUintBytes
153 case "Private_Clean":
154 s.PrivateClean += vUintBytes
155 case "Private_Dirty":
156 s.PrivateDirty += vUintBytes
157 case "Referenced":
158 s.Referenced += vUintBytes
159 case "Anonymous":
160 s.Anonymous += vUintBytes
161 case "Swap":
162 s.Swap += vUintBytes
163 case "SwapPss":
164 s.SwapPss += vUintBytes
165 }
166 }
167
View as plain text