cubefs
121 строка · 3.0 Кб
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
14package procfs15
16import (17"bufio"18"errors"19"os"20"regexp"21"strconv"22)
23
24var (25cpuLineRE = regexp.MustCompile(`cpu(\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)`)26procLineRE = regexp.MustCompile(`(\d+) (\d+) (\d+)`)27)
28
29// Schedstat contains scheduler statistics from /proc/schedstat
30//
31// See
32// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt
33// for a detailed description of what these numbers mean.
34//
35// Note the current kernel documentation claims some of the time units are in
36// jiffies when they are actually in nanoseconds since 2.6.23 with the
37// introduction of CFS. A fix to the documentation is pending. See
38// https://lore.kernel.org/patchwork/project/lkml/list/?series=403473
39type Schedstat struct {40CPUs []*SchedstatCPU41}
42
43// SchedstatCPU contains the values from one "cpu<N>" line.
44type SchedstatCPU struct {45CPUNum string46
47RunningNanoseconds uint6448WaitingNanoseconds uint6449RunTimeslices uint6450}
51
52// ProcSchedstat contains the values from `/proc/<pid>/schedstat`.
53type ProcSchedstat struct {54RunningNanoseconds uint6455WaitingNanoseconds uint6456RunTimeslices uint6457}
58
59// Schedstat reads data from `/proc/schedstat`.
60func (fs FS) Schedstat() (*Schedstat, error) {61file, err := os.Open(fs.proc.Path("schedstat"))62if err != nil {63return nil, err64}65defer file.Close()66
67stats := &Schedstat{}68scanner := bufio.NewScanner(file)69
70for scanner.Scan() {71match := cpuLineRE.FindStringSubmatch(scanner.Text())72if match != nil {73cpu := &SchedstatCPU{}74cpu.CPUNum = match[1]75
76cpu.RunningNanoseconds, err = strconv.ParseUint(match[8], 10, 64)77if err != nil {78continue79}80
81cpu.WaitingNanoseconds, err = strconv.ParseUint(match[9], 10, 64)82if err != nil {83continue84}85
86cpu.RunTimeslices, err = strconv.ParseUint(match[10], 10, 64)87if err != nil {88continue89}90
91stats.CPUs = append(stats.CPUs, cpu)92}93}94
95return stats, nil96}
97
98func parseProcSchedstat(contents string) (ProcSchedstat, error) {99var (100stats ProcSchedstat
101err error102)103match := procLineRE.FindStringSubmatch(contents)104
105if match != nil {106stats.RunningNanoseconds, err = strconv.ParseUint(match[1], 10, 64)107if err != nil {108return stats, err109}110
111stats.WaitingNanoseconds, err = strconv.ParseUint(match[2], 10, 64)112if err != nil {113return stats, err114}115
116stats.RunTimeslices, err = strconv.ParseUint(match[3], 10, 64)117return stats, err118}119
120return stats, errors.New("could not parse schedstat")121}
122