From 4f648792221f33322d9c8ef863dca94a1ac2d6a7 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Wed, 18 Dec 2024 21:17:15 -0500 Subject: [PATCH] procstats: bump taskstats and fix file handle leak The taskstats file handle is not being closed and thus it is possible for file descriptors to pile up forever. Pull in a much newer version and fix this problem. In addition, I don't think the naked returns or check helper are doing any favors for readability and have removed them in this block in favor of switch error handling. Signed-off-by: Matt Layher --- go.mod | 15 ++++++++------ go.sum | 35 +++++++++++++++------------------ procstats/delaystats.go | 6 ++---- procstats/delaystats_darwin.go | 4 ++-- procstats/delaystats_linux.go | 34 +++++++++++++++++++------------- procstats/delaystats_windows.go | 4 ++-- 6 files changed, 51 insertions(+), 47 deletions(-) diff --git a/go.mod b/go.mod index b3502c5..4478996 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,26 @@ module github.com/segmentio/stats/v5 go 1.22.0 require ( - github.com/mdlayher/taskstats v0.0.0-20190313225729-7cbba52ee072 + github.com/mdlayher/taskstats v0.0.0-20241218144709-977b30d474ce github.com/segmentio/fasthash v1.0.3 github.com/segmentio/objconv v1.0.1 github.com/segmentio/vpcinfo v0.1.10 github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.21.0 + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.28.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/josharian/native v1.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851 // indirect - github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c // indirect + github.com/mdlayher/genetlink v1.3.2 // indirect + github.com/mdlayher/netlink v1.7.2 // indirect + github.com/mdlayher/socket v0.5.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.32.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 57b5310..f497a52 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,22 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= +github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851 h1:QYJTEbSDJvDBQenHYMxoiBQPgZ4QUcm75vACe3dkW7o= -github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851/go.mod h1:EsbsAEUEs15qC1cosAwxgCWV0Qhd8TmkxnA9Kw1Vhl4= -github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c h1:qYXI+3AN4zBWsTF5drEu1akWPu2juaXPs58tZ4/GaCg= -github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= -github.com/mdlayher/taskstats v0.0.0-20190313225729-7cbba52ee072 h1:7YEPiUVGht4ZVgzzTtfC36BHmyd5+++j+FKucC+zxXU= -github.com/mdlayher/taskstats v0.0.0-20190313225729-7cbba52ee072/go.mod h1:sGdS7A6CAETR53zkdjGkgoFlh1vSm7MtX+i8XfEsTMA= +github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= +github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= +github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= +github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= +github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= +github.com/mdlayher/taskstats v0.0.0-20241218144709-977b30d474ce h1:IbVlJ25doaGn30HkfShedgDsRxCHTwQY8RO53ZXf5AQ= +github.com/mdlayher/taskstats v0.0.0-20241218144709-977b30d474ce/go.mod h1:0gPvvNyurVKWZFI09u1YSPCqhSnj6QwlwEijSrHXYag= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -27,20 +30,14 @@ github.com/segmentio/vpcinfo v0.1.10 h1:iCfT3tS4h2M7WLWmzFGKysZh0ql0B8XdiHYqiPN4 github.com/segmentio/vpcinfo v0.1.10/go.mod h1:KEIWiWRE/KLh90mOzOY0QkFWT7ObUYLp978tICtquqU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/procstats/delaystats.go b/procstats/delaystats.go index 23efb6a..34e0434 100644 --- a/procstats/delaystats.go +++ b/procstats/delaystats.go @@ -50,8 +50,6 @@ type DelayInfo struct { } // CollectDelayInfo returns DelayInfo for a pid and an error, if any. -func CollectDelayInfo(pid int) (info DelayInfo, err error) { - defer func() { err = convertPanicToError(recover()) }() - info = collectDelayInfo(pid) - return +func CollectDelayInfo(pid int) (DelayInfo, error) { + return collectDelayInfo(pid) } diff --git a/procstats/delaystats_darwin.go b/procstats/delaystats_darwin.go index 070329a..44caf24 100644 --- a/procstats/delaystats_darwin.go +++ b/procstats/delaystats_darwin.go @@ -1,6 +1,6 @@ package procstats -func collectDelayInfo(_ int) (info DelayInfo) { +func collectDelayInfo(_ int) (DelayInfo, error) { // TODO - return + return DelayInfo{}, nil } diff --git a/procstats/delaystats_linux.go b/procstats/delaystats_linux.go index 26c3a54..e018771 100644 --- a/procstats/delaystats_linux.go +++ b/procstats/delaystats_linux.go @@ -7,23 +7,29 @@ import ( "golang.org/x/sys/unix" ) -func collectDelayInfo(pid int) DelayInfo { +func collectDelayInfo(pid int) (DelayInfo, error) { client, err := taskstats.New() - if err == unix.ENOENT { - err = errors.New("failed to communicate with taskstats Netlink family, ensure this program is not running in a network namespace") + switch { + case errors.Is(err, unix.ENOENT): + return DelayInfo{}, errors.New("failed to communicate with taskstats Netlink family, ensure this program is not running in a network namespace") + case err != nil: + return DelayInfo{}, err + default: + defer client.Close() } - check(err) stats, err := client.TGID(pid) - if err == unix.EPERM { - err = errors.New("failed to open Netlink socket: permission denied, ensure CAP_NET_RAW is enabled for this process, or run it with root privileges") - } - check(err) - - return DelayInfo{ - BlockIODelay: stats.BlockIODelay, - CPUDelay: stats.CPUDelay, - FreePagesDelay: stats.FreePagesDelay, - SwapInDelay: stats.SwapInDelay, + switch { + case errors.Is(err, unix.EPERM): + return DelayInfo{}, errors.New("failed to open Netlink socket: permission denied, ensure CAP_NET_RAW is enabled for this process, or run it with root privileges") + case err != nil: + return DelayInfo{}, err + default: + return DelayInfo{ + BlockIODelay: stats.BlockIODelay, + CPUDelay: stats.CPUDelay, + FreePagesDelay: stats.FreePagesDelay, + SwapInDelay: stats.SwapInDelay, + }, nil } } diff --git a/procstats/delaystats_windows.go b/procstats/delaystats_windows.go index c2a01a0..44caf24 100644 --- a/procstats/delaystats_windows.go +++ b/procstats/delaystats_windows.go @@ -1,6 +1,6 @@ package procstats -func collectDelayInfo(pid int) (info DelayInfo) { +func collectDelayInfo(_ int) (DelayInfo, error) { // TODO - return + return DelayInfo{}, nil }