cubefs

Форк
0
166 строк · 3.9 Кб
1
// Copyright 2020 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

14
//go:build !windows
15
// +build !windows
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
	// match the header line before each mapped zone in `/proc/pid/smaps`.
33
	procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)
34
)
35

36
type ProcSMapsRollup struct {
37
	// Amount of the mapping that is currently resident in RAM.
38
	Rss uint64
39
	// Process's proportional share of this mapping.
40
	Pss uint64
41
	// Size in bytes of clean shared pages.
42
	SharedClean uint64
43
	// Size in bytes of dirty shared pages.
44
	SharedDirty uint64
45
	// Size in bytes of clean private pages.
46
	PrivateClean uint64
47
	// Size in bytes of dirty private pages.
48
	PrivateDirty uint64
49
	// Amount of memory currently marked as referenced or accessed.
50
	Referenced uint64
51
	// Amount of memory that does not belong to any file.
52
	Anonymous uint64
53
	// Amount would-be-anonymous memory currently on swap.
54
	Swap uint64
55
	// Process's proportional memory on swap.
56
	SwapPss uint64
57
}
58

59
// ProcSMapsRollup reads from /proc/[pid]/smaps_rollup to get summed memory information of the
60
// process.
61
//
62
// If smaps_rollup does not exists (require kernel >= 4.15), the content of /proc/pid/smaps will
63
// we read and summed.
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
	// skip first line which don't contains information we need
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
// Read /proc/pid/smaps and do the roll-up in Go code.
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, v, vKBytes, vBytes)
139

140
	return nil
141
}
142

143
func (s *ProcSMapsRollup) addValue(k string, vString string, vUint uint64, 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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.