-
Notifications
You must be signed in to change notification settings - Fork 315
/
psi_file.go
96 lines (81 loc) · 2.26 KB
/
psi_file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
Copyright 2022 The Koordinator Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package system
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"strings"
"k8s.io/klog/v2"
)
const psiLineFormat = "avg10=%f avg60=%f avg300=%f total=%d"
type PSILine struct {
Avg10 float64
Avg60 float64
Avg300 float64
Total uint64
}
type PSIStats struct {
Some *PSILine
Full *PSILine
FullSupported bool
}
func ReadPSI(pressureFilePath string) (PSIStats, error) {
fileContents, err := os.ReadFile(pressureFilePath)
if err != nil {
return PSIStats{}, err
}
//todo: delete these logs after panic handled
klog.V(4).Infof("read psi file contents: %s", string(fileContents))
stats, err := parsePSIStats(bytes.NewReader(fileContents))
if err != nil {
return PSIStats{}, err
}
return stats, nil
}
// parsePSIStats parses the specified file for pressure stall information.
func parsePSIStats(r io.Reader) (PSIStats, error) {
psiStats := PSIStats{}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
l := scanner.Text()
prefix := strings.Split(l, " ")[0]
switch prefix {
case "some":
psi := PSILine{}
_, err := fmt.Sscanf(l, fmt.Sprintf("some %s", psiLineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
if err != nil {
return PSIStats{}, err
}
psiStats.Some = &psi
case "full":
psi := PSILine{}
_, err := fmt.Sscanf(l, fmt.Sprintf("full %s", psiLineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
if err != nil {
return PSIStats{}, err
}
psiStats.Full = &psi
default:
return PSIStats{}, fmt.Errorf("unknown PSI prefix: %s", prefix)
}
}
// full cpu pressure not supported in old kernel versions
psiStats.FullSupported = true
if psiStats.Full == nil {
psiStats.FullSupported = false
psiStats.Full = &PSILine{}
}
return psiStats, nil
}