354 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2022 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"
 | |
| )
 | |
| 
 | |
| // ProcSnmp models the content of /proc/<pid>/net/snmp.
 | |
| type ProcSnmp struct {
 | |
| 	// The process ID.
 | |
| 	PID int
 | |
| 	Ip
 | |
| 	Icmp
 | |
| 	IcmpMsg
 | |
| 	Tcp
 | |
| 	Udp
 | |
| 	UdpLite
 | |
| }
 | |
| 
 | |
| type Ip struct { // nolint:revive
 | |
| 	Forwarding      float64
 | |
| 	DefaultTTL      float64
 | |
| 	InReceives      float64
 | |
| 	InHdrErrors     float64
 | |
| 	InAddrErrors    float64
 | |
| 	ForwDatagrams   float64
 | |
| 	InUnknownProtos float64
 | |
| 	InDiscards      float64
 | |
| 	InDelivers      float64
 | |
| 	OutRequests     float64
 | |
| 	OutDiscards     float64
 | |
| 	OutNoRoutes     float64
 | |
| 	ReasmTimeout    float64
 | |
| 	ReasmReqds      float64
 | |
| 	ReasmOKs        float64
 | |
| 	ReasmFails      float64
 | |
| 	FragOKs         float64
 | |
| 	FragFails       float64
 | |
| 	FragCreates     float64
 | |
| }
 | |
| 
 | |
| type Icmp struct {
 | |
| 	InMsgs           float64
 | |
| 	InErrors         float64
 | |
| 	InCsumErrors     float64
 | |
| 	InDestUnreachs   float64
 | |
| 	InTimeExcds      float64
 | |
| 	InParmProbs      float64
 | |
| 	InSrcQuenchs     float64
 | |
| 	InRedirects      float64
 | |
| 	InEchos          float64
 | |
| 	InEchoReps       float64
 | |
| 	InTimestamps     float64
 | |
| 	InTimestampReps  float64
 | |
| 	InAddrMasks      float64
 | |
| 	InAddrMaskReps   float64
 | |
| 	OutMsgs          float64
 | |
| 	OutErrors        float64
 | |
| 	OutDestUnreachs  float64
 | |
| 	OutTimeExcds     float64
 | |
| 	OutParmProbs     float64
 | |
| 	OutSrcQuenchs    float64
 | |
| 	OutRedirects     float64
 | |
| 	OutEchos         float64
 | |
| 	OutEchoReps      float64
 | |
| 	OutTimestamps    float64
 | |
| 	OutTimestampReps float64
 | |
| 	OutAddrMasks     float64
 | |
| 	OutAddrMaskReps  float64
 | |
| }
 | |
| 
 | |
| type IcmpMsg struct {
 | |
| 	InType3  float64
 | |
| 	OutType3 float64
 | |
| }
 | |
| 
 | |
| type Tcp struct { // nolint:revive
 | |
| 	RtoAlgorithm float64
 | |
| 	RtoMin       float64
 | |
| 	RtoMax       float64
 | |
| 	MaxConn      float64
 | |
| 	ActiveOpens  float64
 | |
| 	PassiveOpens float64
 | |
| 	AttemptFails float64
 | |
| 	EstabResets  float64
 | |
| 	CurrEstab    float64
 | |
| 	InSegs       float64
 | |
| 	OutSegs      float64
 | |
| 	RetransSegs  float64
 | |
| 	InErrs       float64
 | |
| 	OutRsts      float64
 | |
| 	InCsumErrors float64
 | |
| }
 | |
| 
 | |
| type Udp struct { // nolint:revive
 | |
| 	InDatagrams  float64
 | |
| 	NoPorts      float64
 | |
| 	InErrors     float64
 | |
| 	OutDatagrams float64
 | |
| 	RcvbufErrors float64
 | |
| 	SndbufErrors float64
 | |
| 	InCsumErrors float64
 | |
| 	IgnoredMulti float64
 | |
| }
 | |
