diff --git a/fs_statfs_notype.go b/fs_statfs_notype.go index 134767d6..1b5bdbdf 100644 --- a/fs_statfs_notype.go +++ b/fs_statfs_notype.go @@ -17,7 +17,7 @@ package procfs // isRealProc returns true on architectures that don't have a Type argument -// in their Statfs_t struct -func isRealProc(mountPoint string) (bool, error) { +// in their Statfs_t struct. +func isRealProc(_ string) (bool, error) { return true, nil } diff --git a/internal/util/ptr.go b/internal/util/ptr.go new file mode 100644 index 00000000..66372acb --- /dev/null +++ b/internal/util/ptr.go @@ -0,0 +1,19 @@ +// Copyright 2024 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 util + +// PtrTo returns a pointer to the given value. +func PtrTo[T any](v T) *T { + return &v +} diff --git a/net_ip_socket.go b/net_ip_socket.go index b70f1fc7..66c2dfbf 100644 --- a/net_ip_socket.go +++ b/net_ip_socket.go @@ -17,6 +17,7 @@ import ( "bufio" "encoding/hex" "fmt" + "github.com/prometheus/procfs/internal/util" "io" "net" "os" @@ -24,14 +25,14 @@ import ( "strings" ) -const ( - // readLimit is used by io.LimitReader while reading the content of the +var ( + // defaultReadLimitPtr is used by io.LimitReader while reading the content of the // /proc/net/udp{,6} files. The number of lines inside such a file is dynamic // as each line represents a single used socket. // In theory, the number of available sockets is 65535 (2^16 - 1) per IP. // With e.g. 150 Byte per line and the maximum number of 65535, // the reader needs to handle 150 Byte * 65535 =~ 10 MB for a single IP. - readLimit = 4294967296 // Byte -> 4 GiB + defaultReadLimit = util.PtrTo(4294967296) // Byte -> 4 GiB ) // This contains generic data structures for both udp and tcp sockets. @@ -73,7 +74,7 @@ type ( } ) -func newNetIPSocket(file string) (NetIPSocket, error) { +func newNetIPSocket(file string, readLimit *int) (NetIPSocket, error) { f, err := os.Open(file) if err != nil { return nil, err @@ -83,7 +84,10 @@ func newNetIPSocket(file string) (NetIPSocket, error) { var netIPSocket NetIPSocket isUDP := strings.Contains(file, "udp") - lr := io.LimitReader(f, readLimit) + if readLimit == nil { + readLimit = defaultReadLimit + } + lr := io.LimitReader(f, int64(*readLimit)) s := bufio.NewScanner(lr) s.Scan() // skip first line with headers for s.Scan() { @@ -101,7 +105,7 @@ func newNetIPSocket(file string) (NetIPSocket, error) { } // newNetIPSocketSummary creates a new NetIPSocket{,6} from the contents of the given file. -func newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) { +func newNetIPSocketSummary(file string, readLimit *int) (*NetIPSocketSummary, error) { f, err := os.Open(file) if err != nil { return nil, err @@ -112,7 +116,10 @@ func newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) { var udpPacketDrops uint64 isUDP := strings.Contains(file, "udp") - lr := io.LimitReader(f, readLimit) + if readLimit == nil { + readLimit = defaultReadLimit + } + lr := io.LimitReader(f, int64(*readLimit)) s := bufio.NewScanner(lr) s.Scan() // skip first line with headers for s.Scan() { diff --git a/net_tcp.go b/net_tcp.go index 52776295..73c86aca 100644 --- a/net_tcp.go +++ b/net_tcp.go @@ -25,37 +25,37 @@ type ( // NetTCP returns the IPv4 kernel/networking statistics for TCP datagrams // read from /proc/net/tcp. -func (fs FS) NetTCP() (NetTCP, error) { - return newNetTCP(fs.proc.Path("net/tcp")) +func (fs FS) NetTCP(readLimit *int) (NetTCP, error) { + return newNetTCP(fs.proc.Path("net/tcp"), readLimit) } // NetTCP6 returns the IPv6 kernel/networking statistics for TCP datagrams // read from /proc/net/tcp6. -func (fs FS) NetTCP6() (NetTCP, error) { - return newNetTCP(fs.proc.Path("net/tcp6")) +func (fs FS) NetTCP6(readLimit *int) (NetTCP, error) { + return newNetTCP(fs.proc.Path("net/tcp6"), readLimit) } // NetTCPSummary returns already computed statistics like the total queue lengths // for TCP datagrams read from /proc/net/tcp. -func (fs FS) NetTCPSummary() (*NetTCPSummary, error) { - return newNetTCPSummary(fs.proc.Path("net/tcp")) +func (fs FS) NetTCPSummary(readLimit *int) (*NetTCPSummary, error) { + return newNetTCPSummary(fs.proc.Path("net/tcp"), readLimit) } // NetTCP6Summary returns already computed statistics like the total queue lengths // for TCP datagrams read from /proc/net/tcp6. -func (fs FS) NetTCP6Summary() (*NetTCPSummary, error) { - return newNetTCPSummary(fs.proc.Path("net/tcp6")) +func (fs FS) NetTCP6Summary(readLimit *int) (*NetTCPSummary, error) { + return newNetTCPSummary(fs.proc.Path("net/tcp6"), readLimit) } // newNetTCP creates a new NetTCP{,6} from the contents of the given file. -func newNetTCP(file string) (NetTCP, error) { - n, err := newNetIPSocket(file) +func newNetTCP(file string, readLimit *int) (NetTCP, error) { + n, err := newNetIPSocket(file, readLimit) n1 := NetTCP(n) return n1, err } -func newNetTCPSummary(file string) (*NetTCPSummary, error) { - n, err := newNetIPSocketSummary(file) +func newNetTCPSummary(file string, readLimit *int) (*NetTCPSummary, error) { + n, err := newNetIPSocketSummary(file, readLimit) if n == nil { return nil, err } diff --git a/net_tcp_test.go b/net_tcp_test.go index 5ff33ef3..2b745de1 100644 --- a/net_tcp_test.go +++ b/net_tcp_test.go @@ -115,7 +115,7 @@ func Test_newNetTCP(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := newNetTCP(tt.file) + got, err := newNetTCP(tt.file, nil) if (err != nil) != tt.wantErr { t.Errorf("newNetTCP() error = %v, wantErr %v", err, tt.wantErr) return @@ -161,7 +161,7 @@ func Test_newNetTCPSummary(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := newNetTCPSummary(tt.file) + got, err := newNetTCPSummary(tt.file, nil) if (err != nil) != tt.wantErr { t.Errorf("newNetTCPSummary() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/net_udp.go b/net_udp.go index 9ac3daf2..ff85264f 100644 --- a/net_udp.go +++ b/net_udp.go @@ -49,13 +49,13 @@ func (fs FS) NetUDP6Summary() (*NetUDPSummary, error) { // newNetUDP creates a new NetUDP{,6} from the contents of the given file. func newNetUDP(file string) (NetUDP, error) { - n, err := newNetIPSocket(file) + n, err := newNetIPSocket(file, nil) n1 := NetUDP(n) return n1, err } func newNetUDPSummary(file string) (*NetUDPSummary, error) { - n, err := newNetIPSocketSummary(file) + n, err := newNetIPSocketSummary(file, nil) if n == nil { return nil, err }