cubefs

Форк
0
102 строки · 3.3 Кб
1
// Copyright 2019 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
package procfs
15

16
// The PSI / pressure interface is described at
17
//   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/accounting/psi.txt
18
// Each resource (cpu, io, memory, ...) is exposed as a single file.
19
// Each file may contain up to two lines, one for "some" pressure and one for "full" pressure.
20
// Each line contains several averages (over n seconds) and a total in µs.
21
//
22
// Example io pressure file:
23
// > some avg10=0.06 avg60=0.21 avg300=0.99 total=8537362
24
// > full avg10=0.00 avg60=0.13 avg300=0.96 total=8183134
25

26
import (
27
	"bufio"
28
	"bytes"
29
	"fmt"
30
	"io"
31
	"strings"
32

33
	"github.com/prometheus/procfs/internal/util"
34
)
35

36
const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d"
37

38
// PSILine is a single line of values as returned by `/proc/pressure/*`.
39
//
40
// The Avg entries are averages over n seconds, as a percentage.
41
// The Total line is in microseconds.
42
type PSILine struct {
43
	Avg10  float64
44
	Avg60  float64
45
	Avg300 float64
46
	Total  uint64
47
}
48

49
// PSIStats represent pressure stall information from /proc/pressure/*
50
//
51
// "Some" indicates the share of time in which at least some tasks are stalled.
52
// "Full" indicates the share of time in which all non-idle tasks are stalled simultaneously.
53
type PSIStats struct {
54
	Some *PSILine
55
	Full *PSILine
56
}
57

58
// PSIStatsForResource reads pressure stall information for the specified
59
// resource from /proc/pressure/<resource>. At time of writing this can be
60
// either "cpu", "memory" or "io".
61
func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
62
	data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
63
	if err != nil {
64
		return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %q: %w", resource, err)
65
	}
66

67
	return parsePSIStats(resource, bytes.NewReader(data))
68
}
69

70
// parsePSIStats parses the specified file for pressure stall information.
71
func parsePSIStats(resource string, r io.Reader) (PSIStats, error) {
72
	psiStats := PSIStats{}
73

74
	scanner := bufio.NewScanner(r)
75
	for scanner.Scan() {
76
		l := scanner.Text()
77
		prefix := strings.Split(l, " ")[0]
78
		switch prefix {
79
		case "some":
80
			psi := PSILine{}
81
			_, err := fmt.Sscanf(l, fmt.Sprintf("some %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
82
			if err != nil {
83
				return PSIStats{}, err
84
			}
85
			psiStats.Some = &psi
86
		case "full":
87
			psi := PSILine{}
88
			_, err := fmt.Sscanf(l, fmt.Sprintf("full %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
89
			if err != nil {
90
				return PSIStats{}, err
91
			}
92
			psiStats.Full = &psi
93
		default:
94
			// If we encounter a line with an unknown prefix, ignore it and move on
95
			// Should new measurement types be added in the future we'll simply ignore them instead
96
			// of erroring on retrieval
97
			continue
98
		}
99
	}
100

101
	return psiStats, nil
102
}
103

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

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

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

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