// 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" ) // ProcNetstat models the content of /proc//net/netstat. type ProcNetstat struct { // The process ID. PID int TcpExt IpExt } type TcpExt struct { // nolint:revive SyncookiesSent float64 SyncookiesRecv float64 SyncookiesFailed float64 EmbryonicRsts float64 PruneCalled float64 RcvPruned float64 OfoPruned float64 OutOfWindowIcmps float64 LockDroppedIcmps float64 ArpFilter float64 TW float64 TWRecycled float64 TWKilled float64 PAWSActive float64 PAWSEstab float64 DelayedACKs float64 DelayedACKLocked float64 DelayedACKLost float64 ListenOverflows float64 ListenDrops float64 TCPHPHits float64 TCPPureAcks float64 TCPHPAcks float64 TCPRenoRecovery float64 TCPSackRecovery float64 TCPSACKReneging float64 TCPSACKReorder float64 TCPRenoReorder float64 TCPTSReorder float64 TCPFullUndo float64 TCPPartialUndo float64 TCPDSACKUndo float64 TCPLossUndo float64 TCPLostRetransmit float64 TCPRenoFailures float64 TCPSackFailures float64 TCPLossFailures float64 TCPFastRetrans float64 TCPSlowStartRetrans float64 TCPTimeouts float64 TCPLossProbes float64 TCPLossProbeRecovery float64 TCPRenoRecoveryFail float64 TCPSackRecoveryFail float64 TCPRcvCollapsed float64 TCPDSACKOldSent float64 TCPDSACKOfoSent float64 TCPDSACKRecv float64 TCPDSACKOfoRecv float64 TCPAbortOnData float64 TCPAbortOnClose float64 TCPAbortOnMemory float64 TCPAbortOnTimeout float64 TCPAbortOnLinger float64 TCPAbortFailed float64 TCPMemoryPressures float64 TCPMemoryPressuresChrono float64 TCPSACKDiscard float64 TCPDSACKIgnoredOld float64 TCPDSACKIgnoredNoUndo float64 TCPSpuriousRTOs float64 TCPMD5NotFound float64 TCPMD5Unexpected float64 TCPMD5Failure float64 TCPSackShifted float64 TCPSackMerged float64 TCPSackShiftFallback float64 TCPBacklogDrop float64 PFMemallocDrop float64 TCPMinTTLDrop float64 TCPDeferAcceptDrop float64 IPReversePathFilter float64 TCPTimeWaitOverflow float64 TCPReqQFullDoCookies float64 TCPReqQFullDrop float64 TCPRetransFail float64 TCPRcvCoalesce float64 TCPOFOQueue float64 TCPOFODrop float64 TCPOFOMerge float64 TCPChallengeACK float64 TCPSYNChallenge float64 TCPFastOpenActive float64 TCPFastOpenActiveFail float64 TCPFastOpenPassive float64 TCPFastOpenPassiveFail float64 TCPFastOpenListenOverflow float64 TCPFastOpenCookieReqd float64 TCPFastOpenBlackhole float64 TCPSpuriousRtxHostQueues float64 BusyPollRxPackets float64 TCPAutoCorking float64 TCPFromZeroWindowAdv float64 TCPToZeroWindowAdv float64 TCPWantZeroWindowAdv float64 TCPSynRetrans float64 TCPOrigDataSent float64 TCPHystartTrainDetect float64 TCPHystartTrainCwnd float64 TCPHystartDelayDetect float64 TCPHystartDelayCwnd float64 TCPACKSkippedSynRecv float64 TCPACKSkippedPAWS float64 TCPACKSkippedSeq float64 TCPACKSkippedFinWait2 float64 TCPACKSkippedTimeWait float64 TCPACKSkippedChallenge float64 TCPWinProbe float64 TCPKeepAlive float64 TCPMTUPFail float64 TCPMTUPSuccess float64 TCPWqueueTooBig float64 } type IpExt struct { // nolint:revive InNoRoutes float64 InTruncatedPkts float64 InMcastPkts float64 OutMcastPkts float64 InBcastPkts float64 OutBcastPkts float64 InOctets float64 OutOctets float64 InMcastOctets float64 OutMcastOctets float64 InBcastOctets float64 OutBcastOctets float64 InCsumErrors float64 InNoECTPkts float64 InECT1Pkts float64 InECT0Pkts float64 InCEPkts float64 ReasmOverlaps float64 } func (p Proc) Netstat() (ProcNetstat, error) { filename := p.path("net/netstat") data, err := util.ReadFileNoStat(filename) if err != nil { return ProcNetstat{PID: p.PID}, err } procNetstat, err := parseNetstat(bytes.NewReader(data), filename) procNetstat.PID = p.PID return procNetstat, err } // parseNetstat parses the metrics from proc//net/netstat file // and returns a ProcNetstat structure. func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) { var ( scanner = bufio.NewScanner(r) procNetstat = ProcNetstat{} ) 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 procNetstat, 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 procNetstat, err } key := nameParts[i] switch protocol { case "TcpExt": switch key { case "SyncookiesSent": procNetstat.TcpExt.SyncookiesSent = value case "SyncookiesRecv": procNetstat.TcpExt.SyncookiesRecv = value case "SyncookiesFailed": procNetstat.TcpExt.SyncookiesFailed = value case "EmbryonicRsts": procNetstat.TcpExt.EmbryonicRsts = value case "PruneCalled": procNetstat.TcpExt.PruneCalled = value case "RcvPruned": procNetstat.TcpExt.RcvPruned = value case "OfoPruned": procNetstat.TcpExt.OfoPruned = value case "OutOfWindowIcmps": procNetstat.TcpExt.OutOfWindowIcmps = value case "LockDroppedIcmps": procNetstat.TcpExt.LockDroppedIcmps = value case "ArpFilter": procNetstat.TcpExt.ArpFilter = value case "TW": procNetstat.TcpExt.TW = value case "TWRecycled": procNetstat.TcpExt.TWRecycled = value case "TWKilled": procNetstat.TcpExt.TWKilled = value case "PAWSActive": procNetstat.TcpExt.PAWSActive = value case "PAWSEstab": procNetstat.TcpExt.PAWSEstab = value case "DelayedACKs": procNetstat.TcpExt.DelayedACKs = value case "DelayedACKLocked": procNetstat.TcpExt.DelayedACKLocked = value case "DelayedACKLost": procNetstat.TcpExt.DelayedACKLost = value case "ListenOverflows": procNetstat.TcpExt.ListenOverflows = value case "ListenDrops": procNetstat.TcpExt.ListenDrops = value case "TCPHPHits": procNetstat.TcpExt.TCPHPHits = value case "TCPPureAcks": procNetstat.TcpExt.TCPPureAcks = value case "TCPHPAcks": procNetstat.TcpExt.TCPHPAcks = value case "TCPRenoRecovery": procNetstat.TcpExt.TCPRenoRecovery = value case "TCPSackRecovery": procNetstat.TcpExt.TCPSackRecovery = value case "TCPSACKReneging": procNetstat.TcpExt.TCPSACKReneging = value case "TCPSACKReorder": procNetstat.TcpExt.TCPSACKReorder = value case "TCPRenoReorder": procNetstat.TcpExt.TCPRenoReorder = value case "TCPTSReorder": procNetstat.TcpExt.TCPTSReorder = value case "TCPFullUndo": procNetstat.TcpExt.TCPFullUndo = value case "TCPPartialUndo": procNetstat.TcpExt.TCPPartialUndo = value case "TCPDSACKUndo": procNetstat.TcpExt.TCPDSACKUndo = value case "TCPLossUndo": procNetstat.TcpExt.TCPLossUndo = value case "TCPLostRetransmit": procNetstat.TcpExt.TCPLostRetransmit = value case "TCPRenoFailures": procNetstat.TcpExt.TCPRenoFailures = value case "TCPSackFailures": procNetstat.TcpExt.TCPSackFailures = value case "TCPLossFailures": procNetstat.TcpExt.TCPLossFailures = value case "TCPFastRetrans": procNetstat.TcpExt.TCPFastRetrans = value case "TCPSlowStartRetrans": procNetstat.TcpExt.TCPSlowStartRetrans = value case "TCPTimeouts": procNetstat.TcpExt.TCPTimeouts = value case "TCPLossProbes": procNetstat.TcpExt.TCPLossProbes = value case "TCPLossProbeRecovery": procNetstat.TcpExt.TCPLossProbeRecovery = value case "TCPRenoRecoveryFail": procNetstat.TcpExt.TCPRenoRecoveryFail = value case "TCPSackRecoveryFail": procNetstat.TcpExt.TCPSackRecoveryFail = value case "TCPRcvCollapsed": procNetstat.TcpExt.TCPRcvCollapsed = value case "TCPDSACKOldSent": procNetstat.TcpExt.TCPDSACKOldSent = value case "TCPDSACKOfoSent": procNetstat.TcpExt.TCPDSACKOfoSent = value case "TCPDSACKRecv": procNetstat.TcpExt.TCPDSACKRecv = value case "TCPDSACKOfoRecv": procNetstat.TcpExt.TCPDSACKOfoRecv = value case "TCPAbortOnData": procNetstat.TcpExt.TCPAbortOnData = value case "TCPAbortOnClose": procNetstat.TcpExt.TCPAbortOnClose = value case "TCPDeferAcceptDrop": procNetstat.TcpExt.TCPDeferAcceptDrop = value case "IPReversePathFilter": procNetstat.TcpExt.IPReversePathFilter = value case "TCPTimeWaitOverflow": procNetstat.TcpExt.TCPTimeWaitOverflow = value case "TCPReqQFullDoCookies": procNetstat.TcpExt.TCPReqQFullDoCookies = value case "TCPReqQFullDrop": procNetstat.TcpExt.TCPReqQFullDrop = value case "TCPRetransFail": procNetstat.TcpExt.TCPRetransFail = value case "TCPRcvCoalesce": procNetstat.TcpExt.TCPRcvCoalesce = value case "TCPOFOQueue": procNetstat.TcpExt.TCPOFOQueue = value case "TCPOFODrop": procNetstat.TcpExt.TCPOFODrop = value case "TCPOFOMerge": procNetstat.TcpExt.TCPOFOMerge = value case "TCPChallengeACK": procNetstat.TcpExt.TCPChallengeACK = value case "TCPSYNChallenge": procNetstat.TcpExt.TCPSYNChallenge = value case "TCPFastOpenActive": procNetstat.TcpExt.TCPFastOpenActive = value case "TCPFastOpenActiveFail": procNetstat.TcpExt.TCPFastOpenActiveFail = value case "TCPFastOpenPassive": procNetstat.TcpExt.TCPFastOpenPassive = value case "TCPFastOpenPassiveFail": procNetstat.TcpExt.TCPFastOpenPassiveFail = value case "TCPFastOpenListenOverflow": procNetstat.TcpExt.TCPFastOpenListenOverflow = value case "TCPFastOpenCookieReqd": procNetstat.TcpExt.TCPFastOpenCookieReqd = value case "TCPFastOpenBlackhole": procNetstat.TcpExt.TCPFastOpenBlackhole = value case "TCPSpuriousRtxHostQueues": procNetstat.TcpExt.TCPSpuriousRtxHostQueues = value case "BusyPollRxPackets": procNetstat.TcpExt.BusyPollRxPackets = value case "TCPAutoCorking": procNetstat.TcpExt.TCPAutoCorking = value case "TCPFromZeroWindowAdv": procNetstat.TcpExt.TCPFromZeroWindowAdv = value case "TCPToZeroWindowAdv": procNetstat.TcpExt.TCPToZeroWindowAdv = value case "TCPWantZeroWindowAdv": procNetstat.TcpExt.TCPWantZeroWindowAdv = value case "TCPSynRetrans": procNetstat.TcpExt.TCPSynRetrans = value case "TCPOrigDataSent": procNetstat.TcpExt.TCPOrigDataSent = value case "TCPHystartTrainDetect": procNetstat.TcpExt.TCPHystartTrainDetect = value case "TCPHystartTrainCwnd": procNetstat.TcpExt.TCPHystartTrainCwnd = value case "TCPHystartDelayDetect": procNetstat.TcpExt.TCPHystartDelayDetect = value case "TCPHystartDelayCwnd": procNetstat.TcpExt.TCPHystartDelayCwnd = value case "TCPACKSkippedSynRecv": procNetstat.TcpExt.TCPACKSkippedSynRecv = value case "TCPACKSkippedPAWS": procNetstat.TcpExt.TCPACKSkippedPAWS = value case "TCPACKSkippedSeq": procNetstat.TcpExt.TCPACKSkippedSeq = value case "TCPACKSkippedFinWait2": procNetstat.TcpExt.TCPACKSkippedFinWait2 = value case "TCPACKSkippedTimeWait": procNetstat.TcpExt.TCPACKSkippedTimeWait = value case "TCPACKSkippedChallenge": procNetstat.TcpExt.TCPACKSkippedChallenge = value case "TCPWinProbe": procNetstat.TcpExt.TCPWinProbe = value case "TCPKeepAlive": procNetstat.TcpExt.TCPKeepAlive = value case "TCPMTUPFail": procNetstat.TcpExt.TCPMTUPFail = value case "TCPMTUPSuccess": procNetstat.TcpExt.TCPMTUPSuccess = value case "TCPWqueueTooBig": procNetstat.TcpExt.TCPWqueueTooBig = value } case "IpExt": switch key { case "InNoRoutes": procNetstat.IpExt.InNoRoutes = value case "InTruncatedPkts": procNetstat.IpExt.InTruncatedPkts = value case "InMcastPkts": procNetstat.IpExt.InMcastPkts = value case "OutMcastPkts": procNetstat.IpExt.OutMcastPkts = value case "InBcastPkts": procNetstat.IpExt.InBcastPkts = value case "OutBcastPkts": procNetstat.IpExt.OutBcastPkts = value case "InOctets": procNetstat.IpExt.InOctets = value case "OutOctets": procNetstat.IpExt.OutOctets = value case "InMcastOctets": procNetstat.IpExt.InMcastOctets = value case "OutMcastOctets": procNetstat.IpExt.OutMcastOctets = value case "InBcastOctets": procNetstat.IpExt.InBcastOctets = value case "OutBcastOctets": procNetstat.IpExt.OutBcastOctets = value case "InCsumErrors": procNetstat.IpExt.InCsumErrors = value case "InNoECTPkts": procNetstat.IpExt.InNoECTPkts = value case "InECT1Pkts": procNetstat.IpExt.InECT1Pkts = value case "InECT0Pkts": procNetstat.IpExt.InECT0Pkts = value case "InCEPkts": procNetstat.IpExt.InCEPkts = value case "ReasmOverlaps": procNetstat.IpExt.ReasmOverlaps = value } } } } return procNetstat, scanner.Err() }