source: code/trunk/vendor/github.com/prometheus/procfs/softirqs.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 4.7 KB
Line 
1// Copyright 2022 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 "bufio"
18 "bytes"
19 "fmt"
20 "io"
21 "strconv"
22 "strings"
23
24 "github.com/prometheus/procfs/internal/util"
25)
26
27// Softirqs represents the softirq statistics.
28type Softirqs struct {
29 Hi []uint64
30 Timer []uint64
31 NetTx []uint64
32 NetRx []uint64
33 Block []uint64
34 IRQPoll []uint64
35 Tasklet []uint64
36 Sched []uint64
37 HRTimer []uint64
38 RCU []uint64
39}
40
41func (fs FS) Softirqs() (Softirqs, error) {
42 fileName := fs.proc.Path("softirqs")
43 data, err := util.ReadFileNoStat(fileName)
44 if err != nil {
45 return Softirqs{}, err
46 }
47
48 reader := bytes.NewReader(data)
49
50 return parseSoftirqs(reader)
51}
52
53func parseSoftirqs(r io.Reader) (Softirqs, error) {
54 var (
55 softirqs = Softirqs{}
56 scanner = bufio.NewScanner(r)
57 )
58
59 if !scanner.Scan() {
60 return Softirqs{}, fmt.Errorf("softirqs empty")
61 }
62
63 for scanner.Scan() {
64 parts := strings.Fields(scanner.Text())
65 var err error
66
67 // require at least one cpu
68 if len(parts) < 2 {
69 continue
70 }
71 switch {
72 case parts[0] == "HI:":
73 perCPU := parts[1:]
74 softirqs.Hi = make([]uint64, len(perCPU))
75 for i, count := range perCPU {
76 if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil {
77 return Softirqs{}, fmt.Errorf("couldn't parse %q (HI%d): %w", count, i, err)
78 }
79 }
80 case parts[0] == "TIMER:":
81 perCPU := parts[1:]
82 softirqs.Timer = make([]uint64, len(perCPU))
83 for i, count := range perCPU {
84 if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil {
85 return Softirqs{}, fmt.Errorf("couldn't parse %q (TIMER%d): %w", count, i, err)
86 }
87 }
88 case parts[0] == "NET_TX:":
89 perCPU := parts[1:]
90 softirqs.NetTx = make([]uint64, len(perCPU))
91 for i, count := range perCPU {
92 if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil {
93 return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_TX%d): %w", count, i, err)
94 }
95 }
96 case parts[0] == "NET_RX:":
97 perCPU := parts[1:]
98 softirqs.NetRx = make([]uint64, len(perCPU))
99 for i, count := range perCPU {
100 if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil {
101 return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_RX%d): %w", count, i, err)
102 }
103 }
104 case parts[0] == "BLOCK:":
105 perCPU := parts[1:]
106 softirqs.Block = make([]uint64, len(perCPU))
107 for i, count := range perCPU {
108 if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil {
109 return Softirqs{}, fmt.Errorf("couldn't parse %q (BLOCK%d): %w", count, i, err)
110 }
111 }
112 case parts[0] == "IRQ_POLL:":
113 perCPU := parts[1:]
114 softirqs.IRQPoll = make([]uint64, len(perCPU))
115 for i, count := range perCPU {
116 if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil {
117 return Softirqs{}, fmt.Errorf("couldn't parse %q (IRQ_POLL%d): %w", count, i, err)
118 }
119 }
120 case parts[0] == "TASKLET:":
121 perCPU := parts[1:]
122 softirqs.Tasklet = make([]uint64, len(perCPU))
123 for i, count := range perCPU {
124 if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil {
125 return Softirqs{}, fmt.Errorf("couldn't parse %q (TASKLET%d): %w", count, i, err)
126 }
127 }
128 case parts[0] == "SCHED:":
129 perCPU := parts[1:]
130 softirqs.Sched = make([]uint64, len(perCPU))
131 for i, count := range perCPU {
132 if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil {
133 return Softirqs{}, fmt.Errorf("couldn't parse %q (SCHED%d): %w", count, i, err)
134 }
135 }
136 case parts[0] == "HRTIMER:":
137 perCPU := parts[1:]
138 softirqs.HRTimer = make([]uint64, len(perCPU))
139 for i, count := range perCPU {
140 if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil {
141 return Softirqs{}, fmt.Errorf("couldn't parse %q (HRTIMER%d): %w", count, i, err)
142 }
143 }
144 case parts[0] == "RCU:":
145 perCPU := parts[1:]
146 softirqs.RCU = make([]uint64, len(perCPU))
147 for i, count := range perCPU {
148 if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil {
149 return Softirqs{}, fmt.Errorf("couldn't parse %q (RCU%d): %w", count, i, err)
150 }
151 }
152 }
153 }
154
155 if err := scanner.Err(); err != nil {
156 return Softirqs{}, fmt.Errorf("couldn't parse softirqs: %w", err)
157 }
158
159 return softirqs, scanner.Err()
160}
Note: See TracBrowser for help on using the repository browser.