cubefs
153 строки · 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
14package procfs15
16import (17"bufio"18"bytes"19"fmt"20"io"21"strconv"22"strings"23
24"github.com/prometheus/procfs/internal/util"25)
26
27// A ConntrackStatEntry represents one line from net/stat/nf_conntrack
28// and contains netfilter conntrack statistics at one CPU core.
29type ConntrackStatEntry struct {30Entries uint6431Found uint6432Invalid uint6433Ignore uint6434Insert uint6435InsertFailed uint6436Drop uint6437EarlyDrop uint6438SearchRestart uint6439}
40
41// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores.
42func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {43return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack"))44}
45
46// Parses a slice of ConntrackStatEntries from the given filepath.
47func readConntrackStat(path string) ([]ConntrackStatEntry, error) {48// This file is small and can be read with one syscall.49b, err := util.ReadFileNoStat(path)50if err != nil {51// Do not wrap this error so the caller can detect os.IsNotExist and52// similar conditions.53return nil, err54}55
56stat, err := parseConntrackStat(bytes.NewReader(b))57if err != nil {58return nil, fmt.Errorf("failed to read conntrack stats from %q: %w", path, err)59}60
61return stat, nil62}
63
64// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries.
65func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) {66var entries []ConntrackStatEntry67
68scanner := bufio.NewScanner(r)69scanner.Scan()70for scanner.Scan() {71fields := strings.Fields(scanner.Text())72conntrackEntry, err := parseConntrackStatEntry(fields)73if err != nil {74return nil, err75}76entries = append(entries, *conntrackEntry)77}78
79return entries, nil80}
81
82// Parses a ConntrackStatEntry from given array of fields.
83func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) {84if len(fields) != 17 {85return nil, fmt.Errorf("invalid conntrackstat entry, missing fields")86}87entry := &ConntrackStatEntry{}88
89entries, err := parseConntrackStatField(fields[0])90if err != nil {91return nil, err92}93entry.Entries = entries94
95found, err := parseConntrackStatField(fields[2])96if err != nil {97return nil, err98}99entry.Found = found100
101invalid, err := parseConntrackStatField(fields[4])102if err != nil {103return nil, err104}105entry.Invalid = invalid106
107ignore, err := parseConntrackStatField(fields[5])108if err != nil {109return nil, err110}111entry.Ignore = ignore112
113insert, err := parseConntrackStatField(fields[8])114if err != nil {115return nil, err116}117entry.Insert = insert118
119insertFailed, err := parseConntrackStatField(fields[9])120if err != nil {121return nil, err122}123entry.InsertFailed = insertFailed124
125drop, err := parseConntrackStatField(fields[10])126if err != nil {127return nil, err128}129entry.Drop = drop130
131earlyDrop, err := parseConntrackStatField(fields[11])132if err != nil {133return nil, err134}135entry.EarlyDrop = earlyDrop136
137searchRestart, err := parseConntrackStatField(fields[16])138if err != nil {139return nil, err140}141entry.SearchRestart = searchRestart142
143return entry, nil144}
145
146// Parses a uint64 from given hex in string.
147func parseConntrackStatField(field string) (uint64, error) {148val, err := strconv.ParseUint(field, 16, 64)149if err != nil {150return 0, fmt.Errorf("couldn't parse %q field: %w", field, err)151}152return val, err153}
154