// 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 TCPRcvQDrop *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 := parseProcNetstat(bytes.NewReader(data), filename) procNetstat.PID = p.PID return procNetstat, err } // parseProcNetstat parses the metrics from proc//net/netstat file // and returns a ProcNetstat structure. func parseProcNetstat(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("%w: mismatch field count mismatch in %s: %s", ErrFileParse, 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.SyncookiesSent = &value case "SyncookiesRecv": procNetstat.SyncookiesRecv = &value case "SyncookiesFailed": procNetstat.SyncookiesFailed = &value case "EmbryonicRsts": procNetstat.EmbryonicRsts = &value case "PruneCalled": procNetstat.PruneCalled = &value case "RcvPruned": procNetstat.RcvPruned = &value case "OfoPruned": procNetstat.OfoPruned = &value case "OutOfWindowIcmps": procNetstat.OutOfWindowIcmps = &value case "LockDroppedIcmps": procNetstat.LockDroppedIcmps = &value case "ArpFilter": procNetstat.ArpFilter = &value case "TW": procNetstat.TW = &value case "TWRecycled": procNetstat.TWRecycled = &value case "TWKilled": procNetstat.TWKilled = &value case "PAWSActive": procNetstat.PAWSActive = &value case "PAWSEstab": procNetstat.PAWSEstab = &value case "DelayedACKs": procNetstat.DelayedACKs = &value case "DelayedACKLocked": procNetstat.DelayedACKLocked = &value case "DelayedACKLost": procNetstat.DelayedACKLost = &value case "ListenOverflows": procNetstat.ListenOverflows = &value case "ListenDrops": procNetstat.ListenDrops = &value case "TCPHPHits": procNetstat.TCPHPHits = &value case "TCPPureAcks": procNetstat.TCPPureAcks = &value case "TCPHPAcks": procNetstat.TCPHPAcks = &value case "TCPRenoRecovery": procNetstat.TCPRenoRecovery = &value case "TCPSackRecovery": procNetstat.TCPSackRecovery = &value case "TCPSACKReneging": procNetstat.TCPSACKReneging = &value case "TCPSACKReorder": procNetstat.TCPSACKReorder = &value case "TCPRenoReorder": procNetstat.TCPRenoReorder = &value case "TCPTSReorder": procNetstat.TCPTSReorder = &value case "TCPFullUndo": procNetstat.TCPFullUndo = &value case "TCPPartialUndo": procNetstat.TCPPartialUndo = &value case "TCPDSACKUndo": procNetstat.TCPDSACKUndo = &value case "TCPLossUndo": procNetstat.TCPLossUndo = &value case "TCPLostRetransmit": procNetstat.TCPLostRetransmit = &value case "TCPRenoFailures": procNetstat.TCPRenoFailures = &value case "TCPSackFailures": procNetstat.TCPSackFailures = &value case "TCPLossFailures": procNetstat.TCPLossFailures = &value case "TCPFastRetrans": procNetstat.TCPFastRetrans = &value case "TCPSlowStartRetrans": procNetstat.TCPSlowStartRetrans = &value case "TCPTimeouts": procNetstat.TCPTimeouts = &value case "TCPLossProbes": procNetstat.TCPLossProbes = &value case "TCPLossProbeRecovery": procNetstat.TCPLossProbeRecovery = &value case "TCPRenoRecoveryFail": procNetstat.TCPRenoRecoveryFail = &value case "TCPSackRecoveryFail": procNetstat.TCPSackRecoveryFail = &value case "TCPRcvCollapsed": procNetstat.TCPRcvCollapsed = &value case "TCPDSACKOldSent": procNetstat.TCPDSACKOldSent = &value case "TCPDSACKOfoSent": procNetstat.TCPDSACKOfoSent = &value case "TCPDSACKRecv": procNetstat.TCPDSACKRecv = &value case "TCPDSACKOfoRecv": procNetstat.TCPDSACKOfoRecv = &value case "TCPAbortOnData": procNetstat.TCPAbortOnData = &value case "TCPAbortOnClose": procNetstat.TCPAbortOnClose = &value case "TCPDeferAcceptDrop": procNetstat.TCPDeferAcceptDrop = &value case "IPReversePathFilter": procNetstat.IPReversePathFilter = &value case "TCPTimeWaitOverflow": procNetstat.TCPTimeWaitOverflow = &value case "TCPReqQFullDoCookies": procNetstat.TCPReqQFullDoCookies = &value case "TCPReqQFullDrop": procNetstat.TCPReqQFullDrop = &value case "TCPRetransFail": procNetstat.TCPRetransFail = &value case "TCPRcvCoalesce": procNetstat.TCPRcvCoalesce = &value case "TCPRcvQDrop": procNetstat.TCPRcvQDrop = &value case "TCPOFOQueue": procNetstat.TCPOFOQueue = &value case "TCPOFODrop": procNetstat.TCPOFODrop = &value case "TCPOFOMerge": procNetstat.TCPOFOMerge = &value case "TCPChallengeACK": procNetstat.TCPChallengeACK = &value case "TCPSYNChallenge": procNetstat.TCPSYNChallenge = &value case "TCPFastOpenActive": procNetstat.TCPFastOpenActive = &value case "TCPFastOpenActiveFail": procNetstat.TCPFastOpenActiveFail = &value case "TCPFastOpenPassive": procNetstat.TCPFastOpenPassive = &value case "TCPFastOpenPassiveFail": procNetstat.TCPFastOpenPassiveFail = &value case "TCPFastOpenListenOverflow": procNetstat.TCPFastOpenListenOverflow = &value case "TCPFastOpenCookieReqd": procNetstat.TCPFastOpenCookieReqd = &value case "TCPFastOpenBlackhole": procNetstat.TCPFastOpenBlackhole = &value case "TCPSpuriousRtxHostQueues": procNetstat.TCPSpuriousRtxHostQueues = &value case "BusyPollRxPackets": procNetstat.BusyPollRxPackets = &value case "TCPAutoCorking": procNetstat.TCPAutoCorking = &value case "TCPFromZeroWindowAdv": procNetstat.TCPFromZeroWindowAdv = &value case "TCPToZeroWindowAdv": procNetstat.TCPToZeroWindowAdv = &value case "TCPWantZeroWindowAdv": procNetstat.TCPWantZeroWindowAdv = &value case "TCPSynRetrans": procNetstat.TCPSynRetrans = &value case "TCPOrigDataSent": procNetstat.TCPOrigDataSent = &value case "TCPHystartTrainDetect": procNetstat.TCPHystartTrainDetect = &value case "TCPHystartTrainCwnd": procNetstat.TCPHystartTrainCwnd = &value case "TCPHystartDelayDetect": procNetstat.TCPHystartDelayDetect = &value case "TCPHystartDelayCwnd": procNetstat.TCPHystartDelayCwnd = &value case "TCPACKSkippedSynRecv": procNetstat.TCPACKSkippedSynRecv = &value case "TCPACKSkippedPAWS": procNetstat.TCPACKSkippedPAWS = &value case "TCPACKSkippedSeq": procNetstat.TCPACKSkippedSeq = &value case "TCPACKSkippedFinWait2": procNetstat.TCPACKSkippedFinWait2 = &value case "TCPACKSkippedTimeWait": procNetstat.TCPACKSkippedTimeWait = &value case "TCPACKSkippedChallenge": procNetstat.TCPACKSkippedChallenge = &value case "TCPWinProbe": procNetstat.TCPWinProbe = &value case "TCPKeepAlive": procNetstat.TCPKeepAlive = &value case "TCPMTUPFail": procNetstat.TCPMTUPFail = &value case "TCPMTUPSuccess": procNetstat.TCPMTUPSuccess = &value case "TCPWqueueTooBig": procNetstat.TCPWqueueTooBig = &value } case "IpExt": switch key { case "InNoRoutes": procNetstat.InNoRoutes = &value case "InTruncatedPkts": procNetstat.InTruncatedPkts = &value case "InMcastPkts": procNetstat.InMcastPkts = &value case "OutMcastPkts": procNetstat.OutMcastPkts = &value case "InBcastPkts": procNetstat.InBcastPkts = &value case "OutBcastPkts": procNetstat.OutBcastPkts = &value case "InOctets": procNetstat.InOctets = &value case "OutOctets": procNetstat.OutOctets = &value case "InMcastOctets": procNetstat.InMcastOctets = &value case "OutMcastOctets": procNetstat.OutMcastOctets = &value case "InBcastOctets": procNetstat.InBcastOctets = &value case "OutBcastOctets": procNetstat.OutBcastOctets = &value case "InCsumErrors": procNetstat.InCsumErrors = &value case "InNoECTPkts": procNetstat.InNoECTPkts = &value case "InECT1Pkts": procNetstat.InECT1Pkts = &value case "InECT0Pkts": procNetstat.InECT0Pkts = &value case "InCEPkts": procNetstat.InCEPkts = &value case "ReasmOverlaps": procNetstat.ReasmOverlaps = &value } } } } return procNetstat, scanner.Err() }