From 748c6e7e7c953a990a2e8e2b96854860220765af Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Fri, 27 Sep 2024 19:49:01 -0700 Subject: [PATCH] Switch to slog --- .github/workflows/build.yml | 6 +- .github/workflows/release.yml | 10 +-- .golangci.yml | 20 ++++++ .goreleaser.yml | 3 + Makefile | 6 +- cmd/integration-tester/main.go | 8 ++- cmd/load-generator/main.go | 6 +- cmd/process-exporter/main.go | 122 ++++++++++++++------------------- collector/process_collector.go | 16 ++--- config/config.go | 24 ++++--- config/config_test.go | 31 +++++---- go.mod | 40 ++++++----- go.sum | 92 ++++++++++++------------- proc/base_test.go | 2 +- proc/grouper.go | 12 ++-- proc/grouper_test.go | 90 ++++++++++++++++-------- proc/read.go | 17 +++-- proc/read_test.go | 3 +- proc/tracker.go | 61 ++++++----------- proc/tracker_test.go | 61 ++++++++++++++--- 20 files changed, 349 insertions(+), 281 deletions(-) create mode 100644 .golangci.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a125b7c..2e4d58ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,9 @@ jobs: runs-on: ubuntu-latest steps: - name: setup Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: stable - uses: actions/checkout@v4 with: @@ -16,4 +16,4 @@ jobs: - run: make vet - run: make test - run: make BRANCH=${{ github.head_ref || github.ref_name }} build - - run: make integ \ No newline at end of file + - run: make integ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c41611a..383f363c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,17 +16,17 @@ jobs: fetch-depth: 0 - name: setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: stable - run: make test - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5 + uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser - version: "~> 1.25" - args: release --rm-dist + version: "~> v2" + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..ebbad726 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,20 @@ +--- +linters: + enable: + - misspell + - sloglint + - gofumpt + - goimports + - gofmt + +issues: + exclude-rules: + - path: _test.go + linters: + - errcheck + +linters-settings: + errcheck: + exclude-functions: + # Used in HTTP handlers, any error is handled by the server itself. + - (net/http.ResponseWriter).Write diff --git a/.goreleaser.yml b/.goreleaser.yml index 2155ccba..c9ab8008 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,6 +1,9 @@ +version: 2 builds: - main: cmd/process-exporter/main.go binary: process-exporter + flags: + - -trimpath ldflags: - -s -w - -X github.com/prometheus/common/version.BuildDate={{.Date}} diff --git a/Makefile b/Makefile index 63a88819..e54e4fc3 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ vet: build: @echo ">> building code" - cd cmd/process-exporter; CGO_ENABLED=0 go build -ldflags "$(VERSION_LDFLAGS)" -o ../../process-exporter -a -tags netgo + cd cmd/process-exporter; CGO_ENABLED=0 go build -trimpath -ldflags "$(VERSION_LDFLAGS)" -o ../../process-exporter -a -tags netgo smoke: @echo ">> smoke testing process-exporter" @@ -64,10 +64,10 @@ docker: docker run --rm --volumes-from configs "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" $(SMOKE_TEST) dockertest: - docker run --rm -it -v `pwd`:/go/src/github.com/ncabatoff/process-exporter golang:1.22 make -C /go/src/github.com/ncabatoff/process-exporter test + docker run --rm -it -v `pwd`:/go/src/github.com/ncabatoff/process-exporter golang:1.23 make -C /go/src/github.com/ncabatoff/process-exporter test dockerinteg: - docker run --rm -it -v `pwd`:/go/src/github.com/ncabatoff/process-exporter golang:1.22 make -C /go/src/github.com/ncabatoff/process-exporter build integ + docker run --rm -it -v `pwd`:/go/src/github.com/ncabatoff/process-exporter golang:1.23 make -C /go/src/github.com/ncabatoff/process-exporter build integ .PHONY: update-go-deps update-go-deps: diff --git a/cmd/integration-tester/main.go b/cmd/integration-tester/main.go index 0f1b1232..943176f1 100644 --- a/cmd/integration-tester/main.go +++ b/cmd/integration-tester/main.go @@ -30,7 +30,7 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() cmdlg := exec.CommandContext(ctx, *flagLoadGenerator, "-write-size-bytes", strconv.Itoa(*flagWriteSizeBytes)) - var buf = &bytes.Buffer{} + buf := &bytes.Buffer{} cmdlg.Stdout = buf err := cmdlg.Start() if err != nil { @@ -60,7 +60,11 @@ func main() { } cancel() - cmdlg.Wait() + err = cmdlg.Wait() + if err != nil { + log.Printf("Error waiting for load generator %q: %v", *flagLoadGenerator, err) + success = false + } if !success { os.Exit(1) diff --git a/cmd/load-generator/main.go b/cmd/load-generator/main.go index f2f520d6..d9f0c85b 100644 --- a/cmd/load-generator/main.go +++ b/cmd/load-generator/main.go @@ -1,10 +1,12 @@ +//go:build linux + package main import ( "flag" "fmt" - "io/ioutil" "math/rand" + "os" "runtime" "syscall" "unsafe" @@ -93,7 +95,7 @@ func diskio(sync bool, writesize int) { panic("unable to get rands: " + err.Error()) } - f, err := ioutil.TempFile("", "loadgen") + f, err := os.CreateTemp("", "loadgen") if err != nil { panic("unable to create tempfile: " + err.Error()) } diff --git a/cmd/process-exporter/main.go b/cmd/process-exporter/main.go index 6dfc0a08..b22ef1d8 100644 --- a/cmd/process-exporter/main.go +++ b/cmd/process-exporter/main.go @@ -1,9 +1,7 @@ package main import ( - "flag" "fmt" - "log" "net/http" _ "net/http/pprof" "os" @@ -11,6 +9,7 @@ import ( "strings" "time" + "github.com/alecthomas/kingpin/v2" "github.com/ncabatoff/fakescraper" common "github.com/ncabatoff/process-exporter" "github.com/ncabatoff/process-exporter/collector" @@ -18,9 +17,12 @@ import ( "github.com/prometheus/client_golang/prometheus" verCollector "github.com/prometheus/client_golang/prometheus/collectors/version" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/prometheus/common/promlog" + "github.com/prometheus/common/promslog" + + "github.com/prometheus/common/promslog/flag" promVersion "github.com/prometheus/common/version" "github.com/prometheus/exporter-toolkit/web" + "github.com/prometheus/exporter-toolkit/web/kingpinflag" ) // Version is set at build time use ldflags. @@ -30,31 +32,31 @@ func printManual() { fmt.Print(`Usage: process-exporter [options] -config.path filename.yml -or +or process-exporter [options] -procnames name1,...,nameN [-namemapping k1,v1,...,kN,vN] The recommended option is to use a config file, but for convenience and backwards compatibility the -procnames/-namemapping options exist as an alternative. - + The -children option (default:true) makes it so that any process that otherwise isn't part of its own group becomes part of the first group found (if any) when -walking the process tree upwards. In other words, resource usage of +walking the process tree upwards. In other words, resource usage of subprocesses is added to their parent's usage unless the subprocess identifies as a different group name. Command-line process selection (procnames/namemapping): Every process not in the procnames list is ignored. Otherwise, all processes - found are reported on as a group based on the process name they share. + found are reported on as a group based on the process name they share. Here 'process name' refers to the value found in the second field of /proc//stat, which is truncated at 15 chars. The -namemapping option allows assigning a group name based on a combination of - the process name and command line. For example, using + the process name and command line. For example, using - -namemapping "python2,([^/]+)\.py,java,-jar\s+([^/]+).jar" + -namemapping "python2,([^/]+)\.py,java,-jar\s+([^/]+).jar" will make it so that each different python2 and java -jar invocation will be tracked with distinct metrics. Processes whose remapped name is absent from @@ -72,7 +74,6 @@ Config file process selection (filename.yml): See README.md. ` + "\n") - } type ( @@ -147,49 +148,33 @@ func init() { func main() { var ( - listenAddress = flag.String("web.listen-address", ":9256", - "Address on which to expose metrics and web interface.") - metricsPath = flag.String("web.telemetry-path", "/metrics", - "Path under which to expose metrics.") - onceToStdoutDelay = flag.Duration("once-to-stdout-delay", 0, - "Don't bind, just wait this much time, print the metrics once to stdout, and exit") - procNames = flag.String("procnames", "", - "comma-separated list of process names to monitor") - procfsPath = flag.String("procfs", "/proc", - "path to read proc data from") - nameMapping = flag.String("namemapping", "", - "comma-separated list, alternating process name and capturing regex to apply to cmdline") - children = flag.Bool("children", true, - "if a proc is tracked, track with it any children that aren't part of their own group") - threads = flag.Bool("threads", true, - "report on per-threadname metrics as well") - smaps = flag.Bool("gather-smaps", true, - "gather metrics from smaps file, which contains proportional resident memory size") - man = flag.Bool("man", false, - "print manual") - configPath = flag.String("config.path", "", - "path to YAML config file") - tlsConfigFile = flag.String("web.config.file", "", - "path to YAML web config file") - recheck = flag.Bool("recheck", false, - "recheck process names on each scrape") - recheckTimeLimit = flag.Duration("recheck-with-time-limit", 0, - "recheck processes only this much time after their start, but no longer.") - debug = flag.Bool("debug", false, - "log debugging information to stdout") - showVersion = flag.Bool("version", false, - "print version information and exit") - removeEmptyGroups = flag.Bool("remove-empty-groups", false, "forget process groups with no processes") + webConfig = kingpinflag.AddFlags(kingpin.CommandLine, ":9256") + metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String() + onceToStdoutDelay = kingpin.Flag("once-to-stdout-delay", "If set, will collect metrics once and print them to stdout after the given delay.").Default("0s").Duration() + procNames = kingpin.Flag("procnames", "comma-separated list of process names to monitor").String() + procfsPath = kingpin.Flag("procfs", "path to read proc data from").Default("/proc").String() + nameMapping = kingpin.Flag("namemapping", "comma-separated list, alternating process name and capturing regex to apply to cmdline").String() + children = kingpin.Flag("children", "if a proc is tracked, track with it any children that aren't part of their own group").Default("true").Bool() + threads = kingpin.Flag("threads", "report on per-threadname metrics as well").Default("true").Bool() + smaps = kingpin.Flag("gather-smaps", "gather metrics from smaps file, which contains proportional resident memory size").Bool() + man = kingpin.Flag("man", "print manual").Bool() + configPath = kingpin.Flag("config.path", "path to YAML config file").String() + recheck = kingpin.Flag("recheck", "recheck process names on each scrape").Bool() + recheckTimeLimit = kingpin.Flag("recheck-with-time-limit", "recheck processes only this much time after their start, but no longer.").Duration() + removeEmptyGroups = kingpin.Flag("remove-empty-groups", "forget process groups with no processes").Bool() ) - flag.Parse() - promlogConfig := &promlog.Config{} - logger := promlog.New(promlogConfig) + promslogConfig := &promslog.Config{} - if *showVersion { - fmt.Printf("%s\n", promVersion.Print("process-exporter")) - os.Exit(0) - } + flag.AddFlags(kingpin.CommandLine, promslogConfig) + kingpin.Version(promVersion.Print("process-exporter")) + kingpin.HelpFlag.Short('h') + + kingpin.Parse() + logger := promslog.New(promslogConfig) + + logger.Info("process-exporter", "version", promVersion.Info()) + logger.Info("build context", "build_context", promVersion.BuildContext()) if *man { printManual() @@ -200,22 +185,23 @@ func main() { if *configPath != "" { if *nameMapping != "" || *procNames != "" { - log.Fatalf("-config.path cannot be used with -namemapping or -procnames") + logger.Error("-config.path cannot be used with -namemapping or -procnames") + os.Exit(1) } - cfg, err := config.ReadFile(*configPath, *debug) + cfg, err := config.ReadFile(*configPath, logger) if err != nil { - log.Fatalf("error reading config file %q: %v", *configPath, err) + logger.Error("error reading config file", "config path", *configPath, "error", err.Error()) + os.Exit(1) } - log.Printf("Reading metrics from %s based on %q", *procfsPath, *configPath) + logger.Info("Reading metrics", "procfs path", *procfsPath, "config path", *configPath) matchnamer = cfg.MatchNamers - if *debug { - log.Printf("using config matchnamer: %v", cfg.MatchNamers) - } + logger.Debug("using config matchnamer", "config", cfg.MatchNamers) } else { namemapper, err := parseNameMapper(*nameMapping) if err != nil { - log.Fatalf("Error parsing -namemapping argument '%s': %v", *nameMapping, err) + logger.Error("Error parsing -namemapping argument", "arg", *nameMapping, "error", err.Error()) + os.Exit(1) } var names []string @@ -228,10 +214,8 @@ func main() { } } - log.Printf("Reading metrics from %s for procnames: %v", *procfsPath, names) - if *debug { - log.Printf("using cmdline matchnamer: %v", namemapper) - } + logger.Info("Reading metrics", "procfs path", *procfsPath, "procnames", names) + logger.Debug("using cmdline matchnamer", "cmdline", namemapper) matchnamer = namemapper } @@ -248,12 +232,13 @@ func main() { Namer: matchnamer, Recheck: *recheck, RecheckTimeLimit: *recheckTimeLimit, - Debug: *debug, RemoveEmptyGroups: *removeEmptyGroups, }, + logger, ) if err != nil { - log.Fatalf("Error initializing: %v", err) + logger.Error("Error initializing", "error", err.Error()) + os.Exit(1) } prometheus.MustRegister(pc) @@ -280,12 +265,9 @@ func main() { `)) }) - server := &http.Server{Addr: *listenAddress} - if err := web.ListenAndServe(server, &web.FlagConfig{ - WebListenAddresses: &[]string{*listenAddress}, - WebConfigFile: tlsConfigFile, - }, logger); err != nil { - log.Fatalf("Failed to start the server: %v", err) + server := &http.Server{} + if err := web.ListenAndServe(server, webConfig, logger); err != nil { + logger.Error("Failed to start the server", "error", err.Error()) os.Exit(1) } } diff --git a/collector/process_collector.go b/collector/process_collector.go index 8f41ba47..a599b037 100644 --- a/collector/process_collector.go +++ b/collector/process_collector.go @@ -2,6 +2,7 @@ package collector import ( "log" + "log/slog" "time" common "github.com/ncabatoff/process-exporter" @@ -163,7 +164,6 @@ type ( Namer common.MatchNamer Recheck bool RecheckTimeLimit time.Duration - Debug bool RemoveEmptyGroups bool } @@ -176,12 +176,12 @@ type ( scrapeErrors int scrapeProcReadErrors int scrapePartialErrors int - debug bool + logger *slog.Logger } ) -func NewProcessCollector(options ProcessCollectorOption) (*NamedProcessCollector, error) { - fs, err := proc.NewFS(options.ProcFSPath, options.Debug) +func NewProcessCollector(options ProcessCollectorOption, logger *slog.Logger) (*NamedProcessCollector, error) { + fs, err := proc.NewFS(options.ProcFSPath) if err != nil { return nil, err } @@ -189,18 +189,16 @@ func NewProcessCollector(options ProcessCollectorOption) (*NamedProcessCollector fs.GatherSMaps = options.GatherSMaps p := &NamedProcessCollector{ scrapeChan: make(chan scrapeRequest), - Grouper: proc.NewGrouper(options.Namer, options.Children, options.Threads, options.Recheck, options.RecheckTimeLimit, options.Debug, options.RemoveEmptyGroups), + Grouper: proc.NewGrouper(options.Namer, options.Children, options.Threads, options.Recheck, options.RecheckTimeLimit, options.RemoveEmptyGroups, logger), source: fs, threads: options.Threads, smaps: options.GatherSMaps, - debug: options.Debug, + logger: logger, } colErrs, _, err := p.Update(p.source.AllProcs()) if err != nil { - if options.Debug { - log.Print(err) - } + p.logger.Debug("error reading procs", "error", err.Error()) return nil, err } p.scrapePartialErrors += colErrs.Partial diff --git a/config/config.go b/config/config.go index ebb23a5c..244df77e 100644 --- a/config/config.go +++ b/config/config.go @@ -3,8 +3,8 @@ package config import ( "bytes" "fmt" - "io/ioutil" - "log" + "log/slog" + "os" "path/filepath" "regexp" "strings" @@ -70,7 +70,7 @@ func (e *exeMatcher) String() string { } func (c *commMatcher) String() string { - var comms = make([]string, 0, len(c.comms)) + comms := make([]string, 0, len(c.comms)) for cm := range c.comms { comms = append(comms, cm) } @@ -115,7 +115,7 @@ func (m *matchNamer) MatchAndName(nacl common.ProcAttributes) (bool, string) { } var buf bytes.Buffer - m.template.Execute(&buf, &templateParams{ + err := m.template.Execute(&buf, &templateParams{ Comm: nacl.Name, Cgroups: nacl.Cgroups, ExeBase: exebase, @@ -125,6 +125,9 @@ func (m *matchNamer) MatchAndName(nacl common.ProcAttributes) (bool, string) { PID: nacl.PID, StartTime: nacl.StartTime, }) + if err != nil { + return false, "" + } return true, buf.String() } @@ -269,19 +272,18 @@ func (r MatcherRules) ToConfig() (*Config, error) { } // ReadRecipesFile opens the named file and extracts recipes from it. -func ReadFile(cfgpath string, debug bool) (*Config, error) { - content, err := ioutil.ReadFile(cfgpath) +func ReadFile(cfgpath string, logger *slog.Logger) (*Config, error) { + content, err := os.ReadFile(cfgpath) if err != nil { return nil, fmt.Errorf("error reading config file %q: %v", cfgpath, err) } - if debug { - log.Printf("Config file %q contents:\n%s", cfgpath, content) - } - return GetConfig(string(content), debug) + logger.Debug("Config file", "path", cfgpath, "contents", string(content)) + + return GetConfig(string(content)) } // GetConfig extracts Config from content by parsing it as YAML. -func GetConfig(content string, debug bool) (*Config, error) { +func GetConfig(content string) (*Config, error) { var cfg Config err := yaml.Unmarshal([]byte(content), &cfg) if err != nil { diff --git a/config/config_test.go b/config/config_test.go index 138538c8..22819a15 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2,22 +2,23 @@ package config import ( // "github.com/kylelemons/godebug/pretty" + "time" + common "github.com/ncabatoff/process-exporter" . "gopkg.in/check.v1" - "time" ) func (s MySuite) TestConfigBasic(c *C) { yml := ` process_names: - - exe: + - exe: - bash - - exe: + - exe: - sh - - exe: + - exe: - /bin/ksh ` - cfg, err := GetConfig(yml, false) + cfg, err := GetConfig(yml) c.Assert(err, IsNil) c.Check(cfg.MatchNamers.matchers, HasLen, 3) @@ -28,22 +29,22 @@ process_names: found, name := cfg.MatchNamers.matchers[0].MatchAndName(bash) c.Check(found, Equals, true) c.Check(name, Equals, "bash") - found, name = cfg.MatchNamers.matchers[0].MatchAndName(sh) + found, _ = cfg.MatchNamers.matchers[0].MatchAndName(sh) c.Check(found, Equals, false) - found, name = cfg.MatchNamers.matchers[0].MatchAndName(ksh) + found, _ = cfg.MatchNamers.matchers[0].MatchAndName(ksh) c.Check(found, Equals, false) - found, name = cfg.MatchNamers.matchers[1].MatchAndName(bash) + found, _ = cfg.MatchNamers.matchers[1].MatchAndName(bash) c.Check(found, Equals, false) found, name = cfg.MatchNamers.matchers[1].MatchAndName(sh) c.Check(found, Equals, true) c.Check(name, Equals, "sh") - found, name = cfg.MatchNamers.matchers[1].MatchAndName(ksh) + found, _ = cfg.MatchNamers.matchers[1].MatchAndName(ksh) c.Check(found, Equals, false) - found, name = cfg.MatchNamers.matchers[2].MatchAndName(bash) + found, _ = cfg.MatchNamers.matchers[2].MatchAndName(bash) c.Check(found, Equals, false) - found, name = cfg.MatchNamers.matchers[2].MatchAndName(sh) + found, _ = cfg.MatchNamers.matchers[2].MatchAndName(sh) c.Check(found, Equals, false) found, name = cfg.MatchNamers.matchers[2].MatchAndName(ksh) c.Check(found, Equals, true) @@ -53,19 +54,19 @@ process_names: func (s MySuite) TestConfigTemplates(c *C) { yml := ` process_names: - - exe: + - exe: - postmaster - cmdline: + cmdline: - "-D\\s+.+?(?P[^/]+)(?:$|\\s)" name: "{{.ExeBase}}:{{.Matches.Path}}" - - exe: + - exe: - prometheus name: "{{.ExeFull}}:{{.PID}}" - comm: - cat name: "{{.StartTime}}" ` - cfg, err := GetConfig(yml, false) + cfg, err := GetConfig(yml) c.Assert(err, IsNil) c.Check(cfg.MatchNamers.matchers, HasLen, 3) diff --git a/go.mod b/go.mod index d343e90c..8c888164 100644 --- a/go.mod +++ b/go.mod @@ -1,39 +1,41 @@ module github.com/ncabatoff/process-exporter -go 1.21 +go 1.22 require ( + github.com/alecthomas/kingpin/v2 v2.4.0 github.com/google/go-cmp v0.6.0 github.com/ncabatoff/fakescraper v0.0.0-20201102132415-4b37ba603d65 github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833 - github.com/prometheus/client_golang v1.19.0 - github.com/prometheus/common v0.52.3 - github.com/prometheus/exporter-toolkit v0.11.0 - github.com/prometheus/procfs v0.14.0 + github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/common v0.59.1 + github.com/prometheus/exporter-toolkit v0.13.0 + github.com/prometheus/procfs v0.15.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/yaml.v2 v2.4.0 ) require ( + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/jpillora/backoff v1.0.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/mdlayher/socket v0.4.1 // indirect + github.com/mdlayher/vsock v1.2.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.33.0 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go.sum b/go.sum index ff920287..095a2129 100644 --- a/go.sum +++ b/go.sum @@ -1,26 +1,24 @@ +github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -28,6 +26,14 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= +github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= +github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= +github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/ncabatoff/fakescraper v0.0.0-20201102132415-4b37ba603d65 h1:Og+dVkxEQNvRGU2vUKeOwYT2UJ+pEaDMWB6tIQnIh6A= @@ -37,49 +43,43 @@ github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833/go.mod h1:0CznHmX 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= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= -github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= -github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= -github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= -github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= -github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/exporter-toolkit v0.13.0 h1:lmA0Q+8IaXgmFRKw09RldZmZdnvu9wwcDLIXGmTPw1c= +github.com/prometheus/exporter-toolkit v0.13.0/go.mod h1:2uop99EZl80KdXhv/MxVI2181fMcwlsumFOqBecGkG0= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/proc/base_test.go b/proc/base_test.go index 7302165f..4b559c79 100644 --- a/proc/base_test.go +++ b/proc/base_test.go @@ -51,7 +51,7 @@ func newNamer(names ...string) namer { } func (n namer) String() string { - var ss = make([]string, 0, len(n)) + ss := make([]string, 0, len(n)) for s := range n { ss = append(ss, s) } diff --git a/proc/grouper.go b/proc/grouper.go index bbf240ca..1b44a82d 100644 --- a/proc/grouper.go +++ b/proc/grouper.go @@ -1,6 +1,7 @@ package proc import ( + "log/slog" "time" seq "github.com/ncabatoff/go-seq/seq" @@ -16,7 +17,7 @@ type ( groupAccum map[string]Counts tracker *Tracker threadAccum map[string]map[string]Threads - debug bool + logger *slog.Logger removeEmptyGroups bool } @@ -50,13 +51,13 @@ type ( func lessThreads(x, y Threads) bool { return seq.Compare(x, y) < 0 } // NewGrouper creates a grouper. -func NewGrouper(namer common.MatchNamer, trackChildren, trackThreads, recheck bool, recheckTimeLimit time.Duration, debug bool, removeEmptyGroups bool) *Grouper { +func NewGrouper(namer common.MatchNamer, trackChildren, trackThreads, recheck bool, recheckTimeLimit time.Duration, removeEmptyGroups bool, logger *slog.Logger) *Grouper { g := Grouper{ groupAccum: make(map[string]Counts), threadAccum: make(map[string]map[string]Threads), - tracker: NewTracker(namer, trackChildren, recheck, recheckTimeLimit, debug), - debug: debug, + tracker: NewTracker(namer, trackChildren, recheck, recheckTimeLimit, logger), removeEmptyGroups: removeEmptyGroups, + logger: logger, } return &g } @@ -118,8 +119,7 @@ func (g *Grouper) groups(tracked []Update) GroupByName { for _, update := range tracked { groups[update.GroupName] = groupadd(groups[update.GroupName], update) if update.Threads != nil { - threadsByGroup[update.GroupName] = - append(threadsByGroup[update.GroupName], update.Threads...) + threadsByGroup[update.GroupName] = append(threadsByGroup[update.GroupName], update.Threads...) } } diff --git a/proc/grouper_test.go b/proc/grouper_test.go index 826d1e97..a03bad3a 100644 --- a/proc/grouper_test.go +++ b/proc/grouper_test.go @@ -1,6 +1,8 @@ package proc import ( + "log/slog" + "os" "testing" "time" @@ -8,12 +10,6 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" ) -type grouptest struct { - grouper *Grouper - procs Iter - want GroupByName -} - //func (gt grouptest) run(c *C) { // _, err := gt.grouper.Update(gt.procs) // c.Assert(err, IsNil) @@ -51,10 +47,24 @@ func TestGrouperBasic(t *testing.T) { Filedesc{40, 400}, 3, States{Waiting: 1}), }, GroupByName{ - "g1": Group{Counts{}, States{Other: 1}, msi{}, 1, Memory{7, 8, 0, 0, 0}, starttime, - 4, 0.01, 2, nil}, - "g2": Group{Counts{}, States{Waiting: 1}, msi{}, 1, Memory{8, 9, 0, 0, 0}, starttime, - 40, 0.1, 3, nil}, + "g1": Group{ + Counts{}, + States{Other: 1}, + msi{}, + 1, + Memory{7, 8, 0, 0, 0}, + starttime, + 4, 0.01, 2, nil, + }, + "g2": Group{ + Counts{}, + States{Waiting: 1}, + msi{}, + 1, + Memory{8, 9, 0, 0, 0}, + starttime, + 40, 0.1, 3, nil, + }, }, }, { @@ -65,15 +75,27 @@ func TestGrouperBasic(t *testing.T) { Memory{9, 8, 0, 0, 0}, Filedesc{400, 400}, 2, States{Running: 1}), }, GroupByName{ - "g1": Group{Counts{1, 1, 1, 1, 1, 1, 0, 0}, States{Zombie: 1}, msi{}, 1, - Memory{6, 7, 0, 0, 0}, starttime, 100, 0.25, 4, nil}, - "g2": Group{Counts{2, 2, 2, 2, 2, 2, 0, 0}, States{Running: 1}, msi{}, 1, - Memory{9, 8, 0, 0, 0}, starttime, 400, 1, 2, nil}, + "g1": Group{ + Counts{1, 1, 1, 1, 1, 1, 0, 0}, + States{Zombie: 1}, + msi{}, + 1, + Memory{6, 7, 0, 0, 0}, + starttime, 100, 0.25, 4, nil, + }, + "g2": Group{ + Counts{2, 2, 2, 2, 2, 2, 0, 0}, + States{Running: 1}, + msi{}, + 1, + Memory{9, 8, 0, 0, 0}, + starttime, 400, 1, 2, nil, + }, }, }, } - gr := NewGrouper(newNamer(n1, n2), false, false, false, 0, false, false) + gr := NewGrouper(newNamer(n1, n2), false, false, false, 0, false, slog.Default()) for i, tc := range tests { got := rungroup(t, gr, procInfoIter(tc.procs...)) if diff := cmp.Diff(got, tc.want); diff != "" { @@ -111,8 +133,14 @@ func TestGrouperProcJoin(t *testing.T) { Memory{1, 2, 0, 0, 0}, Filedesc{40, 400}, 3, States{Sleeping: 1}), }, GroupByName{ - "g1": Group{Counts{2, 2, 2, 2, 2, 2, 0, 0}, States{Running: 1, Sleeping: 1}, msi{}, 2, - Memory{4, 6, 0, 0, 0}, starttime, 44, 0.1, 5, nil}, + "g1": Group{ + Counts{2, 2, 2, 2, 2, 2, 0, 0}, + States{Running: 1, Sleeping: 1}, + msi{}, + 2, + Memory{4, 6, 0, 0, 0}, + starttime, 44, 0.1, 5, nil, + }, }, }, { []IDInfo{ @@ -122,13 +150,19 @@ func TestGrouperProcJoin(t *testing.T) { Memory{2, 4, 0, 0, 0}, Filedesc{40, 400}, 3, States{Running: 1}), }, GroupByName{ - "g1": Group{Counts{4, 4, 4, 4, 4, 4, 0, 0}, States{Running: 2}, msi{}, 2, - Memory{3, 9, 0, 0, 0}, starttime, 44, 0.1, 5, nil}, + "g1": Group{ + Counts{4, 4, 4, 4, 4, 4, 0, 0}, + States{Running: 2}, + msi{}, + 2, + Memory{3, 9, 0, 0, 0}, + starttime, 44, 0.1, 5, nil, + }, }, }, } - gr := NewGrouper(newNamer(n1), false, false, false, 0, false, false) + gr := NewGrouper(newNamer(n1), false, false, false, 0, false, slog.Default()) for i, tc := range tests { got := rungroup(t, gr, procInfoIter(tc.procs...)) if diff := cmp.Diff(got, tc.want); diff != "" { @@ -171,7 +205,7 @@ func TestGrouperNonDecreasing(t *testing.T) { }, } - gr := NewGrouper(newNamer(n1), false, false, false, 0, false, false) + gr := NewGrouper(newNamer(n1), false, false, false, 0, false, slog.Default()) for i, tc := range tests { got := rungroup(t, gr, procInfoIter(tc.procs...)) if diff := cmp.Diff(got, tc.want); diff != "" { @@ -213,7 +247,7 @@ func TestGrouperRemoveEmptyGroups(t *testing.T) { }, } - gr := NewGrouper(newNamer(n1, n2), false, false, false, 0, false, true) + gr := NewGrouper(newNamer(n1, n2), false, false, false, 0, false, slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug}))) for i, tc := range tests { got := rungroup(t, gr, procInfoIter(tc.procs...)) if diff := cmp.Diff(got, tc.want); diff != "" { @@ -236,8 +270,8 @@ func TestGrouperThreads(t *testing.T) { }), GroupByName{ "g1": Group{Counts{}, States{}, msi{}, 1, Memory{}, tm, 1, 1, 2, []Threads{ - Threads{"t1", 1, Counts{}}, - Threads{"t2", 1, Counts{}}, + {"t1", 1, Counts{}}, + {"t2", 1, Counts{}}, }}, }, }, { @@ -248,8 +282,8 @@ func TestGrouperThreads(t *testing.T) { }), GroupByName{ "g1": Group{Counts{}, States{}, msi{}, 1, Memory{}, tm, 1, 1, 3, []Threads{ - Threads{"t1", 1, Counts{1, 1, 1, 1, 1, 1, 0, 0}}, - Threads{"t2", 2, Counts{1, 1, 1, 1, 1, 1, 0, 0}}, + {"t1", 1, Counts{1, 1, 1, 1, 1, 1, 0, 0}}, + {"t2", 2, Counts{1, 1, 1, 1, 1, 1, 0, 0}}, }}, }, }, { @@ -259,14 +293,14 @@ func TestGrouperThreads(t *testing.T) { }), GroupByName{ "g1": Group{Counts{}, States{}, msi{}, 1, Memory{}, tm, 1, 1, 2, []Threads{ - Threads{"t2", 2, Counts{4, 5, 6, 7, 8, 9, 0, 0}}, + {"t2", 2, Counts{4, 5, 6, 7, 8, 9, 0, 0}}, }}, }, }, } opts := cmpopts.SortSlices(lessThreads) - gr := NewGrouper(newNamer(n), false, true, false, 0, false, false) + gr := NewGrouper(newNamer(n), false, true, false, 0, false, slog.Default()) for i, tc := range tests { got := rungroup(t, gr, procInfoIter(tc.proc)) if diff := cmp.Diff(got, tc.want, opts); diff != "" { diff --git a/proc/read.go b/proc/read.go index 7358aa1b..fae2ffb4 100644 --- a/proc/read.go +++ b/proc/read.go @@ -107,7 +107,7 @@ type ( // } // Proc wraps the details of the underlying procfs-reading library. - // Any of these methods may fail if the process has disapeared. + // Any of these methods may fail if the process has disappeared. // We try to return as much as possible rather than an error, e.g. // if some /proc files are unreadable. Proc interface { @@ -194,7 +194,6 @@ type ( BootTime uint64 MountPoint string GatherSMaps bool - debug bool } ) @@ -279,7 +278,7 @@ func (p *proccache) GetPid() int { func (p *proccache) getStat() (procfs.ProcStat, error) { if p.stat == nil { - stat, err := p.Proc.NewStat() + stat, err := p.Stat() if err != nil { return procfs.ProcStat{}, err } @@ -490,7 +489,7 @@ func (p proc) GetMetrics() (Metrics, int, error) { softerrors |= 1 } - limits, err := p.Proc.NewLimits() + limits, err := p.Limits() if err != nil { return Metrics{}, 0, err } @@ -583,16 +582,16 @@ const userHZ = 100 // NewFS returns a new FS mounted under the given mountPoint. It will error // if the mount point can't be read. -func NewFS(mountPoint string, debug bool) (*FS, error) { +func NewFS(mountPoint string) (*FS, error) { fs, err := procfs.NewFS(mountPoint) if err != nil { return nil, err } - stat, err := fs.NewStat() + stat, err := fs.Stat() if err != nil { return nil, err } - return &FS{fs, stat.BootTime, mountPoint, false, debug}, nil + return &FS{fs, stat.BootTime, mountPoint, false}, nil } func (fs *FS) threadFs(pid int) (*FS, error) { @@ -601,14 +600,14 @@ func (fs *FS) threadFs(pid int) (*FS, error) { if err != nil { return nil, err } - return &FS{tfs, fs.BootTime, mountPoint, fs.GatherSMaps, false}, nil + return &FS{tfs, fs.BootTime, mountPoint, fs.GatherSMaps}, nil } // AllProcs implements Source. func (fs *FS) AllProcs() Iter { procs, err := fs.FS.AllProcs() if err != nil { - err = fmt.Errorf("Error reading procs: %v", err) + err = fmt.Errorf("error reading procs: %v", err) } return &procIterator{procs: procfsprocs{procs, fs}, err: err, idx: -1} } diff --git a/proc/read_test.go b/proc/read_test.go index bddda5df..7a93fab1 100644 --- a/proc/read_test.go +++ b/proc/read_test.go @@ -29,7 +29,7 @@ func procInfoIter(ps ...IDInfo) *procIterator { } func allprocs(procpath string) Iter { - fs, err := NewFS(procpath, false) + fs, err := NewFS(procpath) if err != nil { cwd, _ := os.Getwd() panic("can't read " + procpath + ", cwd=" + cwd + ", err=" + fmt.Sprintf("%v", err)) @@ -139,6 +139,7 @@ func TestAllProcs(t *testing.T) { t.Errorf("got empty states") } threads, err := procs.GetThreads() + noerr(t, err) if len(threads) < 2 { t.Errorf("got %d thread details, want >1", len(threads)) } diff --git a/proc/tracker.go b/proc/tracker.go index e09e6158..3dd74cc1 100644 --- a/proc/tracker.go +++ b/proc/tracker.go @@ -2,7 +2,7 @@ package proc import ( "fmt" - "log" + "log/slog" "os/user" "strconv" "time" @@ -34,7 +34,7 @@ type ( // limit rechecks to this much time recheckTimeLimit time.Duration username map[int]string - debug bool + logger *slog.Logger } // Delta is an alias of Counts used to signal that its contents are not @@ -113,8 +113,6 @@ func lessUpdateGroupName(x, y Update) bool { return x.GroupName < y.GroupName } func lessThreadUpdate(x, y ThreadUpdate) bool { return seq.Compare(x, y) < 0 } -func lessCounts(x, y Counts) bool { return seq.Compare(x, y) < 0 } - func (tp *trackedProc) getUpdate() Update { u := Update{ GroupName: tp.groupName, @@ -141,7 +139,7 @@ func (tp *trackedProc) getUpdate() Update { } // NewTracker creates a Tracker. -func NewTracker(namer common.MatchNamer, trackChildren bool, recheck bool, recheckTimeLimit time.Duration, debug bool) *Tracker { +func NewTracker(namer common.MatchNamer, trackChildren bool, recheck bool, recheckTimeLimit time.Duration, logger *slog.Logger) *Tracker { return &Tracker{ namer: namer, tracked: make(map[ID]*trackedProc), @@ -150,7 +148,7 @@ func NewTracker(namer common.MatchNamer, trackChildren bool, recheck bool, reche recheck: recheck, recheckTimeLimit: recheckTimeLimit, username: make(map[int]string), - debug: debug, + logger: logger, } } @@ -164,7 +162,8 @@ func (t *Tracker) track(groupName string, idinfo IDInfo) { tproc.threads = make(map[ThreadID]trackedThread) for _, thr := range idinfo.Threads { tproc.threads[thr.ThreadID] = trackedThread{ - thr.ThreadName, thr.Counts, Delta{}, time.Time{}, thr.Wchan} + thr.ThreadName, thr.Counts, Delta{}, time.Time{}, thr.Wchan, + } } } @@ -228,9 +227,7 @@ func (t *Tracker) handleProc(proc Proc, updateTime time.Time) (*IDInfo, CollectE var cerrs CollectErrors procID, err := proc.GetProcID() if err != nil { - if t.debug { - log.Printf("error getting proc ID for pid %+v: %v", proc.GetPid(), err) - } + t.logger.Debug("error getting proc ID", "pid", proc.GetPid(), "error", err.Error()) return nil, cerrs } @@ -242,9 +239,8 @@ func (t *Tracker) handleProc(proc Proc, updateTime time.Time) (*IDInfo, CollectE metrics, softerrors, err := proc.GetMetrics() if err != nil { - if t.debug { - log.Printf("error reading metrics for %+v: %v", procID, err) - } + t.logger.Debug("error reading metrics", "pid", proc.GetPid(), "error", err.Error()) + // This usually happens due to the proc having exited, i.e. // we lost the race. We don't count that as an error. if err != ErrProcNotExist { @@ -256,9 +252,8 @@ func (t *Tracker) handleProc(proc Proc, updateTime time.Time) (*IDInfo, CollectE var threads []Thread threads, err = proc.GetThreads() if err != nil { - if t.debug { - log.Printf("can't read thread metrics for %+v: %v", procID, err) - } + t.logger.Debug("can't read thread metrics", "pid", proc.GetPid(), "error", err.Error()) + softerrors |= 1 } cerrs.Partial += softerrors @@ -278,15 +273,12 @@ func (t *Tracker) handleProc(proc Proc, updateTime time.Time) (*IDInfo, CollectE } else { static, err := proc.GetStatic() if err != nil { - if t.debug { - log.Printf("error reading static details for %+v: %v", procID, err) - } + t.logger.Debug("error reading static details", "pid", proc.GetPid(), "error", err.Error()) + return nil, cerrs } newProc = &IDInfo{procID, static, metrics, threads} - if t.debug { - log.Printf("found new proc: %s", newProc) - } + t.logger.Debug("found new proc", "proc", newProc) // Is this a new process with the same pid as one we already know? // Then delete it from the known map, otherwise the cleanup in Update() @@ -305,7 +297,7 @@ func (t *Tracker) handleProc(proc Proc, updateTime time.Time) (*IDInfo, CollectE func (t *Tracker) update(procs Iter) ([]IDInfo, CollectErrors, error) { var newProcs []IDInfo var colErrs CollectErrors - var now = time.Now() + now := time.Now() for procs.Next() { newProc, cerrs := t.handleProc(procs, now) @@ -348,9 +340,7 @@ func (t *Tracker) checkAncestry(idinfo IDInfo, newprocs map[ID]IDInfo) string { ppid := idinfo.ParentPid pProcID := t.procIds[ppid] if pProcID.Pid < 1 { - if t.debug { - log.Printf("ignoring unmatched proc with no matched parent: %+v", idinfo) - } + t.logger.Debug("ignoring unmatched proc with no matched parent", "proc", idinfo) // Reached root of process tree without finding a tracked parent. t.ignore(idinfo.ID, idinfo.Static.StartTime) return "" @@ -359,10 +349,8 @@ func (t *Tracker) checkAncestry(idinfo IDInfo, newprocs map[ID]IDInfo) string { // Is the parent already known to the tracker? if ptproc, ok := t.tracked[pProcID]; ok { if ptproc != nil { - if t.debug { - log.Printf("matched as %q because child of %+v: %+v", - ptproc.groupName, pProcID, idinfo) - } + t.logger.Debug("matched as child of tracked proc", "parent", ptproc, "child", idinfo) + // We've found a tracked parent. t.track(ptproc.groupName, idinfo) return ptproc.groupName @@ -375,10 +363,7 @@ func (t *Tracker) checkAncestry(idinfo IDInfo, newprocs map[ID]IDInfo) string { // Is the parent another new process? if pinfoid, ok := newprocs[pProcID]; ok { if name := t.checkAncestry(pinfoid, newprocs); name != "" { - if t.debug { - log.Printf("matched as %q because child of %+v: %+v", - name, pProcID, idinfo) - } + t.logger.Debug("matched as child of tracked proc", "parent", pProcID, "child", idinfo) // We've found a tracked parent, which implies this entire lineage should be tracked. t.track(name, idinfo) return name @@ -386,9 +371,7 @@ func (t *Tracker) checkAncestry(idinfo IDInfo, newprocs map[ID]IDInfo) string { } // Parent is dead, i.e. we never saw it, or there's no tracked proc in our ancestry. - if t.debug { - log.Printf("ignoring unmatched proc with no matched parent: %+v", idinfo) - } + t.logger.Debug("ignoring unmatched proc with no matched parent", "proc", idinfo) t.ignore(idinfo.ID, idinfo.Static.StartTime) return "" } @@ -437,9 +420,7 @@ func (t *Tracker) Update(iter Iter) (CollectErrors, []Update, error) { } wanted, gname := t.namer.MatchAndName(nacl) if wanted { - if t.debug { - log.Printf("matched as %q: %+v", gname, idinfo) - } + t.logger.Debug("matched as tracked proc", "group", gname, "proc", idinfo) t.track(gname, idinfo) } else { untracked[idinfo.ID] = idinfo diff --git a/proc/tracker_test.go b/proc/tracker_test.go index 4a295160..1b5c26e6 100644 --- a/proc/tracker_test.go +++ b/proc/tracker_test.go @@ -1,6 +1,7 @@ package proc import ( + "log/slog" "testing" "time" @@ -36,7 +37,7 @@ func TestTrackerBasic(t *testing.T) { }, } // Note that n3 should not be tracked according to our namer. - tr := NewTracker(newNamer(n1, n2, n4), false, false, 0, false) + tr := NewTracker(newNamer(n1, n2, n4), false, false, 0, slog.Default()) opts := cmpopts.SortSlices(lessUpdateGroupName) for i, tc := range tests { @@ -78,7 +79,7 @@ func TestTrackerChildren(t *testing.T) { }, } // Only n2 and children of n2s should be tracked - tr := NewTracker(newNamer(n2), true, false, 0, false) + tr := NewTracker(newNamer(n2), true, false, 0, slog.Default()) for i, tc := range tests { _, got, err := tr.Update(procInfoIter(tc.procs...)) @@ -101,17 +102,34 @@ func TestTrackerMetrics(t *testing.T) { { piinfost(p, n, Counts{1, 2, 3, 4, 5, 6, 0, 0}, Memory{7, 8, 0, 0, 0}, Filedesc{1, 10}, 9, States{Sleeping: 1}), - Update{n, Delta{}, Memory{7, 8, 0, 0, 0}, Filedesc{1, 10}, tm, - 9, States{Sleeping: 1}, msi{}, nil}, + Update{ + n, + Delta{}, + Memory{7, 8, 0, 0, 0}, + Filedesc{1, 10}, + tm, + 9, + States{Sleeping: 1}, + msi{}, + nil, + }, }, { piinfost(p, n, Counts{2, 3, 4, 5, 6, 7, 0, 0}, Memory{1, 2, 0, 0, 0}, Filedesc{2, 20}, 1, States{Running: 1}), - Update{n, Delta{1, 1, 1, 1, 1, 1, 0, 0}, Memory{1, 2, 0, 0, 0}, - Filedesc{2, 20}, tm, 1, States{Running: 1}, msi{}, nil}, + Update{ + n, + Delta{1, 1, 1, 1, 1, 1, 0, 0}, + Memory{1, 2, 0, 0, 0}, + Filedesc{2, 20}, + tm, 1, + States{Running: 1}, + msi{}, + nil, + }, }, } - tr := NewTracker(newNamer(n), false, false, 0, false) + tr := NewTracker(newNamer(n), false, false, 0, slog.Default()) for i, tc := range tests { _, got, err := tr.Update(procInfoIter(tc.proc)) @@ -137,7 +155,14 @@ func TestTrackerThreads(t *testing.T) { {ThreadID(ID{p, 0}), "t1", Counts{1, 2, 3, 4, 5, 6, 0, 0}, "", States{}}, {ThreadID(ID{p + 1, 0}), "t2", Counts{1, 1, 1, 1, 1, 1, 0, 0}, "", States{}}, }), - Update{n, Delta{}, Memory{}, Filedesc{1, 1}, tm, 2, States{}, msi{}, + Update{ + n, + Delta{}, + Memory{}, + Filedesc{1, 1}, + tm, 2, + States{}, + msi{}, []ThreadUpdate{ {"t1", Delta{}}, {"t2", Delta{}}, @@ -149,7 +174,14 @@ func TestTrackerThreads(t *testing.T) { {ThreadID(ID{p + 1, 0}), "t2", Counts{2, 2, 2, 2, 2, 2, 0, 0}, "", States{}}, {ThreadID(ID{p + 2, 0}), "t2", Counts{1, 1, 1, 1, 1, 1, 0, 0}, "", States{}}, }), - Update{n, Delta{}, Memory{}, Filedesc{1, 1}, tm, 3, States{}, msi{}, + Update{ + n, + Delta{}, + Memory{}, + Filedesc{1, 1}, + tm, 3, + States{}, + msi{}, []ThreadUpdate{ {"t1", Delta{1, 1, 1, 1, 1, 1, 0, 0}}, {"t2", Delta{1, 1, 1, 1, 1, 1, 0, 0}}, @@ -161,7 +193,14 @@ func TestTrackerThreads(t *testing.T) { {ThreadID(ID{p, 0}), "t1", Counts{2, 3, 4, 5, 6, 7, 0, 0}, "", States{}}, {ThreadID(ID{p + 2, 0}), "t2", Counts{1, 2, 3, 4, 5, 6, 0, 0}, "", States{}}, }), - Update{n, Delta{}, Memory{}, Filedesc{1, 1}, tm, 2, States{}, msi{}, + Update{ + n, + Delta{}, + Memory{}, + Filedesc{1, 1}, + tm, 2, + States{}, + msi{}, []ThreadUpdate{ {"t1", Delta{}}, {"t2", Delta{0, 1, 2, 3, 4, 5, 0, 0}}, @@ -169,7 +208,7 @@ func TestTrackerThreads(t *testing.T) { }, }, } - tr := NewTracker(newNamer(n), false, false, 0, false) + tr := NewTracker(newNamer(n), false, false, 0, slog.Default()) opts := cmpopts.SortSlices(lessThreadUpdate) for i, tc := range tests {