├── .bonsai.yml ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .kitchen.yml ├── .rubocop.yml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin ├── check-load.rb └── metrics-load.rb ├── lib ├── sensu-plugins-load-checks.rb └── sensu-plugins-load-checks │ ├── load-average.rb │ └── version.rb ├── sensu-plugins-load-checks.gemspec └── test ├── fixtures └── bootstrap.sh ├── integration ├── helpers │ └── serverspec │ │ ├── check-load_spec.rb │ │ ├── metrics-load_spec.rb │ │ ├── shared_spec.rb │ │ └── spec_helper.rb ├── ruby-21 │ └── serverspec │ │ └── default_spec.rb ├── ruby-22 │ └── serverspec │ │ └── default_spec.rb ├── ruby-230 │ └── serverspec │ │ └── default_spec.rb └── ruby-241 │ └── serverspec │ └── default_spec.rb └── spec_helper.rb /.bonsai.yml: -------------------------------------------------------------------------------- 1 | --- 2 | description: "#{repo}" 3 | builds: 4 | - platform: "alpine" 5 | arch: "amd64" 6 | asset_filename: "#{repo}_#{version}_alpine_linux_amd64.tar.gz" 7 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 8 | filter: 9 | - "entity.system.os == 'linux'" 10 | - "entity.system.arch == 'amd64'" 11 | - "entity.system.platform == 'alpine'" 12 | - "entity.system.platform_version.split('.')[0] == '3'" 13 | - platform: "alpine3.8" 14 | arch: "amd64" 15 | asset_filename: "#{repo}_#{version}_alpine3.8_linux_amd64.tar.gz" 16 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 17 | filter: 18 | - "entity.system.os == 'linux'" 19 | - "entity.system.arch == 'amd64'" 20 | - "entity.system.platform == 'alpine'" 21 | - platform: "centos" 22 | arch: "amd64" 23 | asset_filename: "#{repo}_#{version}_centos_linux_amd64.tar.gz" 24 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 25 | filter: 26 | - "entity.system.os == 'linux'" 27 | - "entity.system.arch == 'amd64'" 28 | - "entity.system.platform_family == 'rhel'" 29 | - platform: "centos6" 30 | arch: "amd64" 31 | asset_filename: "#{repo}_#{version}_centos6_linux_amd64.tar.gz" 32 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 33 | filter: 34 | - "entity.system.os == 'linux'" 35 | - "entity.system.arch == 'amd64'" 36 | - "entity.system.platform_family == 'rhel'" 37 | - "entity.system.platform_version.split('.')[0] == '6'" 38 | - platform: "centos7" 39 | arch: "amd64" 40 | asset_filename: "#{repo}_#{version}_centos7_linux_amd64.tar.gz" 41 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 42 | filter: 43 | - "entity.system.os == 'linux'" 44 | - "entity.system.arch == 'amd64'" 45 | - "entity.system.platform_family == 'rhel'" 46 | - "entity.system.platform_version.split('.')[0] == '7'" 47 | - platform: "debian" 48 | arch: "amd64" 49 | asset_filename: "#{repo}_#{version}_debian_linux_amd64.tar.gz" 50 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 51 | filter: 52 | - "entity.system.os == 'linux'" 53 | - "entity.system.arch == 'amd64'" 54 | - "entity.system.platform_family == 'debian'" 55 | - platform: "debian9" 56 | arch: "amd64" 57 | asset_filename: "#{repo}_#{version}_debian9_linux_amd64.tar.gz" 58 | sha_filename: "#{repo}_#{version}_sha512-checksums.txt" 59 | filter: 60 | - "entity.system.os == 'linux'" 61 | - "entity.system.arch == 'amd64'" 62 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Pull Request Checklist 2 | 3 | **Is this in reference to an existing issue?** 4 | 5 | #### General 6 | 7 | - [ ] Update Changelog following the conventions laid out [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) 8 | 9 | - [ ] Update README with any necessary configuration snippets 10 | 11 | - [ ] Binstubs are created if needed 12 | 13 | - [ ] RuboCop passes 14 | 15 | - [ ] Existing tests pass 16 | 17 | #### New Plugins 18 | 19 | - [ ] Tests 20 | 21 | - [ ] Add the plugin to the README 22 | 23 | - [ ] Does it have a complete header as outlined [here](http://sensu-plugins.io/docs/developer_guidelines.html#coding-style) 24 | 25 | #### Purpose 26 | 27 | #### Known Compatibility Issues 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.bundle 11 | *.so 12 | *.o 13 | *.a 14 | mkmf.log 15 | .vagrant/* 16 | .DS_Store 17 | .idea/* 18 | *.gem 19 | .kitchen 20 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: docker 4 | use_sudo: false 5 | 6 | provisioner: 7 | name: shell 8 | data_path: . 9 | script: test/fixtures/bootstrap.sh 10 | 11 | # verifier: 12 | # ruby_bindir: <%= ENV['MY_RUBY_HOME'] || '/opt/sensu/embedded' %>/bin 13 | verifier: 14 | ruby_bindir: /usr/local/bin 15 | 16 | platforms: 17 | - name: debian-8 18 | 19 | suites: 20 | - name: ruby-21 21 | driver: 22 | image: ruby:2.1-slim 23 | - name: ruby-22 24 | driver: 25 | image: ruby:2.2-slim 26 | - name: ruby-230 27 | driver: 28 | image: ruby:2.3.0-slim 29 | - name: ruby-241 30 | driver: 31 | image: ruby:2.4.1-slim 32 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | 2 | MethodLength: 3 | Max: 200 4 | 5 | LineLength: 6 | Max: 160 7 | 8 | AbcSize: 9 | Max: 100 10 | 11 | FileName: 12 | Enabled: false 13 | 14 | PerceivedComplexity: 15 | Enabled: false 16 | 17 | CyclomaticComplexity: 18 | Enabled: false 19 | 20 | ClassLength: 21 | Enabled: false 22 | 23 | IfUnlessModifier: 24 | Enabled: false 25 | 26 | RegexpLiteral: 27 | Enabled: false 28 | 29 | Style/Documentation: 30 | Enabled: false 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: true 2 | services: docker 3 | language: ruby 4 | cache: 5 | - bundler 6 | install: 7 | - bundle install 8 | rvm: 9 | - 2.3.0 10 | - 2.4.1 11 | notifications: 12 | email: 13 | recipients: 14 | - sensu-plugin@sensu-plugins.io 15 | on_success: change 16 | on_failure: always 17 | script: 18 | - bundle exec rake quick 19 | #- bundle exec rake kitchen:ruby-`echo $TRAVIS_RUBY_VERSION | sed -e "s/\.//g"`-debian-8 20 | - gem build sensu-plugins-load-checks.gemspec 21 | - gem install sensu-plugins-load-checks-*.gem 22 | before_deploy: 23 | - bash -c "[ ! -d bonsai/ ] && git clone https://github.com/sensu/sensu-go-bonsai-asset.git bonsai || echo 'bonsai/ exists, skipping git clone'" 24 | deploy: 25 | - provider: rubygems 26 | api_key: 27 | secure: J19rBhFsEYozDnd5nAqLVGldCJRsyT5//9ZqbbtLIxgnoNllEPA0Qq3X358zkjZ8b1L+JrnRjv+/WyXNrUkXMP0/YLgy5T1rG90HhGp2dqXacF20Tj/6so4y8S4WKv7Y3Kf4vdxQFlPPBOaYzhvDkeIQuPUBxjMHvpmvsrK3RPg= 28 | gem: sensu-plugins-load-checks 29 | on: 30 | tags: true 31 | all_branches: true 32 | rvm: 2.3.0 33 | rvm: 2.4.1 34 | repo: sensu-plugins/sensu-plugins-load-checks 35 | - provider: script 36 | script: bonsai/ruby-runtime/travis-build-ruby-plugin-assets.sh sensu-plugins-load-checks 37 | skip_cleanup: true 38 | on: 39 | tags: true 40 | all_branches: true 41 | rvm: 2.4.1 42 | 43 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | This project adheres to [Semantic Versioning](http://semver.org/). 3 | 4 | This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) 5 | 6 | ## [Unreleased] 7 | 8 | ## [5.1.0] - 2019-12-12 9 | ### Added 10 | - Updated asset build targets to support centos6 11 | 12 | ## [5.0.0] - 2019-04-18 13 | ### Breaking Changes 14 | - Update minimum required ruby version to 2.3. Drop unsupported ruby versions. 15 | - Bump `sensu-plugin` dependency from `~> 1.2` to `~> 4.0` you can read the changelog entries for [4.0](https://github.com/sensu-plugins/sensu-plugin/blob/master/CHANGELOG.md#400---2018-02-17), [3.0](https://github.com/sensu-plugins/sensu-plugin/blob/master/CHANGELOG.md#300---2018-12-04), and [2.0](https://github.com/sensu-plugins/sensu-plugin/blob/master/CHANGELOG.md#v200---2017-03-29) 16 | 17 | ### Added 18 | - Travis build automation to generate Sensu Asset tarballs that can be used n conjunction with Sensu provided ruby runtime assets and the Bonsai Asset Index 19 | - Require latest sensu-plugin for [Sensu Go support](https://github.com/sensu-plugins/sensu-plugin#sensu-go-enablement) 20 | 21 | 22 | ## [4.0.2] - 2018-03-27 23 | ### Security 24 | - updated yard dependency to `~> 0.9.11` per: https://nvd.nist.gov/vuln/detail/CVE-2017-17042 (@majormoses) 25 | 26 | ## [4.0.1] - 2018-03-07 27 | ### Security 28 | - updated rubocop dependency to `~> 0.51.0` per: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8418. (@majormoses) 29 | 30 | ### Changed 31 | - appeased the cops (@majormoses) 32 | 33 | ### Fixed 34 | - Remove the comment explaining the per-cores flag from the merics-load.rb file as this option no longer exists (@AaronKalair) 35 | 36 | ### Fixed 37 | - use the `quick` tests as we want to not run all integration tests just the requested suites (@majormoses) 38 | 39 | ## [4.0.0] - 2017-10-03 40 | ### Breaking Changes 41 | - dropped support for Ruby 2.0.0 (@barryorourke) 42 | 43 | ### Added 44 | - now includes kitchen integration tests (@barryorourke) 45 | - added ruby 2.4 testing (@majormoses) 46 | 47 | ### Changed 48 | - updated the changelog location guidelines (@majormoses) 49 | 50 | ### Fixed 51 | - PR template spelling (@majormoses) 52 | - make changelog a title (@majormoses) 53 | 54 | ## [3.0.0] - 05-18-2017 55 | ### Breaking Change 56 | - bin/check-load.rb remove option for per_core as its useless and broken (@majormoses) 57 | - bin/metrics-load.rb remove option for per_core as its useless and broken (@majormoses) 58 | 59 | ### Changed 60 | - moved common logic into its own library location (@majormoses) 61 | ### Fixed 62 | - bin/metrics-load.rb now uses common logic which fixes issues with uptime LOCALE parsing (@majormoses) 63 | 64 | ### [2.0.0] 65 | ### Breaking Change 66 | - bin/check-load.rb change the default of per_core to true (@majormoses) 67 | ### Changed 68 | - Use the `uptime` command in bin/check-load.rb as well (@smuth4) 69 | - Correctly detect the number of cores on BSD (@smuth4) 70 | - bin/check-load.rb better output message (@woltage) 71 | - bin/check-load.rb change the default thresholds to better align with per_core values (@majormoses) 72 | - bin/check-load.rb changes to use >= rather than > for thresholds (@majormoses) 73 | - bin/check-load.rb switch to using 'unknown' rather than 'warning' when unable to determine the load average (@majormoses) 74 | 75 | ## [1.0.0] - 2016-06-16 76 | ### Changed 77 | - Loosen dependency on sensu-plugin from `= 1.2.0` to `~> 1.2` 78 | - Update Rubocop to 0.40, apply auto-correct. 79 | 80 | ### Removed 81 | - Removed Ruby 1.9.3 support; add Ruby 2.3.0 support to test matrix. 82 | 83 | ## [0.0.4] - 2015-12-11 84 | ### Changed 85 | - Use pure ruby for cpu count in check-load.rb 86 | 87 | ## [0.0.3] - 2015-07-14 88 | ### Changed 89 | - updated sensu-plugin gem to 1.2.0 90 | 91 | ## [0.0.2] - 2015-06-03 92 | ### Fixed 93 | - added binstubs 94 | 95 | ### Changed 96 | - removed cruft from /lib 97 | 98 | ## 0.0.1 - 2015-05-21 99 | ### Added 100 | - initial release 101 | 102 | [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/5.1.0...HEAD 103 | [5.1.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/5.0.0...5.1.0 104 | [5.0.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/4.0.2...5.0.0 105 | [4.0.2]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/4.0.1...4.0.2 106 | [4.0.1]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/4.0.0...4.0.1 107 | [4.0.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/3.0.0...4.0.0 108 | [3.0.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/2.0.0...3.0.0 109 | [2.0.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/1.0.0...2.0.0 110 | [1.0.0]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/0.0.4...1.0.0 111 | [0.0.4]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/0.0.3...0.0.4 112 | [0.0.3]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/0.0.2...0.0.3 113 | [0.0.2]: https://github.com/sensu-plugins/sensu-plugins-load-checks/compare/0.0.1...0.0.2 114 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | [Development Documentation](http://sensu-plugins.io/docs/developer_guidelines.html) 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Sensu-Plugins 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Sensu Bonsai Asset](https://img.shields.io/badge/Bonsai-Download%20Me-brightgreen.svg?colorB=89C967&logo=sensu)](https://bonsai.sensu.io/assets/sensu-plugins/sensu-plugins-load-checks) 2 | [ ![Build Status](https://travis-ci.org/sensu-plugins/sensu-plugins-load-checks.svg?branch=master)](https://travis-ci.org/sensu-plugins/sensu-plugins-load-checks) 3 | [![Gem Version](https://badge.fury.io/rb/sensu-plugins-load-checks.svg)](http://badge.fury.io/rb/sensu-plugins-load-checks) 4 | [![Code Climate](https://codeclimate.com/github/sensu-plugins/sensu-plugins-load-checks/badges/gpa.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-load-checks) 5 | [![Test Coverage](https://codeclimate.com/github/sensu-plugins/sensu-plugins-load-checks/badges/coverage.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-load-checks) 6 | [![Dependency Status](https://gemnasium.com/sensu-plugins/sensu-plugins-load-checks.svg)](https://gemnasium.com/sensu-plugins/sensu-plugins-load-checks) 7 | 8 | ## Sensu Plugins Load Checks Plugin 9 | 10 | - [Overview](#overview) 11 | - [Files](#files) 12 | - [Usage examples](#usage-examples) 13 | - [Configuration](#configuration) 14 | - [Sensu Go](#sensu-go) 15 | - [Asset registration](#asset-registration) 16 | - [Asset definition](#asset-definition) 17 | - [Check definition](#check-definition) 18 | - [Sensu Core](#sensu-core) 19 | - [Check definition](#check-definition) 20 | - [Installation from source](#installation-from-source) 21 | - [Additional notes](#additional-notes) 22 | - [Contributing](#contributing) 23 | 24 | ### Overview 25 | 26 | This plugin provides native load instrumentation for monitoring and metrics collection, including load health and total or per-core metrics. 27 | 28 | ### Files 29 | * bin/check-load.rb 30 | * bin/metrics-load.rb 31 | 32 | **check-load** 33 | Takes the `loadavg` and divides by the number of cores. 34 | 35 | **metrics-load** 36 | Uses uptime to collect load metrics. The number of CPUs is determined by reading `/proc/cpuinfo`, which makes the feature Linux-specific. 37 | 38 | ## Usage examples 39 | 40 | ### Help 41 | 42 | **check-load.rb** 43 | ``` 44 | Usage: check-load.rb (options) 45 | -c, --crit L1,L5,L15 Load CRITICAL threshold, 1/5/15 min average 46 | -w, --warn L1,L5,L15 Load WARNING threshold, 1/5/15 min average 47 | ``` 48 | 49 | **metrics-load.rb** 50 | ``` 51 | Usage: metrics-load.rb (options) 52 | --scheme SCHEME Metric naming scheme, text to prepend to .$parent.$child 53 | ``` 54 | 55 | ## Configuration 56 | ### Sensu Go 57 | #### Asset registration 58 | 59 | Assets are the best way to make use of this plugin. If you're not using an asset, please consider doing so! If you're using sensuctl 5.13 or later, you can use the following command to add the asset: 60 | 61 | `sensuctl asset add sensu-plugins/sensu-plugins-load-checks` 62 | 63 | If you're using an earlier version of sensuctl, you can download the asset definition from [this project's Bonsai asset index page](https://bonsai.sensu.io/assets/sensu-plugins/sensu-plugins-load-checks). 64 | 65 | #### Asset definition 66 | 67 | ```yaml 68 | --- 69 | type: Asset 70 | api_version: core/v2 71 | metadata: 72 | name: sensu-plugins-load-checks 73 | spec: 74 | url: https://assets.bonsai.sensu.io/1accacdd780175a02183e722effa0986e6472f21/sensu-plugins-load-checks_5.0.0_centos_linux_amd64.tar.gz 75 | sha512: 0e97bc162d6f9529ef044d0173f97330c597d31cf3389539baed6d17c713a8961e8d7e0f62b2f195eae6da66dc65ddfbff59379f0c846596b29fb6977b4e368b 76 | ``` 77 | 78 | #### Check definition 79 | 80 | ```yaml 81 | --- 82 | type: CheckConfig 83 | spec: 84 | command: "check-load.rb" 85 | handlers: [] 86 | high_flap_threshold: 0 87 | interval: 10 88 | low_flap_threshold: 0 89 | publish: true 90 | runtime_assets: 91 | - sensu-plugins/sensu-plugins-load-checks 92 | - sensu/sensu-ruby-runtime 93 | subscriptions: 94 | - linux 95 | ``` 96 | 97 | ### Sensu Core 98 | 99 | #### Check definition 100 | ```json 101 | { 102 | "checks": { 103 | "check-load": { 104 | "command": "check-load.rb", 105 | "subscribers": ["linux"], 106 | "interval": 10, 107 | "refresh": 10, 108 | "handlers": ["influxdb"] 109 | } 110 | } 111 | } 112 | ``` 113 | 114 | ## Installation from source 115 | 116 | ### Sensu Go 117 | 118 | See the instructions above for [asset registration](#asset-registration). 119 | 120 | ### Sensu Core 121 | 122 | Install and setup plugins on [Sensu Core](https://docs.sensu.io/sensu-core/latest/installation/installing-plugins/). 123 | 124 | ## Additional notes 125 | 126 | ### Sensu Go Ruby Runtime Assets 127 | 128 | The Sensu assets packaged from this repository are built against the Sensu Ruby runtime environment. When using these assets as part of a Sensu Go resource (check, mutator, or handler), make sure to include the corresponding [Sensu Ruby Runtime Asset](https://bonsai.sensu.io/assets/sensu/sensu-ruby-runtime) in the list of assets needed by the resource. 129 | 130 | ## Contributing 131 | 132 | See [CONTRIBUTING.md](https://github.com/sensu-plugins/sensu-plugins-load-checks/blob/master/CONTRIBUTING.md) for information about contributing to this plugin. 133 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'github/markup' 3 | require 'redcarpet' 4 | require 'rspec/core/rake_task' 5 | require 'rubocop/rake_task' 6 | require 'yard' 7 | require 'yard/rake/yardoc_task' 8 | require 'kitchen/rake_tasks' 9 | 10 | YARD::Rake::YardocTask.new do |t| 11 | OTHER_PATHS = %w[].freeze 12 | t.files = ['lib/**/*.rb', 'bin/**/*.rb', OTHER_PATHS] 13 | t.options = %w[--markup-provider=redcarpet --markup=markdown --main=README.md --files CHANGELOG.md] 14 | end 15 | 16 | RuboCop::RakeTask.new 17 | 18 | RSpec::Core::RakeTask.new(:spec) do |r| 19 | r.pattern = FileList['**/**/*_spec.rb'] 20 | end 21 | 22 | desc 'Make all plugins executable' 23 | task :make_bin_executable do 24 | `chmod -R +x bin/*` 25 | end 26 | 27 | desc 'Test for binstubs' 28 | task :check_binstubs do 29 | bin_list = Gem::Specification.load('sensu-plugins-load-checks.gemspec').executables 30 | bin_list.each do |b| 31 | `which #{ b }` 32 | unless $CHILD_STATUS.success? 33 | puts "#{b} was not a binstub" 34 | exit 35 | end 36 | end 37 | end 38 | 39 | Kitchen::RakeTasks.new 40 | 41 | desc 'Alias for kitchen:all' 42 | task integration: 'kitchen:all' 43 | 44 | task default: %i[make_bin_executable yard rubocop check_binstubs integration] 45 | 46 | task quick: %i[make_bin_executable yard rubocop check_binstubs] 47 | -------------------------------------------------------------------------------- /bin/check-load.rb: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ruby 2 | # 3 | # check-load 4 | # 5 | # DESCRIPTION: 6 | # 7 | # OUTPUT: 8 | # plain text 9 | # 10 | # PLATFORMS: 11 | # Linux, BSD, Solaris, etc 12 | # 13 | # DEPENDENCIES: 14 | # gem: sensu-plugin 15 | # 16 | # USAGE: 17 | # ./bin/check-load.rb --help 18 | # NOTES: 19 | # 20 | # LICENSE: 21 | # Copyright 2012 Sonian, Inc 22 | # Released under the same terms as Sensu (the MIT license); see LICENSE 23 | # for details. 24 | # 25 | 26 | require 'sensu-plugin/check/cli' 27 | require_relative '../lib/sensu-plugins-load-checks/load-average.rb' 28 | 29 | class CheckLoad < Sensu::Plugin::Check::CLI 30 | option :warn, 31 | short: '-w L1,L5,L15', 32 | long: '--warn L1,L5,L15', 33 | description: 'Load WARNING threshold, 1/5/15 min average', 34 | proc: proc { |a| a.split(',').map(&:to_f) }, 35 | default: [2.75, 2.5, 2.0] 36 | 37 | option :crit, 38 | short: '-c L1,L5,L15', 39 | long: '--crit L1,L5,L15', 40 | description: 'Load CRITICAL threshold, 1/5/15 min average', 41 | proc: proc { |a| a.split(',').map(&:to_f) }, 42 | default: [3.5, 3.25, 3.0] 43 | 44 | def run 45 | data = LoadAverage.new 46 | unknown 'Could not read load average from /proc or `uptime`' if data.failed? 47 | 48 | message "Per core load average (#{data.cpu_count} CPU): #{data.load_avg}" 49 | 50 | critical if data.exceed?(config[:crit]) 51 | warning if data.exceed?(config[:warn]) 52 | ok 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /bin/metrics-load.rb: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ruby 2 | 3 | # 4 | # DESCRIPTION: 5 | # This plugin uses uptime to collect load metrics 6 | # Basically copied from sensu-community-plugins/plugins/system/vmstat-metrics.rb 7 | # 8 | # Load per processor 9 | # ------------------ 10 | # 11 | # The number of CPUs is determined by reading `/proc/cpuinfo`. This makes the 12 | # feature Linux specific. Other OSs can be supported by adding OS # detection 13 | # and a method to determine the number of CPUs. 14 | # 15 | # OUTPUT: 16 | # metric data 17 | # 18 | # PLATFORMS: 19 | # Linux, BSD, Solaris, etc 20 | # 21 | # DEPENDENCIES: 22 | # gem: sensu-plugin 23 | # gem: socket 24 | # 25 | # USAGE: 26 | # 27 | # NOTES: 28 | # 29 | # LICENSE: 30 | # Copyright 2012 Sonian, Inc 31 | # Released under the same terms as Sensu (the MIT license); see LICENSE 32 | # for details. 33 | # 34 | 35 | require 'sensu-plugin/metric/cli' 36 | require_relative '../lib/sensu-plugins-load-checks/load-average.rb' 37 | require 'socket' 38 | 39 | class LoadStat < Sensu::Plugin::Metric::CLI::Graphite 40 | option :scheme, 41 | description: 'Metric naming scheme, text to prepend to .$parent.$child', 42 | long: '--scheme SCHEME', 43 | default: Socket.gethostname.to_s 44 | 45 | def run 46 | data = LoadAverage.new 47 | unknown 'Could not read load average from /proc or `uptime`' if data.failed? 48 | 49 | timestamp = Time.now.to_i 50 | metrics = { 51 | load_avg: { 52 | one: data.load_avg[0].round(2), 53 | five: data.load_avg[1].round(2), 54 | fifteen: data.load_avg[2].round(2) 55 | } 56 | } 57 | 58 | metrics.each do |parent, children| 59 | children.each do |child, value| 60 | output [config[:scheme], parent, child].join('.'), value, timestamp 61 | end 62 | end 63 | ok 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/sensu-plugins-load-checks.rb: -------------------------------------------------------------------------------- 1 | require 'sensu-plugins-load-checks/version' 2 | -------------------------------------------------------------------------------- /lib/sensu-plugins-load-checks/load-average.rb: -------------------------------------------------------------------------------- 1 | class LoadAverage 2 | def initialize 3 | @cores = cpu_count 4 | @avg = load_avg 5 | end 6 | 7 | def load_avg 8 | if File.exist?('/proc/loadavg') 9 | # linux 10 | File.read('/proc/loadavg').split.take(3).map { |a| (a.to_f / @cores).round(2) } rescue nil # rubocop:disable RescueModifier 11 | else 12 | # fallback for FreeBSD 13 | `uptime`.split(' ')[-3..-1].map(&:to_f).map { |a| (a.to_f / @cores).round(2) } rescue nil # rubocop:disable RescueModifier 14 | end 15 | end 16 | 17 | def cpu_count 18 | if File.exist?('/proc/cpuinfo') 19 | File.read('/proc/cpuinfo').scan(/^processor/).count 20 | else 21 | `sysctl -n hw.ncpu`.to_i 22 | end 23 | rescue StandardError 24 | 0 25 | end 26 | 27 | def failed? 28 | @avg.nil? || @cores.zero? 29 | end 30 | 31 | def exceed?(thresholds) 32 | @avg.zip(thresholds).any? { |a, t| a >= t } 33 | end 34 | 35 | def to_s 36 | @avg.join(', ') 37 | end 38 | 39 | def total 40 | @avg.map { |a| (a / @cores) }.join(', ') 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/sensu-plugins-load-checks/version.rb: -------------------------------------------------------------------------------- 1 | module SensuPluginsLoadChecks 2 | module Version 3 | MAJOR = 5 4 | MINOR = 1 5 | PATCH = 0 6 | 7 | VER_STRING = [MAJOR, MINOR, PATCH].compact.join('.') 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /sensu-plugins-load-checks.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('../lib', __FILE__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | 4 | require 'date' 5 | require_relative 'lib/sensu-plugins-load-checks' 6 | 7 | Gem::Specification.new do |s| # rubocop:disable Metrics/BlockLength 8 | s.authors = ['Sensu-Plugins and contributors'] 9 | s.date = Date.today.to_s 10 | s.description = 'This plugin provides native load instrumentation 11 | for monitoring and metrics collection, including: 12 | load health, and total or per core metrics' 13 | s.email = '' 14 | s.executables = Dir.glob('bin/**/*.rb').map { |file| File.basename(file) } 15 | s.files = Dir.glob('{bin,lib}/**/*') + %w[LICENSE README.md CHANGELOG.md] 16 | s.homepage = 'https://github.com/sensu-plugins/sensu-plugins-load-checks' 17 | s.license = 'MIT' 18 | s.metadata = { 'maintainer' => '@mattyjones', 19 | 'development_status' => 'active', 20 | 'production_status' => 'unstable - testing reccomended', 21 | 'release_draft' => 'false', 22 | 'release_prerelease' => 'false' } 23 | 24 | s.name = 'sensu-plugins-load-checks' 25 | s.platform = Gem::Platform::RUBY 26 | s.post_install_message = 'You can use the embedded Ruby by setting EMBEDDED_RUBY=true in /etc/default/sensu' 27 | s.require_paths = ['lib'] 28 | s.required_ruby_version = '>= 2.3' 29 | # s.signing_key = File.expand_path(pvt_key) if $PROGRAM_NAME =~ /gem\z/ 30 | s.summary = 'Sensu plugins for load checks' 31 | s.test_files = s.files.grep(%r{^(test|spec|features)/}) 32 | s.version = SensuPluginsLoadChecks::Version::VER_STRING 33 | 34 | s.add_runtime_dependency 'sensu-plugin', '~> 4.0' 35 | 36 | s.add_development_dependency 'bundler', '~> 1.7' 37 | s.add_development_dependency 'codeclimate-test-reporter', '~> 1.0' 38 | s.add_development_dependency 'github-markup', '~> 1.3' 39 | s.add_development_dependency 'kitchen-docker', '~> 2.6' 40 | s.add_development_dependency 'kitchen-localhost', '~> 0.3' 41 | # locked to keep ruby 2.1 support, this is pulled in by test-kitchen 42 | s.add_development_dependency 'mixlib-shellout', ['< 2.3.0', '~> 2.2'] 43 | s.add_development_dependency 'pry', '~> 0.10' 44 | s.add_development_dependency 'rake', '~> 13.0' 45 | s.add_development_dependency 'redcarpet', '~> 3.2' 46 | s.add_development_dependency 'rspec', '~> 3.4' 47 | s.add_development_dependency 'rubocop', '~> 0.51.0' 48 | s.add_development_dependency 'serverspec', '~> 2.41.5' 49 | s.add_development_dependency 'test-kitchen', '~> 1.6' 50 | s.add_development_dependency 'yard', '~> 0.9.11' 51 | end 52 | -------------------------------------------------------------------------------- /test/fixtures/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Install load checks plugin for testing 4 | # 5 | 6 | set -e 7 | 8 | source /etc/profile 9 | DATA_DIR=/tmp/kitchen/data 10 | RUBY_HOME=${MY_RUBY_HOME} 11 | 12 | # Set the locale 13 | apt-get install -y locales build-essential 14 | locale-gen en_US.UTF-8 15 | export LANG="en_US.UTF-8" 16 | export LANGUAGE="en_US:en" 17 | export LC_ALL="en_US.UTF-8" 18 | 19 | cd $DATA_DIR 20 | SIGN_GEM=false gem build sensu-plugins-load-checks.gemspec 21 | gem install sensu-plugins-load-checks-*.gem 22 | 23 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/check-load_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'shared_spec' 5 | 6 | gem_path = '/usr/local/bin' 7 | check_name = 'check-load.rb' 8 | check = "#{gem_path}/#{check_name}" 9 | 10 | describe 'ruby environment' do 11 | it_behaves_like 'ruby checks', check 12 | end 13 | 14 | describe command(check.to_s) do 15 | its(:exit_status) { should eq 0 } 16 | its(:stdout) { should match(/CheckLoad OK: Per core load average \([\d+] CPU\)\: \[[\d]+.[\d]+, [\d]+.[\d]+, [\d]+.[\d]+\]/) } 17 | end 18 | 19 | describe command("#{check} -w 0") do 20 | its(:exit_status) { should eq 1 } 21 | its(:stdout) { should match(/CheckLoad WARNING: Per core load average \([\d+] CPU\)\: \[[\d]+.[\d]+, [\d]+.[\d]+, [\d]+.[\d]+\]/) } 22 | end 23 | 24 | describe command("#{check} -c 0") do 25 | its(:exit_status) { should eq 2 } 26 | its(:stdout) { should match(/CheckLoad CRITICAL: Per core load average \([\d+] CPU\)\: \[[\d]+.[\d]+, [\d]+.[\d]+, [\d]+.[\d]+\]/) } 27 | end 28 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/metrics-load_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'shared_spec' 5 | 6 | gem_path = '/usr/local/bin' 7 | check_name = 'metrics-load.rb' 8 | check = "#{gem_path}/#{check_name}" 9 | 10 | describe 'ruby environment' do 11 | it_behaves_like 'ruby checks', check 12 | end 13 | 14 | describe command(check.to_s) do 15 | its(:exit_status) { should eq 0 } 16 | its(:stdout) { should match(/[\w]+.load_avg.one [\d+].[\d]+ [\d]+\n[\w]+.load_avg.five [\d+].[\d]+ [\d]+\n[\w]+.load_avg.fifteen [\d+].[\d]+ [\d]+\n/) } 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/shared_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | shared_examples_for 'ruby checks' do |check| 6 | describe command('which ruby') do 7 | its(:exit_status) { should eq 0 } 8 | its(:stdout) { should match(/\/usr\/local\/bin\/ruby/) } 9 | end 10 | 11 | describe command('which gem') do 12 | its(:exit_status) { should eq 0 } 13 | its(:stdout) { should match(/\/usr\/local\/bin\/gem/) } 14 | end 15 | 16 | describe command("which #{check}") do 17 | its(:exit_status) { should eq 0 } 18 | its(:stdout) { should match(Regexp.new(Regexp.escape(check))) } 19 | end 20 | 21 | describe file(check) do 22 | it { should be_file } 23 | it { should be_executable } 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'serverspec' 4 | 5 | set :backend, :exec 6 | -------------------------------------------------------------------------------- /test/integration/ruby-21/serverspec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | -------------------------------------------------------------------------------- /test/integration/ruby-22/serverspec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | -------------------------------------------------------------------------------- /test/integration/ruby-230/serverspec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | -------------------------------------------------------------------------------- /test/integration/ruby-241/serverspec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | -------------------------------------------------------------------------------- /test/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'codeclimate-test-reporter' 2 | CodeClimate::TestReporter.start 3 | --------------------------------------------------------------------------------