| 
 | |
| type UdpLite struct { // nolint:revive
 | |
| 	InDatagrams  float64
 | |
| 	NoPorts      float64
 | |
| 	InErrors     float64
 | |
| 	OutDatagrams float64
 | |
| 	RcvbufErrors float64
 | |
| 	SndbufErrors float64
 | |
| 	InCsumErrors float64
 | |
| 	IgnoredMulti float64
 | |
| }
 | |
| 
 | |
| func (p Proc) Snmp() (ProcSnmp, error) {
 | |
| 	filename := p.path("net/snmp")
 | |
| 	data, err := util.ReadFileNoStat(filename)
 | |
| 	if err != nil {
 | |
| 		return ProcSnmp{PID: p.PID}, err
 | |
| 	}
 | |
| 	procSnmp, err := parseSnmp(bytes.NewReader(data), filename)
 | |
| 	procSnmp.PID = p.PID
 | |
| 	return procSnmp, err
 | |
| }
 | |
| 
 | |
| // parseSnmp parses the metrics from proc/<pid>/net/snmp file
 | |
| // and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}).
 | |
| func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) {
 | |
| 	var (
 | |
| 		scanner  = bufio.NewScanner(r)
 | |
| 		procSnmp = ProcSnmp{}
 | |
| 	)
 | |
| 
 | |
| 	for scanner.Scan() {
 | |
| 		nameParts := strings.Split(scanner.Text(), " ")
 | |
| 		scanner.Scan()
 | |
| 		valueParts := strings.Split(scanner.Text(), " ")
 | |
| 		// Remove trailing :.
 | |
| 		protocol := strings.TrimSuffix(nameParts[0], ":")
 | |
| 		if len(nameParts) != len(valueParts) {
 | |
| 			return procSnmp, fmt.Errorf("mismatch field count mismatch in %s: %s",
 | |
| 				fileName, protocol)
 | |
| 		}
 | |
| 		for i := 1; i < len(nameParts); i++ {
 | |
| 			value, err := strconv.ParseFloat(valueParts[i], 64)
 | |
| 			if err != nil {
 | |
| 				return procSnmp, err
 | |
| 			}
 | |
| 			key := nameParts[i]
 | |
| 
 | |
| 			switch protocol {
 | |
| 			case "Ip":
 | |
| 				switch key {
 | |
| 				case "Forwarding":
 | |
| 					procSnmp.Ip.Forwarding = value
 | |
| 				case "DefaultTTL":
 | |
| 					procSnmp.Ip.DefaultTTL = value
 | |
| 				case "InReceives":
 | |
| 					procSnmp.Ip.InReceives = value
 | |
| 				case "InHdrErrors":
 | |
| 					procSnmp.Ip.InHdrErrors = value
 | |
| 				case "InAddrErrors":
 | |
| 					procSnmp.Ip.InAddrErrors = value
 | |
| 				case "ForwDatagrams":
 | |
| 					procSnmp.Ip.ForwDatagrams = value
 | |
| 				case "InUnknownProtos":
 | |
| 					procSnmp.Ip.InUnknownProtos = value
 | |
| 				case "InDiscards":
 | |
| 					procSnmp.Ip.InDiscards = value
 | |
| 				case "InDelivers":
 | |
| 					procSnmp.Ip.InDelivers = value
 | |
| 				case "OutRequests":
 | |
| 					procSnmp.Ip.OutRequests = value
 | |
| 				case "OutDiscards":
 | |
| 					procSnmp.Ip.OutDiscards = value
 | |
| 				case "OutNoRoutes":
 | |
| 					procSnmp.Ip.OutNoRoutes = value
 | |
| 				case "ReasmTimeout":
 | |
| 					procSnmp.Ip.ReasmTimeout = value
 | |
| 				case "ReasmReqds":
 | |
| 					procSnmp.Ip.ReasmReqds = value
 | |
| 				case "ReasmOKs":
 | |
| 					procSnmp.Ip.ReasmOKs = value
 | |
| 				case "ReasmFails":
 | |
| 					procSnmp.Ip.ReasmFails = value
 | |
| 				case "FragOKs":
 | |
| 					procSnmp.Ip.FragOKs = value
 | |
| 				case "FragFails":
 | |
| 					procSnmp.Ip.FragFails = value
 | |
| 				case "FragCreates":
 | |
| 					procSnmp.Ip.FragCreates = value
 | |
| 				}
 | |
| 			case "Icmp":
 | |
| 				switch key {
 | |
| 				case "InMsgs":
 | |
| 					procSnmp.Icmp.InMsgs = value
 | |
| 				case "InErrors":
 | |
| 					procSnmp.Icmp.InErrors = value
 | |
| 				case "InCsumErrors":
 | |
| 					procSnmp.Icmp.InCsumErrors = value
 | |
| 				case "InDestUnreachs":
 | |
| 					procSnmp.Icmp.InDestUnreachs = value
 | |
| 				case "InTimeExcds":
 | |
| 					procSnmp.Icmp.InTimeExcds = value
 | |
| 				case "InParmProbs":
 | |
| 					procSnmp.Icmp.InParmProbs = value
 | |
| 				case "InSrcQuenchs":
 | |
| 					procSnmp.Icmp.InSrcQuenchs = value
 | |
| 				case "InRedirects":
 | |
| 					procSnmp.Icmp.InRedirects = value
 | |
| 				case "InEchos":
 | |
| 					procSnmp.Icmp.InEchos = value
 | |
| 				case "InEchoReps":
 | |
| 					procSnmp.Icmp.InEchoReps = value
 | |
| 				case "InTimestamps":
 | |
| 					procSnmp.Icmp.InTimestamps = value
 | |
| 				case "InTimestampReps":
 | |
| 					procSnmp.Icmp.InTimestampReps = value
 | |
| 				case "InAddrMasks":
 | |
| 					procSnmp.Icmp.InAddrMasks = value
 | |
| 				case "InAddrMaskReps":
 | |
| 					procSnmp.Icmp.InAddrMaskReps = value
 | |
| 				case "OutMsgs":
 | |
| 					procSnmp.Icmp.OutMsgs = value
 | |
| 				case "OutErrors":
 | |
| 					procSnmp.Icmp.OutErrors = value
 | |
| 				case "OutDestUnreachs":
 | |
| 					procSnmp.Icmp.OutDestUnreachs = value
 | |
| 				case "OutTimeExcds":
 | |
| 					procSnmp.Icmp.OutTimeExcds = value
 | |
| 				case "OutParmProbs":
 | |
| 					procSnmp.Icmp.OutParmProbs = value
 | |
| 				case "OutSrcQuenchs":
 | |
| 					procSnmp.Icmp.OutSrcQuenchs = value
 | |
| 				case "OutRedirects":
 | |
| 					procSnmp.Icmp.OutRedirects = value
 | |
| 				case "OutEchos":
 | |
| 					procSnmp.Icmp.OutEchos = value
 | |
| 				case "OutEchoReps":
 | |
| 					procSnmp.Icmp.OutEchoReps = value
 | |
| 				case "OutTimestamps":
 | |
| 					procSnmp.Icmp.OutTimestamps = value
 | |
| 				case "OutTimestampReps":
 | |
| 					procSnmp.Icmp.OutTimestampReps = value
 | |
| 				case "OutAddrMasks":
 | |
| 					procSnmp.Icmp.OutAddrMasks = value
 | |
| 				case "OutAddrMaskReps":
 | |
| 					procSnmp.Icmp.OutAddrMaskReps = value
 | |
| 				}
 | |
| 			case "IcmpMsg":
 | |
| 				switch key {
 | |
| 				case "InType3":
 | |
| 					procSnmp.IcmpMsg.InType3 = value
 | |
| 				case "OutType3":
 | |
| 					procSnmp.IcmpMsg.OutType3 = value
 | |
| 				}
 | |
| 			case "Tcp":
 | |
| 				switch key {
 | |
| 				case "RtoAlgorithm":
 | |
| 					procSnmp.Tcp.RtoAlgorithm = value
 | |
| 				case "RtoMin":
 | |
| 					procSnmp.Tcp.RtoMin = value
 | |
| 				case "RtoMax":
 | |
| 					procSnmp.Tcp.RtoMax = value
 | |
| 				case "MaxConn":
 | |
| 					procSnmp.Tcp.MaxConn = value
 | |
| 				case "ActiveOpens":
 | |
| 					procSnmp.Tcp.ActiveOpens = value
 | |
| 				case "PassiveOpens":
 | |
| 					procSnmp.Tcp.PassiveOpens = value
 | |
| 				case "AttemptFails":
 | |
| 					procSnmp.Tcp.AttemptFails = value
 | |
| 				case "EstabResets":
 | |
| 					procSnmp.Tcp.EstabResets = value
 | |
| 				case "CurrEstab":
 | |
| 					procSnmp.Tcp.CurrEstab = value
 | |
| 				case "InSegs":
 | |
| 					procSnmp.Tcp.InSegs = value
 | |
| 				case "OutSegs":
 | |
| 					procSnmp.Tcp.OutSegs = value
 | |
| 				case "RetransSegs":
 | |
| 					procSnmp.Tcp.RetransSegs = value
 | |
| 				case "InErrs":
 | |
| 					procSnmp.Tcp.InErrs = value
 | |
| 				case "OutRsts":
 | |
| 					procSnmp.Tcp.OutRsts = value
 | |
| 				case "InCsumErrors":
 | |
| 					procSnmp.Tcp.InCsumErrors = value
 | |
| 				}
 | |
| 			case "Udp":
 | |
| 				switch key {
 | |
| 				case "InDatagrams":
 | |
| 					procSnmp.Udp.InDatagrams = value
 | |
| 				case "NoPorts":
 | |
| 					procSnmp.Udp.NoPorts = value
 | |
| 				case "InErrors":
 | |
| 					procSnmp.Udp.InErrors = value
 | |
| 				case "OutDatagrams":
 | |
| 					procSnmp.Udp.OutDatagrams = value
 | |
| 				case "RcvbufErrors":
 | |
| 					procSnmp.Udp.RcvbufErrors = value
 | |
| 				case "SndbufErrors":
 | |
| 					procSnmp.Udp.SndbufErrors = value
 | |
| 				case "InCsumErrors":
 | |
| 					procSnmp.Udp.InCsumErrors = value
 | |
| 				case "IgnoredMulti":
 | |
| 					procSnmp.Udp.IgnoredMulti = value
 | |
| 				}
 | |
| 			case "UdpLite":
 | |
| 				switch key {
 | |
| 				case "InDatagrams":
 | |
| 					procSnmp.UdpLite.InDatagrams = value
 | |
| 				case "NoPorts":
 | |
| 					procSnmp.UdpLite.NoPorts = value
 | |
| 				case "InErrors":
 | |
| 					procSnmp.UdpLite.InErrors = value
 | |
| 				case "OutDatagrams":
 | |
| 					procSnmp.UdpLite.OutDatagrams = value
 | |
| 				case "RcvbufErrors":
 | |
| 					procSnmp.UdpLite.RcvbufErrors = value
 | |
| 				case "SndbufErrors":
 | |
| 					procSnmp.UdpLite.SndbufErrors = value
 | |
| 				case "InCsumErrors":
 | |
| 					procSnmp.UdpLite.InCsumErrors = value
 | |
| 				case "IgnoredMulti":
 | |
| 					procSnmp.UdpLite.IgnoredMulti = value
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return procSnmp, scanner.Err()
 | |
| }
 | 
