sensu-plugins-disk-checks 0.0.1.alpha.2 → 0.0.1.alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +15 -2
- data/README.md +72 -4
- data/bin/check-disk-usage.rb +140 -0
- data/bin/check-fs-writable.rb +1 -1
- data/bin/check-smart-status.rb +262 -0
- data/bin/check-smart.rb +150 -0
- data/lib/sensu-plugins-disk-checks.rb +1 -1
- data.tar.gz.sig +2 -2
- metadata +50 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 380b6afbc2f12bfbb4fff5f145ffe75558a5e6cd
|
4
|
+
data.tar.gz: 1f0851cdf0c4a7f50b9dd38dbf06d02b297270aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a7ff14143b439f68f72510e0199a544fdc0228cae7a691f412001fd5cfc0e0497cd07be6c8aa872e45c7fa3c2cd6e516c596f1aed91f6bd56de694cdcfb4b0f
|
7
|
+
data.tar.gz: c7487d14b20e17a4bc7e07bfb5fd5433f69c923a720f3c27a6831e70c6740404ae13f0587f8e20ddd60581f96e3acbb3b6d4fd75a9c0957d6fada2a2b5134a7f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#### 0.1.
|
1
|
+
#### 0.0.1.alpha.1
|
2
2
|
|
3
3
|
* baseline release identical to **sensu-community-plugins** repo
|
4
4
|
* basic yard coverage
|
@@ -6,10 +6,23 @@
|
|
6
6
|
* built against 1.9.3, 2.0, 2.1
|
7
7
|
* cryptographically signed
|
8
8
|
|
9
|
-
#### 0.0.1
|
9
|
+
#### 0.0.1.alpha.2
|
10
10
|
|
11
11
|
* bump Vagrant box to Cent 6.6
|
12
12
|
* update LICENSE and gemspec authors
|
13
13
|
* update README
|
14
14
|
* add required Ruby version *>= 1.9.3*
|
15
15
|
* add test/spec_help.rb
|
16
|
+
|
17
|
+
#### 0.0.1.alpha.3
|
18
|
+
|
19
|
+
* add check-smart-status
|
20
|
+
* add check-smart
|
21
|
+
* add pry gem as a development dependency
|
22
|
+
|
23
|
+
#### 0.0.1.alpha.4
|
24
|
+
|
25
|
+
* refactored check-disk to use sys-filesystem gem instead of df, it is not 100% backwards compatible dur to the new use of objects vs, plain text
|
26
|
+
* depreciated check-disk in favor of check-disk-usage, it will be removed in the first stable release
|
27
|
+
* add pry as a development dependency
|
28
|
+
* updated README with more detailed installation instructions
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
[](http://badge.fury.io/rb/sensu-plugins-disk-checks)
|
5
5
|
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks)
|
6
6
|
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks)
|
7
|
+
[](https://gemnasium.com/sensu-plugins/sensu-plugins-disk-checks)
|
8
|
+
[](http://inch-ci.org/github/sensu-plugins/sensu-plugins-disk-checks)
|
7
9
|
|
8
10
|
## Functionality
|
9
11
|
|
@@ -15,6 +17,10 @@ Check the output of dmesg for a given set of strings that may correspond to a fa
|
|
15
17
|
|
16
18
|
Check disk capacity and inodes based upon the output of df.
|
17
19
|
|
20
|
+
**check-disk-usage**
|
21
|
+
|
22
|
+
Check disk capacity and inodes based upon the gem sys-filesystem.
|
23
|
+
|
18
24
|
**check-fs-writeable**
|
19
25
|
|
20
26
|
Check to make sure a filesytem is writable. This will check both proc and do a smoke test of each given mountpoint. It can also auto-discover mount points in the self namespace.
|
@@ -35,15 +41,55 @@ Read */proc/iostats* for disk metrics and put them in a form usable by Graphite.
|
|
35
41
|
|
36
42
|
Based on disk-capacity-metrics.rb by bhenerey and nstielau. The difference here being how the key is defined in graphite and the size we emit to graphite(now using megabytes), inode info has also been dropped.
|
37
43
|
|
44
|
+
**check-smart-status**
|
45
|
+
|
46
|
+
Check the SMART status of hardrives and alert based upon a given set of thresholds
|
47
|
+
|
48
|
+
**check-smart**
|
49
|
+
|
50
|
+
Check the health of a disk using `smartctl`
|
38
51
|
|
39
52
|
## Files
|
40
53
|
* bin/check-disk-fail.rb
|
41
|
-
* bin/check-
|
42
|
-
* bin/check-
|
54
|
+
* bin/check-disk.rb
|
55
|
+
* bin/check-disk-usage.rb
|
56
|
+
* bin/check-fs-writable.rb
|
57
|
+
* bin/check-fstab-mounts.rb
|
58
|
+
* bin/check-smart-status.rb
|
59
|
+
* bin/check-smart.rb
|
60
|
+
* bin/disk-metrics.rb
|
61
|
+
* bin/disk-capacity-metrics.rb
|
62
|
+
* bin/disk-usage-metrics.rb
|
63
|
+
|
64
|
+
## Usage
|
65
|
+
|
66
|
+
This is a sample input file used by check-smart-status, see the script for further details.
|
67
|
+
```json
|
68
|
+
{
|
69
|
+
"smart": {
|
70
|
+
"attributes": [
|
71
|
+
{ "id": 1, "name": "Raw_read_Error_Rate", "read": "left16bit" },
|
72
|
+
{ "id": 5, "name": "Reallocated_Sector_Ct" },
|
73
|
+
{ "id": 9, "name": "Power_On_Hours", "read": "right16bit", "warn_max": 10000, "crit_max": 15000 },
|
74
|
+
{ "id": 10 , "name": "Spin_Retry_Count" },
|
75
|
+
{ "id": 184, "name": "End-to-End_Error" },
|
76
|
+
{ "id": 187, "name": "Reported_Uncorrect" },
|
77
|
+
{ "id": 188, "name": "Command_Timeout" },
|
78
|
+
{ "id": 193, "name": "Load_Cycle_Count", "warn_max": 300000, "crit_max": 600000 },
|
79
|
+
{ "id": 194, "name": "Temperature_Celsius", "read": "right16bit", "crit_min": 20, "warn_min": 10, "warn_max": 40, "crit_max": 50 },
|
80
|
+
{ "id": 196, "name": "Reallocated_Event_Count" },
|
81
|
+
{ "id": 197, "name": "Current_Pending_Sector" },
|
82
|
+
{ "id": 198, "name": "Offline_Uncorrectable" },
|
83
|
+
{ "id": 199, "name": "UDMA_CRC_Error_Count" },
|
84
|
+
{ "id": 201, "name": "Unc_Soft_read_Err_Rate", "read": "left16bit" },
|
85
|
+
{ "id": 230, "name": "Life_Curve_Status", "crit_min": 100, "warn_min": 100, "warn_max": 100, "crit_max": 100 }
|
86
|
+
]
|
87
|
+
}
|
88
|
+
}
|
89
|
+
```
|
43
90
|
|
44
91
|
## Installation
|
45
92
|
|
46
|
-
|
47
93
|
Add the public key (if you haven’t already) as a trusted certificate
|
48
94
|
|
49
95
|
```
|
@@ -53,8 +99,30 @@ gem install <gem> -P MediumSecurity
|
|
53
99
|
|
54
100
|
You can also download the key from /certs/ within each repository.
|
55
101
|
|
102
|
+
#### Rubygems
|
103
|
+
|
56
104
|
`gem install sensu-plugins-disk-checks`
|
57
105
|
|
58
|
-
|
106
|
+
#### Bundler
|
107
|
+
|
108
|
+
Add *sensu-plugins-disk-checks* to your Gemfile and run `bundle install` or `bundle update`
|
109
|
+
|
110
|
+
#### Chef
|
111
|
+
|
112
|
+
Using the Sensu **sensu_gem** LWRP
|
113
|
+
```
|
114
|
+
sensu_gem 'sensu-plugins-disk-checks' do
|
115
|
+
options('--prerelease')
|
116
|
+
version '0.0.1.alpha.2'
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
Using the Chef **gem_package** resource
|
121
|
+
```
|
122
|
+
gem_package 'sensu-plugins-process-checks' do
|
123
|
+
options('--prerelease')
|
124
|
+
version '0.0.1.alpha.2'
|
125
|
+
end
|
126
|
+
```
|
59
127
|
|
60
128
|
## Notes
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-disk
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# Uses the sys-filesystem gem to get filesystem mount points and metrics
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux, BSD, Solaris, Windows
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
# gem: sys-filesystem
|
17
|
+
#
|
18
|
+
# USAGE:
|
19
|
+
#
|
20
|
+
# NOTES:
|
21
|
+
#
|
22
|
+
# LICENSE:
|
23
|
+
# Copyright 2015 Yieldbot Inc <devops@yieldbot.com>
|
24
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
25
|
+
# for details.
|
26
|
+
#
|
27
|
+
|
28
|
+
require 'sensu-plugin/check/cli'
|
29
|
+
require 'sys/filesystem'
|
30
|
+
include Sys
|
31
|
+
|
32
|
+
#
|
33
|
+
# Check Disk
|
34
|
+
#
|
35
|
+
class CheckDisk < Sensu::Plugin::Check::CLI
|
36
|
+
option :fstype,
|
37
|
+
short: '-t TYPE[,TYPE]',
|
38
|
+
description: 'Only check fs type(s)',
|
39
|
+
proc: proc { |a| a.split(',') }
|
40
|
+
|
41
|
+
option :ignoretype,
|
42
|
+
short: '-x TYPE[,TYPE]',
|
43
|
+
description: 'Ignore fs type(s)',
|
44
|
+
proc: proc { |a| a.split(',') }
|
45
|
+
|
46
|
+
option :ignoremnt,
|
47
|
+
short: '-i MNT[,MNT]',
|
48
|
+
description: 'Ignore mount point(s)',
|
49
|
+
proc: proc { |a| a.split(',') }
|
50
|
+
|
51
|
+
option :bwarn,
|
52
|
+
short: '-w PERCENT',
|
53
|
+
description: 'Warn if PERCENT or more of disk full',
|
54
|
+
proc: proc(&:to_i),
|
55
|
+
default: 85
|
56
|
+
|
57
|
+
option :bcrit,
|
58
|
+
short: '-c PERCENT',
|
59
|
+
description: 'Critical if PERCENT or more of disk full',
|
60
|
+
proc: proc(&:to_i),
|
61
|
+
default: 95
|
62
|
+
|
63
|
+
option :iwarn,
|
64
|
+
short: '-W PERCENT',
|
65
|
+
description: 'Warn if PERCENT or more of inodes used',
|
66
|
+
proc: proc(&:to_i),
|
67
|
+
default: 85
|
68
|
+
|
69
|
+
option :icrit,
|
70
|
+
short: '-K PERCENT',
|
71
|
+
description: 'Critical if PERCENT or more of inodes used',
|
72
|
+
proc: proc(&:to_i),
|
73
|
+
default: 95
|
74
|
+
|
75
|
+
option :debug,
|
76
|
+
short: '-d',
|
77
|
+
long: '--debug',
|
78
|
+
description: 'Output list of included filesystems'
|
79
|
+
|
80
|
+
# Setup variables
|
81
|
+
#
|
82
|
+
def initialize
|
83
|
+
super
|
84
|
+
@crit_fs = []
|
85
|
+
@warn_fs = []
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get mount data
|
89
|
+
#
|
90
|
+
def fs_mounts
|
91
|
+
Filesystem.mounts.each do |line|
|
92
|
+
begin
|
93
|
+
next if config[:fstype] && !config[:fstype].include?(line.mount_type)
|
94
|
+
next if config[:ignoretype] && config[:ignoretype].include?(line.mount_type)
|
95
|
+
next if config[:ignoremnt] && config[:ignoremnt].include?(line.mount_point)
|
96
|
+
puts "Name: #{ line.name } Mount Point: #{ line.mount_point } FS Type: #{ line.mount_type }" if config[:debug]
|
97
|
+
rescue
|
98
|
+
unknown 'An error occured getting the mount info'
|
99
|
+
end
|
100
|
+
@fs_info = Filesystem.stat(line.mount_point)
|
101
|
+
if percent_inodes >= config[:icrit]
|
102
|
+
@crit_fs << "#{line.mount_point} #{percent_inodes}% inode usage"
|
103
|
+
elsif percent_inodes >= config[:iwarn]
|
104
|
+
@warn_fs << "#{line.mount_point} #{percent_inodes}% inode usage"
|
105
|
+
end
|
106
|
+
if percent_bytes >= config[:bcrit]
|
107
|
+
@crit_fs << "#{line.mount_point} #{percent_bytes}% bytes usage"
|
108
|
+
elsif percent_bytes >= config[:bwarn]
|
109
|
+
@warn_fs << "#{line.mount_point} #{percent_bytes}% bytes usage"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Determine the percent inode usage
|
115
|
+
#
|
116
|
+
def percent_inodes
|
117
|
+
(100.0 - (100.0 * @fs_info.inodes_free / @fs_info.inodes)).round(2)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Determine the percent byte usage
|
121
|
+
#
|
122
|
+
def percent_bytes
|
123
|
+
(100.0 - (100.0 * @fs_info.bytes_free / @fs_info.bytes_total)).round(2)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Generate output
|
127
|
+
#
|
128
|
+
def usage_summary
|
129
|
+
(@crit_fs + @warn_fs).join(', ')
|
130
|
+
end
|
131
|
+
|
132
|
+
# Main function
|
133
|
+
#
|
134
|
+
def run
|
135
|
+
fs_mounts
|
136
|
+
critical usage_summary unless @crit_fs.empty?
|
137
|
+
warning usage_summary unless @warn_fs.empty?
|
138
|
+
ok "All disk usage under #{config[:bwarn]}% and inode usage under #{config[:iwarn]}%"
|
139
|
+
end
|
140
|
+
end
|
data/bin/check-fs-writable.rb
CHANGED
@@ -0,0 +1,262 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-smart
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# S.M.A.R.T. - Self-Monitoring, Analysis and Reporting Technology
|
7
|
+
#
|
8
|
+
# Check hdd and ssd SMART attributes defined in smart.json file. Default is
|
9
|
+
# to check all attributes defined in this file if attribute is presented by hdd.
|
10
|
+
# If attribute not presented script will skip it.
|
11
|
+
#
|
12
|
+
# I defined smart.json file based on this two specification
|
13
|
+
# http://en.wikipedia.org/wiki/S.M.A.R.T.#cite_note-kingston1-32
|
14
|
+
# http://media.kingston.com/support/downloads/MKP_306_SMART_attribute.pdf
|
15
|
+
#
|
16
|
+
# I tested on several Seagate, WesternDigital hdd and Cosair force Gt SSD
|
17
|
+
#
|
18
|
+
# It is possible some hdd give strange attribute values and warnings based on it
|
19
|
+
# but in this case simply define attribute list with '-a' parameter
|
20
|
+
# and ignore wrong parameters. Maybe attribute 1 and 201 will be wrong because
|
21
|
+
# format of this attributes specified by hdd vendors.
|
22
|
+
#
|
23
|
+
# You can test the script just make a copy of your smartctl output and change some
|
24
|
+
# value. I put a hdd attribute file into 'test_hdd.txt' and a failed hdd file into
|
25
|
+
# 'test_hdd_failed.txt'.
|
26
|
+
#
|
27
|
+
# OUTPUT:
|
28
|
+
# plain text
|
29
|
+
#
|
30
|
+
# PLATFORMS:
|
31
|
+
# Linux
|
32
|
+
#
|
33
|
+
# DEPENDENCIES:
|
34
|
+
# gem: sensu-plugin
|
35
|
+
# gem: json
|
36
|
+
# smartmontools
|
37
|
+
# smart.json
|
38
|
+
#
|
39
|
+
# USAGE:
|
40
|
+
# You need to add 'sensu' user to suduers or you can't use 'smartctl'
|
41
|
+
# sensu ALL=(ALL) NOPASSWD:ALL
|
42
|
+
#
|
43
|
+
# PARAMETERS:
|
44
|
+
# -b: smartctl binary to use, in case you hide yours (default: /usr/sbin/smartctl)
|
45
|
+
# -d: default threshold for crit_min,warn_min,warn_max,crit_max (default: 0,0,0,0)
|
46
|
+
# -a: SMART attributes to check (default: all)
|
47
|
+
# -t: Custom threshold for SMART attributes. (id,crit_min,warn_min,warn_max,crit_max)
|
48
|
+
# -o: Overall SMART health check (default: on)
|
49
|
+
# -d: Devices to check (default: all)
|
50
|
+
# --debug: turn debug output on (default: off)
|
51
|
+
# --debug_file: process this file instead of smartctl output for testing
|
52
|
+
#
|
53
|
+
# NOTES:
|
54
|
+
#
|
55
|
+
# LICENSE:
|
56
|
+
# Copyright 2013 Peter Kepes <https://github.com/kepes>
|
57
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
58
|
+
# for details.
|
59
|
+
#
|
60
|
+
|
61
|
+
require 'sensu-plugin/check/cli'
|
62
|
+
require 'json'
|
63
|
+
|
64
|
+
#
|
65
|
+
# Smart Check Status
|
66
|
+
#
|
67
|
+
class SmartCheckStatus < Sensu::Plugin::Check::CLI
|
68
|
+
option :binary,
|
69
|
+
short: '-b path/to/smartctl',
|
70
|
+
long: '--binary /usr/sbin/smartctl',
|
71
|
+
description: 'smartctl binary to use, in case you hide yours',
|
72
|
+
required: false,
|
73
|
+
default: 'smartctl'
|
74
|
+
|
75
|
+
option :defaults,
|
76
|
+
short: '-d 0,0,0,0',
|
77
|
+
long: '--defaults 0,0,0,0',
|
78
|
+
description: 'default threshold for crit_min,warn_min,warn_max,crit_max',
|
79
|
+
required: false,
|
80
|
+
default: '0,0,0,0'
|
81
|
+
|
82
|
+
option :attributes,
|
83
|
+
short: '-a 1,5,9,230',
|
84
|
+
long: '--attributes 1,5,9,230',
|
85
|
+
description: 'SMART attributes to check',
|
86
|
+
required: false,
|
87
|
+
default: 'all'
|
88
|
+
|
89
|
+
option :threshold,
|
90
|
+
short: '-t 194,5,10,50,60',
|
91
|
+
long: '--threshold 194,5,10,50,60',
|
92
|
+
description: 'Custom threshold for SMART attributes. (id,crit_min,warn_min,warn_max,crit_max)',
|
93
|
+
required: false
|
94
|
+
|
95
|
+
option :overall,
|
96
|
+
short: '-o off',
|
97
|
+
long: '--overall off',
|
98
|
+
description: 'Overall SMART health check',
|
99
|
+
required: false,
|
100
|
+
default: 'on'
|
101
|
+
|
102
|
+
option :devices,
|
103
|
+
short: '-d sda,sdb,sdc',
|
104
|
+
long: '--device sda,sdb,sdc',
|
105
|
+
description: 'Devices to check',
|
106
|
+
required: false,
|
107
|
+
default: 'all'
|
108
|
+
|
109
|
+
option :debug,
|
110
|
+
long: '--debug on',
|
111
|
+
description: 'Turn debug output on',
|
112
|
+
required: false,
|
113
|
+
default: 'off'
|
114
|
+
|
115
|
+
option :debug_file,
|
116
|
+
long: '--debugfile test_hdd.txt',
|
117
|
+
description: 'Process a debug file for testing',
|
118
|
+
required: false
|
119
|
+
|
120
|
+
# Main function
|
121
|
+
#
|
122
|
+
def run
|
123
|
+
@smart_attributes = JSON.parse(IO.read(File.dirname(__FILE__) + '/smart.json'), symbolize_names: true)[:smart][:attributes]
|
124
|
+
@smart_debug = config[:debug] == 'on'
|
125
|
+
|
126
|
+
# Set default threshold
|
127
|
+
default_threshold = config[:defaults].split(',')
|
128
|
+
fail 'Invalid default threshold parameter count' unless default_threshold.size == 4
|
129
|
+
@smart_attributes.each do |att|
|
130
|
+
att[:crit_min] = default_threshold[0].to_i if att[:crit_min].nil?
|
131
|
+
att[:warn_min] = default_threshold[1].to_i if att[:warn_min].nil?
|
132
|
+
att[:warn_max] = default_threshold[2].to_i if att[:warn_max].nil?
|
133
|
+
att[:crit_max] = default_threshold[3].to_i if att[:crit_max].nil?
|
134
|
+
end
|
135
|
+
|
136
|
+
# Check threshold parameter if present
|
137
|
+
unless config[:threshold].nil?
|
138
|
+
thresholds = config[:threshold].split(',')
|
139
|
+
# Check threshold parameter length
|
140
|
+
fail 'Invalid threshold parameter count' unless thresholds.size % 5 == 0
|
141
|
+
|
142
|
+
(0..(thresholds.size / 5 - 1)).each do |i|
|
143
|
+
att_id = @smart_attributes.index { |att| att[:id] == thresholds[i + 0].to_i }
|
144
|
+
thash = { crit_min: thresholds[i + 1].to_i,
|
145
|
+
warn_min: thresholds[i + 2].to_i,
|
146
|
+
warn_max: thresholds[i + 3].to_i,
|
147
|
+
crit_max: thresholds[i + 4].to_i }
|
148
|
+
@smart_attributes[att_id].merge! thash
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Attributes to check
|
153
|
+
att_check_list = find_attributes
|
154
|
+
|
155
|
+
# Devices to check
|
156
|
+
devices = config[:debug_file].nil? ? find_devices : ['sda']
|
157
|
+
|
158
|
+
# Overall health and attributes parameter
|
159
|
+
parameters = '-H -A'
|
160
|
+
|
161
|
+
# Get attributes in raw48 format
|
162
|
+
att_check_list.each do |att|
|
163
|
+
parameters += " -v #{att},raw48"
|
164
|
+
end
|
165
|
+
|
166
|
+
output = {}
|
167
|
+
warnings = []
|
168
|
+
criticals = []
|
169
|
+
devices.each do |dev|
|
170
|
+
puts "#{config[:binary]} #{parameters} /dev/#{dev}" if @smart_debug
|
171
|
+
# check if debug file specified
|
172
|
+
if config[:debug_file].nil?
|
173
|
+
output[dev] = `sudo #{config[:binary]} #{parameters} /dev/#{dev}`
|
174
|
+
else
|
175
|
+
test_file = File.open(config[:debug_file], 'rb')
|
176
|
+
output[dev] = test_file.read
|
177
|
+
test_file.close
|
178
|
+
end
|
179
|
+
|
180
|
+
# check overall helath status
|
181
|
+
if config[:overall] == 'on' && !output[dev].include?('SMART overall-health self-assessment test result: PASSED')
|
182
|
+
criticals << "Overall health check failed on #{dev}"
|
183
|
+
end
|
184
|
+
|
185
|
+
# #YELLOW
|
186
|
+
output[dev].split("\n").each do |line| # rubocop:disable Style/Next
|
187
|
+
fields = line.split
|
188
|
+
if fields.size == 10 && fields[0].to_i != 0 && att_check_list.include?(fields[0].to_i)
|
189
|
+
smart_att = @smart_attributes.find { |att| att[:id] == fields[0].to_i }
|
190
|
+
att_value = fields[9].to_i
|
191
|
+
att_value = send(smart_att[:read], att_value) unless smart_att[:read].nil?
|
192
|
+
if att_value < smart_att[:crit_min] || att_value > smart_att[:crit_max]
|
193
|
+
criticals << "#{dev} critical #{fields[0]} #{smart_att[:name]}: #{att_value}"
|
194
|
+
puts "#{fields[0]} #{smart_att[:name]}: #{att_value} (critical)" if @smart_debug
|
195
|
+
elsif att_value < smart_att[:warn_min] || att_value > smart_att[:warn_max]
|
196
|
+
warnings << "#{dev} warning #{fields[0]} #{smart_att[:name]}: #{att_value}"
|
197
|
+
puts "#{fields[0]} #{smart_att[:name]}: #{att_value} (warning)" if @smart_debug
|
198
|
+
else
|
199
|
+
puts "#{fields[0]} #{smart_att[:name]}: #{att_value} (ok)" if @smart_debug
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
puts "\n\n" if @smart_debug
|
204
|
+
end
|
205
|
+
|
206
|
+
# check the result
|
207
|
+
if criticals.size != 0
|
208
|
+
critical criticals.concat(warnings).join("\n")
|
209
|
+
elsif warnings.size != 0
|
210
|
+
warning warnings.join("\n")
|
211
|
+
else
|
212
|
+
ok 'All device operating properly'
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Get right 16 bit from raw48
|
217
|
+
#
|
218
|
+
def right16bit(value)
|
219
|
+
value & 0xffff
|
220
|
+
end
|
221
|
+
|
222
|
+
# Get left 16 bit from raw48
|
223
|
+
#
|
224
|
+
def left16bit(value)
|
225
|
+
value >> 32
|
226
|
+
end
|
227
|
+
|
228
|
+
# find all devices from /proc/partitions or from parameter
|
229
|
+
#
|
230
|
+
def find_devices
|
231
|
+
# Return parameter value if it's defined
|
232
|
+
return config[:devices].split(',') unless config[:devices] == 'all'
|
233
|
+
|
234
|
+
# List all device and split it by new line
|
235
|
+
all = `cat /proc/partitions`.split("\n")
|
236
|
+
|
237
|
+
# Delete first two row (header and empty line)
|
238
|
+
(1..2).each { all.delete_at(0) }
|
239
|
+
|
240
|
+
# Search for devices without number
|
241
|
+
devices = []
|
242
|
+
all.each do |line|
|
243
|
+
partition = line.scan(/\w+/).last.scan(/^\D+$/).first
|
244
|
+
devices << partition unless partition.nil?
|
245
|
+
end
|
246
|
+
|
247
|
+
devices
|
248
|
+
end
|
249
|
+
|
250
|
+
# find all attribute id from parameter or json file
|
251
|
+
#
|
252
|
+
def find_attributes
|
253
|
+
return config[:attributes].split(',') unless config[:attributes] == 'all'
|
254
|
+
|
255
|
+
attributes = []
|
256
|
+
@smart_attributes.each do |att|
|
257
|
+
attributes << att[:id]
|
258
|
+
end
|
259
|
+
|
260
|
+
attributes
|
261
|
+
end
|
262
|
+
end
|
data/bin/check-smart.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# check-smart
|
5
|
+
#
|
6
|
+
# DESCRIPTION:
|
7
|
+
#
|
8
|
+
# OUTPUT:
|
9
|
+
# plain text
|
10
|
+
#
|
11
|
+
# PLATFORMS:
|
12
|
+
# Linux
|
13
|
+
#
|
14
|
+
# DEPENDENCIES:
|
15
|
+
# gem: sensu-plugin
|
16
|
+
#
|
17
|
+
# USAGE:
|
18
|
+
#
|
19
|
+
# NOTES:
|
20
|
+
# This is a drop-in replacement for check-disk-health.sh.
|
21
|
+
#
|
22
|
+
# smartctl requires root permissions. When running this script as a non-root
|
23
|
+
# user such as sensu, ensure it is run with sudo.
|
24
|
+
#
|
25
|
+
# Create a file named /etc/sudoers.d/smartctl with this line inside :
|
26
|
+
# sensu ALL=(ALL) NOPASSWD: /usr/sbin/smartctl
|
27
|
+
#
|
28
|
+
# Fedora has some additional restrictions : if requiretty is set, sudo will only
|
29
|
+
# run when the user is logged in to a real tty.
|
30
|
+
# Then add this in the sudoers file (/etc/sudoers), below the line Defaults requiretty :
|
31
|
+
# Defaults sensu !requiretty
|
32
|
+
#
|
33
|
+
# LICENSE:
|
34
|
+
# Copyright 2013 Mitsutoshi Aoe <maoe@foldr.in>
|
35
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
36
|
+
# for details.
|
37
|
+
#
|
38
|
+
|
39
|
+
require 'sensu-plugin/check/cli'
|
40
|
+
|
41
|
+
#
|
42
|
+
# Disk
|
43
|
+
#
|
44
|
+
class Disk
|
45
|
+
# Setup variables
|
46
|
+
#
|
47
|
+
def initialize(name)
|
48
|
+
@device_path = "/dev/#{name}"
|
49
|
+
@smart_available = false
|
50
|
+
@smart_enabled = false
|
51
|
+
@smart_healty = nil
|
52
|
+
check_smart_capability!
|
53
|
+
check_health! if smart_capable?
|
54
|
+
end
|
55
|
+
attr_reader :capability_output, :health_output, :smart_healthy
|
56
|
+
alias_method :healthy?, :smart_healthy
|
57
|
+
|
58
|
+
# Is the device SMART capable and enabled
|
59
|
+
#
|
60
|
+
def smart_capable?
|
61
|
+
@smart_available && @smart_enabled
|
62
|
+
end
|
63
|
+
|
64
|
+
# Check for SMART cspability
|
65
|
+
#
|
66
|
+
def check_smart_capability!
|
67
|
+
output = `sudo smartctl -i #{@device_path}`
|
68
|
+
@smart_available = !output.scan(/SMART support is: Available/).empty?
|
69
|
+
@smart_enabled = !output.scan(/SMART support is: Enabled/).empty?
|
70
|
+
@capability_output = output
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check the SMART health
|
74
|
+
#
|
75
|
+
def check_health!
|
76
|
+
output = `sudo smartctl -H #{@device_path}`
|
77
|
+
@smart_healthy = !output.scan(/PASSED/).empty?
|
78
|
+
@health_output = output
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Check SMART
|
84
|
+
#
|
85
|
+
class CheckSMART < Sensu::Plugin::Check::CLI
|
86
|
+
option :smart_incapable_disks,
|
87
|
+
long: '--smart-incapable-disks EXIT_CODE',
|
88
|
+
description: 'Exit code when SMART is unavailable/disabled on a disk (ok, warn, critical, unknown)',
|
89
|
+
proc: proc(&:to_sym),
|
90
|
+
default: :unknown
|
91
|
+
|
92
|
+
# Setup variables
|
93
|
+
#
|
94
|
+
def initialize
|
95
|
+
super
|
96
|
+
@devices = []
|
97
|
+
scan_disks!
|
98
|
+
end
|
99
|
+
|
100
|
+
# Generate a list of all block devices
|
101
|
+
#
|
102
|
+
def scan_disks!
|
103
|
+
`lsblk -nro NAME,TYPE`.each_line do |line|
|
104
|
+
name, type = line.split
|
105
|
+
@devices << Disk.new(name) if type == 'disk'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Main function
|
110
|
+
#
|
111
|
+
def run
|
112
|
+
# #YELLOW
|
113
|
+
unless @devices.length > 0 # rubocop:disable IfUnlessModifier
|
114
|
+
unknown 'No SMART capable devices found'
|
115
|
+
end
|
116
|
+
|
117
|
+
unhealthy_disks = @devices.select { |disk| disk.smart_capable? && !disk.healthy? }
|
118
|
+
unknown_disks = @devices.reject(&:smart_capable?)
|
119
|
+
|
120
|
+
if unhealthy_disks.length > 0
|
121
|
+
output = unhealthy_disks.map(&:health_output)
|
122
|
+
output.concat(unknown_disks.map(&:capability_output))
|
123
|
+
critical output.join("\n")
|
124
|
+
end
|
125
|
+
|
126
|
+
if unknown_disks.length > 0
|
127
|
+
exit_with(
|
128
|
+
config[:smart_incapable_disks],
|
129
|
+
unknown_disks.map(&:capability_output).join("\n")
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
ok 'PASSED'
|
134
|
+
end
|
135
|
+
|
136
|
+
# Set exit status and message
|
137
|
+
#
|
138
|
+
def exit_with(sym, message)
|
139
|
+
case sym
|
140
|
+
when :ok
|
141
|
+
ok message
|
142
|
+
when :warn
|
143
|
+
warn message
|
144
|
+
when :critical
|
145
|
+
critical message
|
146
|
+
else
|
147
|
+
unknown message
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
�����~�C���[-�:DK/�;4}���>�K�=q��vg ܂���m������ȐS^�Xh�vȀ�K���dMDOyᙓu�KR>d`[�|0�>Ұ��L�ljH��X8�yT�
|
2
|
+
o|>I+ϸ�Q����0�Y��;�Vj��ҝ�ݝ��x�C��3�J�$}����D��W*�[J,z��i�hX\1�J�s/aG\�*����>�9��h�Ș::Hm�)L�H��?[:��g���-p�5�� Ka��_0eZ���\��;YS
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-disk-checks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.alpha.
|
4
|
+
version: 0.0.1.alpha.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yieldbot, Inc. and contributors
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
8sHuVruarogxxKPBzlL2is4EUb6oN/RdpGx2l4254+nyR+abg//Ed27Ym0PkB4lk
|
31
31
|
HP0m8WSjZmFr109pE/sVsM5jtOCvogyujQOjNVGN4gz1wwPr
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2015-02-
|
33
|
+
date: 2015-02-04 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: sensu-plugin
|
@@ -46,6 +46,34 @@ dependencies:
|
|
46
46
|
- - '='
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 1.1.0
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sys-filesystem
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: filesystem
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
49
77
|
- !ruby/object:Gem::Dependency
|
50
78
|
name: codeclimate-test-reporter
|
51
79
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,13 +186,30 @@ dependencies:
|
|
158
186
|
- - '>='
|
159
187
|
- !ruby/object:Gem::Version
|
160
188
|
version: '0'
|
189
|
+
- !ruby/object:Gem::Dependency
|
190
|
+
name: pry
|
191
|
+
requirement: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - '>='
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
type: :development
|
197
|
+
prerelease: false
|
198
|
+
version_requirements: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - '>='
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
161
203
|
description: Sensu disk checks
|
162
204
|
email: <sensu-users@googlegroups.com>
|
163
205
|
executables:
|
164
206
|
- check-disk-fail.rb
|
207
|
+
- check-disk-usage.rb
|
165
208
|
- check-disk.rb
|
166
209
|
- check-fs-writable.rb
|
167
210
|
- check-fstab-mounts.rb
|
211
|
+
- check-smart-status.rb
|
212
|
+
- check-smart.rb
|
168
213
|
- disk-capacity-metrics.rb
|
169
214
|
- disk-metrics.rb
|
170
215
|
- disk-usage-metrics.rb
|
@@ -172,9 +217,12 @@ extensions: []
|
|
172
217
|
extra_rdoc_files: []
|
173
218
|
files:
|
174
219
|
- bin/check-disk-fail.rb
|
220
|
+
- bin/check-disk-usage.rb
|
175
221
|
- bin/check-disk.rb
|
176
222
|
- bin/check-fs-writable.rb
|
177
223
|
- bin/check-fstab-mounts.rb
|
224
|
+
- bin/check-smart-status.rb
|
225
|
+
- bin/check-smart.rb
|
178
226
|
- bin/disk-capacity-metrics.rb
|
179
227
|
- bin/disk-metrics.rb
|
180
228
|
- bin/disk-usage-metrics.rb
|
metadata.gz.sig
CHANGED
Binary file
|