Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.5 KiB
102 lines
2.5 KiB
// Copyright 2019 The Prometheus 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 procfs |
|
|
|
import ( |
|
"bufio" |
|
"bytes" |
|
"fmt" |
|
"io" |
|
"strconv" |
|
"strings" |
|
|
|
"github.com/prometheus/procfs/internal/util" |
|
) |
|
|
|
// For the proc file format details, |
|
// See: |
|
// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343 |
|
// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 |
|
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. |
|
|
|
// SoftnetStat contains a single row of data from /proc/net/softnet_stat |
|
type SoftnetStat struct { |
|
// Number of processed packets |
|
Processed uint32 |
|
// Number of dropped packets |
|
Dropped uint32 |
|
// Number of times processing packets ran out of quota |
|
TimeSqueezed uint32 |
|
} |
|
|
|
var softNetProcFile = "net/softnet_stat" |
|
|
|
// NetSoftnetStat reads data from /proc/net/softnet_stat. |
|
func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) { |
|
b, err := util.ReadFileNoStat(fs.proc.Path(softNetProcFile)) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
entries, err := parseSoftnet(bytes.NewReader(b)) |
|
if err != nil { |
|
return nil, fmt.Errorf("failed to parse /proc/net/softnet_stat: %v", err) |
|
} |
|
|
|
return entries, nil |
|
} |
|
|
|
func parseSoftnet(r io.Reader) ([]SoftnetStat, error) { |
|
const minColumns = 9 |
|
|
|
s := bufio.NewScanner(r) |
|
|
|
var stats []SoftnetStat |
|
for s.Scan() { |
|
columns := strings.Fields(s.Text()) |
|
width := len(columns) |
|
|
|
if width < minColumns { |
|
return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns) |
|
} |
|
|
|
// We only parse the first three columns at the moment. |
|
us, err := parseHexUint32s(columns[0:3]) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
stats = append(stats, SoftnetStat{ |
|
Processed: us[0], |
|
Dropped: us[1], |
|
TimeSqueezed: us[2], |
|
}) |
|
} |
|
|
|
return stats, nil |
|
} |
|
|
|
func parseHexUint32s(ss []string) ([]uint32, error) { |
|
us := make([]uint32, 0, len(ss)) |
|
for _, s := range ss { |
|
u, err := strconv.ParseUint(s, 16, 32) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
us = append(us, uint32(u)) |
|
} |
|
|
|
return us, nil |
|
}
|
|
|