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.
 
 

86 lines
2.1 KiB

  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. package procfs
  14. import (
  15. "bufio"
  16. "io"
  17. "os"
  18. "path/filepath"
  19. "strconv"
  20. "strings"
  21. )
  22. // NetStat contains statistics for all the counters from one file.
  23. type NetStat struct {
  24. Stats map[string][]uint64
  25. Filename string
  26. }
  27. // NetStat retrieves stats from `/proc/net/stat/`.
  28. func (fs FS) NetStat() ([]NetStat, error) {
  29. statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*"))
  30. if err != nil {
  31. return nil, err
  32. }
  33. var netStatsTotal []NetStat
  34. for _, filePath := range statFiles {
  35. file, err := os.Open(filePath)
  36. if err != nil {
  37. return nil, err
  38. }
  39. procNetstat, err := parseNetstat(file)
  40. if err != nil {
  41. return nil, err
  42. }
  43. procNetstat.Filename = filepath.Base(filePath)
  44. netStatsTotal = append(netStatsTotal, procNetstat)
  45. }
  46. return netStatsTotal, nil
  47. }
  48. // parseNetstat parses the metrics from `/proc/net/stat/` file
  49. // and returns a NetStat structure.
  50. func parseNetstat(r io.Reader) (NetStat, error) {
  51. var (
  52. scanner = bufio.NewScanner(r)
  53. netStat = NetStat{
  54. Stats: make(map[string][]uint64),
  55. }
  56. )
  57. scanner.Scan()
  58. // First string is always a header for stats
  59. var headers []string
  60. headers = append(headers, strings.Fields(scanner.Text())...)
  61. // Other strings represent per-CPU counters
  62. for scanner.Scan() {
  63. for num, counter := range strings.Fields(scanner.Text()) {
  64. value, err := strconv.ParseUint(counter, 16, 64)
  65. if err != nil {
  66. return NetStat{}, err
  67. }
  68. netStat.Stats[headers[num]] = append(netStat.Stats[headers[num]], value)
  69. }
  70. }
  71. return netStat, nil
  72. }