diff --git a/.gitignore b/.gitignore index 5d8371c..898294a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ *.dll *.so *.dylib -sensu-top-process +sensu-process-ressources # Test binary, build with `go test -c` *.test diff --git a/README.md b/README.md index caa3ee8..1cff0e7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Sensu Bonsai Asset](https://img.shields.io/badge/Bonsai-Download%20Me-brightgreen.svg?colorB=89C967&logo=sensu)](https://bonsai.sensu.io/assets/elfranne/sensu-top-process) -![Go Test](https://github.com/elfranne/sensu-top-process/workflows/Go%20Test/badge.svg) -![goreleaser](https://github.com/elfranne/sensu-top-process/workflows/goreleaser/badge.svg) +[![Sensu Bonsai Asset](https://img.shields.io/badge/Bonsai-Download%20Me-brightgreen.svg?colorB=89C967&logo=sensu)](https://bonsai.sensu.io/assets/elfranne/sensu-process-ressources) +![Go Test](https://github.com/elfranne/sensu-process-ressources/workflows/Go%20Test/badge.svg) +![goreleaser](https://github.com/elfranne/sensu-process-ressources/workflows/goreleaser/badge.svg) # Check Plugin Template @@ -18,7 +18,7 @@ and customize the `checkArgs` and `executeCheck` functions in [main.go][7]. When writing or updating a plugin's README from this template, review the Sensu Community [plugin README style guide][3] for content suggestions and guidance. Remove everything -prior to `# sensu-top-process` from the generated README file, and add additional context about the +prior to `# sensu-process-ressources` from the generated README file, and add additional context about the plugin per the style guide. ## Releases with Github Actions @@ -29,7 +29,7 @@ the plugin with goreleaser. Register the asset with [Bonsai][8] to share it with *** -# sensu-top-process +# sensu-process-ressources ## Table of Contents - [Overview](#overview) @@ -44,7 +44,7 @@ the plugin with goreleaser. Register the asset with [Bonsai][8] to share it with ## Overview -The sensu-top-process is a [Sensu Check][6] that ... +The sensu-process-ressources is a [Sensu Check][6] that ... ## Files @@ -59,10 +59,10 @@ consider doing so! If you're using sensuctl 5.13 with Sensu Backend 5.13 or late following command to add the asset: ``` -sensuctl asset add elfranne/sensu-top-process +sensuctl asset add elfranne/sensu-process-ressources ``` -If you're using an earlier version of sensuctl, you can find the asset on the [Bonsai Asset Index][https://bonsai.sensu.io/assets/elfranne/sensu-top-process]. +If you're using an earlier version of sensuctl, you can find the asset on the [Bonsai Asset Index][https://bonsai.sensu.io/assets/elfranne/sensu-process-ressources]. ### Check definition @@ -71,14 +71,14 @@ If you're using an earlier version of sensuctl, you can find the asset on the [B type: CheckConfig api_version: core/v2 metadata: - name: sensu-top-process + name: sensu-process-ressources namespace: default spec: - command: sensu-top-process --example example_arg + command: sensu-process-ressources --example example_arg subscriptions: - system runtime_assets: - - elfranne/sensu-top-process + - elfranne/sensu-process-ressources ``` ## Installation from source @@ -87,7 +87,7 @@ The preferred way of installing and deploying this plugin is to use it as an Ass like to compile and install the plugin from source or contribute to it, download the latest version or create an executable script from this source. -From the local path of the sensu-top-process repository: +From the local path of the sensu-process-ressources repository: ``` go build @@ -102,8 +102,8 @@ For more information about contributing to this plugin, see [Contributing][1]. [1]: https://github.com/sensu/sensu-go/blob/master/CONTRIBUTING.md [2]: https://github.com/sensu/sensu-plugin-sdk [3]: https://github.com/sensu-plugins/community/blob/master/PLUGIN_STYLEGUIDE.md -[4]: https://github.com/elfranne/sensu-top-process/blob/master/.github/workflows/release.yml -[5]: https://github.com/elfranne/sensu-top-process/actions +[4]: https://github.com/elfranne/sensu-process-ressources/blob/master/.github/workflows/release.yml +[5]: https://github.com/elfranne/sensu-process-ressources/actions [6]: https://docs.sensu.io/sensu-go/latest/reference/checks/ [7]: https://github.com/sensu/check-plugin-template/blob/master/main.go [8]: https://bonsai.sensu.io/ diff --git a/go.mod b/go.mod index 0c9f2bb..836bf5b 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ -module github.com/elfranne/sensu-top-process +module github.com/elfranne/sensu-process-ressources go 1.18 require ( github.com/sensu/core/v2 v2.19.0 github.com/sensu/sensu-plugin-sdk v0.18.0 - github.com/shirou/gopsutil/v3 v3.23.7 + github.com/shirou/gopsutil/v3 v3.23.9 ) require ( @@ -39,12 +39,12 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.7.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect - github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/etcd/api/v3 v3.5.5 // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect - golang.org/x/sys v0.10.0 // indirect + golang.org/x/sys v0.12.0 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect google.golang.org/grpc v1.41.0 // indirect diff --git a/go.sum b/go.sum index 6b6f874..980e40c 100644 --- a/go.sum +++ b/go.sum @@ -220,8 +220,8 @@ github.com/sensu/sensu-licensing/v2 v2.2.1 h1:9JI4iVm4ujWN4etI/Kdper6Q2lOn3HIEaG github.com/sensu/sensu-licensing/v2 v2.2.1/go.mod h1:53lwddwN4XwZUld5KtnWQduSH6F8rBOsWuEk2EUeooI= github.com/sensu/sensu-plugin-sdk v0.18.0 h1:aR5N9SsqRm1NqiJo7k8GeLEPwGQIfeY4bbePPByUdnI= github.com/sensu/sensu-plugin-sdk v0.18.0/go.mod h1:NCcvkFZka5Az4Z+l9greCQQdEzTfilO4+JoURmELCa4= -github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= -github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -262,10 +262,10 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= -github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= -github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -365,9 +365,10 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/main.go b/main.go index 4c21f1e..5603277 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,6 @@ package main import ( "fmt" "math" - "regexp" - "time" corev2 "github.com/sensu/core/v2" "github.com/sensu/sensu-plugin-sdk/sensu" @@ -14,53 +12,58 @@ import ( // Config represents the check plugin config. type Config struct { sensu.PluginConfig - CPU float64 - Memory float32 - Scheme string - Expand string + CPUWarn float64 + CPUCrit float64 + MemoryWarn float32 + MemoryCrit float32 + Scheme string + Process string } var ( plugin = Config{ PluginConfig: sensu.PluginConfig{ - Name: "check-cpu-usage", - Short: "Check CPU usage and provide metrics", - Keyspace: "sensu.io/plugins/check-cpu-usage/config", + Name: "check-process-ressources", + Short: "Check if process is using too much ressources (CPU/memory)", + Keyspace: "sensu.io/plugins/check-process-ressources/config", }, } options = []sensu.ConfigOption{ + &sensu.PluginConfigOption[string]{ + Path: "process", + Argument: "process", + Default: "", + Usage: "Process to monitor", + Value: &plugin.Process, + }, &sensu.PluginConfigOption[float64]{ - Path: "cpu", - Argument: "cpu", - Shorthand: "c", - Default: float64(10), - Usage: "Show metrics for processes above CPU x%", - Value: &plugin.CPU, + Path: "cpu-warn", + Argument: "cpu-warn", + Default: float64(50), + Usage: "Warn if process is using more than cpu-warn (in percent)", + Value: &plugin.CPUWarn, }, - &sensu.PluginConfigOption[float32]{ - Path: "memory", - Argument: "memory", - Shorthand: "m", - Default: float32(10), - Usage: "Show metrics for processes above Memory x%", - Value: &plugin.Memory, + &sensu.PluginConfigOption[float64]{ + Path: "cpucrit", + Argument: "cpucrit", + Default: float64(75), + Usage: "Critical if process is using more than cpu-crit (in percent)", + Value: &plugin.CPUCrit, }, - &sensu.PluginConfigOption[string]{ - Path: "scheme", - Argument: "scheme", - Shorthand: "s", - Default: "", - Usage: "Scheme to prepend metric", - Value: &plugin.Scheme, + &sensu.PluginConfigOption[float32]{ + Path: "memory-warn", + Argument: "memory-warn", + Default: float32(50), + Usage: "Warn if process is using more than memory-warn (in percent)", + Value: &plugin.MemoryWarn, }, - &sensu.PluginConfigOption[string]{ - Path: "expand", - Argument: "expand", - Shorthand: "e", - Default: "", - Usage: "Expand name for process to include argurment(s) (usefull for bash or powershell)", - Value: &plugin.Expand, + &sensu.PluginConfigOption[float32]{ + Path: "memory-crit", + Argument: "memory-crit", + Default: float32(70), + Usage: "Critical if process is using more than memory-crit (in percent)", + Value: &plugin.MemoryCrit, }, } ) @@ -71,14 +74,20 @@ func main() { } func checkArgs(event *corev2.Event) (int, error) { - if plugin.CPU == 100 { + if plugin.CPUCrit == 100 { + return sensu.CheckStateWarning, fmt.Errorf("that's just stupid") + } + if plugin.CPUWarn == 100 { + return sensu.CheckStateWarning, fmt.Errorf("that's just stupid") + } + if plugin.MemoryCrit == 100 { return sensu.CheckStateWarning, fmt.Errorf("that's just stupid") } - if plugin.Memory == 100 { + if plugin.MemoryWarn == 100 { return sensu.CheckStateWarning, fmt.Errorf("that's just stupid") } - if plugin.Scheme == "" { - return sensu.CheckStateWarning, fmt.Errorf("scheme is required") + if plugin.Process == "" { + return sensu.CheckStateWarning, fmt.Errorf("process is required") } return sensu.CheckStateOK, nil @@ -88,27 +97,32 @@ func Round(x, unit float64) float64 { return math.Round(x/unit) * unit } -func ExpandName(name string, p *process.Process) string { - if plugin.Expand == name { - cmd, _ := p.Cmdline() - return cmd - } else { - return name - } -} - func executeCheck(event *corev2.Event) (int, error) { - re := regexp.MustCompile(`-+|\s+|/+|:+|\.+|,+|=+`) process, _ := process.Processes() for _, p := range process { cpu, _ := p.CPUPercent() memory, _ := p.MemoryPercent() name, _ := p.Name() - expanded := ExpandName(name, p) - if cpu >= plugin.CPU || memory >= plugin.Memory { - fmt.Printf("%s.process.cpu_percent.%s %f %d\n", plugin.Scheme, re.ReplaceAllString(expanded, "_"), Round(cpu, 0.1), time.Now().Unix()) - fmt.Printf("%s.process.memory_percent.%s %f %d\n", plugin.Scheme, re.ReplaceAllString(expanded, "_"), Round(float64(memory), 0.1), time.Now().Unix()) + // Warning memory + if name == plugin.Process && memory >= plugin.MemoryWarn { + fmt.Printf("%s is using %f %% memory, limit set at %f\n", plugin.Process, Round(float64(memory), 0.1), plugin.MemoryWarn) + return sensu.CheckStateWarning, nil + } + // Warning CPU + if name == plugin.Process && cpu >= plugin.CPUWarn { + fmt.Printf("%s is using %f %% CPU, limit set at %f\n", plugin.Process, Round(float64(cpu), 0.1), plugin.CPUWarn) + return sensu.CheckStateWarning, nil + } + // Critical memory + if name == plugin.Process && memory >= plugin.MemoryCrit { + fmt.Printf("%s is using %f %% memory, limit set at %f\n", plugin.Process, Round(float64(memory), 0.1), plugin.MemoryCrit) + return sensu.CheckStateCritical, nil + } + // Critical CPU + if name == plugin.Process && cpu >= plugin.CPUCrit { + fmt.Printf("%s is using %f %% CPU, limit set at %f\n", plugin.Process, Round(float64(cpu), 0.1), plugin.CPUCrit) + return sensu.CheckStateCritical, nil } } return sensu.CheckStateOK, nil