// 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 procfsimport ()// A NetSockstat contains the output of /proc/net/sockstat{,6} for IPv4 or IPv6,// respectively.typeNetSockstatstruct {// Used is non-nil for IPv4 sockstat results, but nil for IPv6. Used *int Protocols []NetSockstatProtocol}// A NetSockstatProtocol contains statistics about a given socket protocol.// Pointer fields indicate that the value may or may not be present on any// given protocol.typeNetSockstatProtocolstruct { Protocol string InUse int Orphan *int TW *int Alloc *int Mem *int Memory *int}// NetSockstat retrieves IPv4 socket statistics.func ( FS) () (*NetSockstat, error) {returnreadSockstat(.proc.Path("net", "sockstat"))}// NetSockstat6 retrieves IPv6 socket statistics.//// If IPv6 is disabled on this kernel, the returned error can be checked with// os.IsNotExist.func ( FS) () (*NetSockstat, error) {returnreadSockstat(.proc.Path("net", "sockstat6"))}// readSockstat opens and parses a NetSockstat from the input file.func readSockstat( string) (*NetSockstat, error) {// This file is small and can be read with one syscall. , := util.ReadFileNoStat()if != nil {// Do not wrap this error so the caller can detect os.IsNotExist and // similar conditions.returnnil, } , := parseSockstat(bytes.NewReader())if != nil {returnnil, fmt.Errorf("%w: sockstats from %q: %w", ErrFileRead, , ) }return , nil}// parseSockstat reads the contents of a sockstat file and parses a NetSockstat.func parseSockstat( io.Reader) (*NetSockstat, error) {varNetSockstat := bufio.NewScanner()for .Scan() {// Expect a minimum of a protocol and one key/value pair. := strings.Split(.Text(), " ")iflen() < 3 {returnnil, fmt.Errorf("%w: Malformed sockstat line: %q", ErrFileParse, .Text()) }// The remaining fields are key/value pairs. , := parseSockstatKVs([1:])if != nil {returnnil, fmt.Errorf("%w: sockstat key/value pairs from %q: %w", ErrFileParse, .Text(), ) }// The first field is the protocol. We must trim its colon suffix. := strings.TrimSuffix([0], ":")switch {case"sockets":// Special case: IPv4 has a sockets "used" key/value pair that we // embed at the top level of the structure. := ["used"] .Used = &default:// Parse all other lines as individual protocols. := parseSockstatProtocol() .Protocol = .Protocols = append(.Protocols, ) } }if := .Err(); != nil {returnnil, }return &, nil}// parseSockstatKVs parses a string slice into a map of key/value pairs.func parseSockstatKVs( []string) (map[string]int, error) {iflen()%2 != 0 {returnnil, fmt.Errorf("%w:: Odd number of fields in key/value pairs %q", ErrFileParse, ) }// Iterate two values at a time to gather key/value pairs. := make(map[string]int, len()/2)for := 0; < len(); += 2 { := util.NewValueParser([+1]) [[]] = .Int()if := .Err(); != nil {returnnil, } }return , nil}// parseSockstatProtocol parses a NetSockstatProtocol from the input kvs map.func parseSockstatProtocol( map[string]int) NetSockstatProtocol {varNetSockstatProtocolfor , := range {// Capture the range variable to ensure we get unique pointers for // each of the optional fields. := switch {case"inuse": .InUse = case"orphan": .Orphan = &case"tw": .TW = &case"alloc": .Alloc = &case"mem": .Mem = &case"memory": .Memory = & } }return}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.