sensu-plugins-disk-checks 0.0.1.alpha.2 → 0.0.1.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/sensu-plugins-disk-checks.svg)](http://badge.fury.io/rb/sensu-plugins-disk-checks)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks/badges/gpa.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks)
|
6
6
|
[![Test Coverage](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks/badges/coverage.svg)](https://codeclimate.com/github/sensu-plugins/sensu-plugins-disk-checks)
|
7
|
+
[![Dependency Status](https://gemnasium.com/sensu-plugins/sensu-plugins-disk-checks.svg)](https://gemnasium.com/sensu-plugins/sensu-plugins-disk-checks)
|
8
|
+
[![Inline docs](http://inch-ci.org/github/sensu-plugins/sensu-plugins-disk-checks.svg?branch=master&style=shields)](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
|