sensu-plugins-graphite 0.0.5 → 0.0.6
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.tar.gz.sig +0 -0
- data/CHANGELOG.md +7 -2
- data/bin/check-graphite-data.rb +19 -96
- data/bin/check-graphite-hosts.rb +98 -0
- data/bin/check-graphite.rb +9 -15
- data/lib/sensu-plugins-graphite/graphite_proxy/options.rb +113 -0
- data/lib/sensu-plugins-graphite/graphite_proxy/proxy.rb +113 -0
- data/lib/sensu-plugins-graphite/version.rb +1 -1
- metadata +6 -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: 95919766647d9a11674c461481f6bf721f6dd5c7
|
4
|
+
data.tar.gz: 73c6e2979abaa4ff35f69b510000e96410921e6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efcbdf877c3405cd8a7b98756581945f6d547b3c41942d61c1ea78dfe7deed82de5eb6dd1ade93d1745b371d981c69cba262ea4cf194a464870a74ebf769b227
|
7
|
+
data.tar.gz: a75f1d56bb46334dcd4a32147f1644311b0ea78c43b832ac015eb86d76259c08b2a2587eac3f38a038c4959544f214a8eec27a2c0b4522247339c5ef112e0c65
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
|
5
5
|
|
6
6
|
## [Unreleased]
|
7
|
-
|
7
|
+
|
8
|
+
## [0.0.6] - 2015-08-27
|
9
|
+
### Added
|
10
|
+
- check on number of hosts
|
11
|
+
- -auth param allows authentication by bearer token
|
8
12
|
|
9
13
|
## [0.0.5] - 2015-08-05
|
10
14
|
### Changed
|
@@ -28,7 +32,8 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
28
32
|
### Added
|
29
33
|
- initial release
|
30
34
|
|
31
|
-
[unreleased]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.
|
35
|
+
[unreleased]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.6...HEAD
|
36
|
+
[0.0.6]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.5...0.0.6
|
32
37
|
[0.0.5]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.4...0.0.5
|
33
38
|
[0.0.4]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.3...0.0.4
|
34
39
|
[0.0.3]: https://github.com/sensu-plugins/sensu-plugins-graphite/compare/0.0.2...0.0.3
|
data/bin/check-graphite-data.rb
CHANGED
@@ -31,48 +31,11 @@ require 'json'
|
|
31
31
|
require 'open-uri'
|
32
32
|
require 'openssl'
|
33
33
|
|
34
|
+
require 'sensu-plugins-graphite/graphite_proxy/options'
|
35
|
+
require 'sensu-plugins-graphite/graphite_proxy/proxy'
|
36
|
+
|
34
37
|
class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
35
|
-
|
36
|
-
description: 'Graphite data target',
|
37
|
-
short: '-t TARGET',
|
38
|
-
long: '--target TARGET',
|
39
|
-
required: true
|
40
|
-
|
41
|
-
option :server,
|
42
|
-
description: 'Server host and port',
|
43
|
-
short: '-s SERVER:PORT',
|
44
|
-
long: '--server SERVER:PORT',
|
45
|
-
required: true
|
46
|
-
|
47
|
-
option :username,
|
48
|
-
description: 'username for basic http authentication',
|
49
|
-
short: '-u USERNAME',
|
50
|
-
long: '--user USERNAME',
|
51
|
-
required: false
|
52
|
-
|
53
|
-
option :password,
|
54
|
-
description: 'user password for basic http authentication',
|
55
|
-
short: '-p PASSWORD',
|
56
|
-
long: '--pass PASSWORD',
|
57
|
-
required: false
|
58
|
-
|
59
|
-
option :passfile,
|
60
|
-
description: 'password file path for basic http authentication',
|
61
|
-
short: '-P PASSWORDFILE',
|
62
|
-
long: '--passfile PASSWORDFILE',
|
63
|
-
required: false
|
64
|
-
|
65
|
-
option :warning,
|
66
|
-
description: 'Generate warning if given value is above received value',
|
67
|
-
short: '-w VALUE',
|
68
|
-
long: '--warn VALUE',
|
69
|
-
proc: proc(&:to_f)
|
70
|
-
|
71
|
-
option :critical,
|
72
|
-
description: 'Generate critical if given value is above received value',
|
73
|
-
short: '-c VALUE',
|
74
|
-
long: '--critical VALUE',
|
75
|
-
proc: proc(&:to_f)
|
38
|
+
include SensuPluginsGraphite::GraphiteProxy::Options
|
76
39
|
|
77
40
|
option :reset_on_decrease,
|
78
41
|
description: 'Send OK if value has decreased on any values within END-INTERVAL to END',
|
@@ -80,12 +43,6 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
80
43
|
long: '--reset INTERVAL',
|
81
44
|
proc: proc(&:to_i)
|
82
45
|
|
83
|
-
option :name,
|
84
|
-
description: 'Name used in responses',
|
85
|
-
short: '-n NAME',
|
86
|
-
long: '--name NAME',
|
87
|
-
default: 'graphite check'
|
88
|
-
|
89
46
|
option :allowed_graphite_age,
|
90
47
|
description: 'Allowed number of seconds since last data update (default: 60 seconds)',
|
91
48
|
short: '-a SECONDS',
|
@@ -93,32 +50,6 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
93
50
|
default: 60,
|
94
51
|
proc: proc(&:to_i)
|
95
52
|
|
96
|
-
option :hostname_sub,
|
97
|
-
description: 'Character used to replace periods (.) in hostname (default: _)',
|
98
|
-
short: '-s CHARACTER',
|
99
|
-
long: '--host-sub CHARACTER'
|
100
|
-
|
101
|
-
option :from,
|
102
|
-
description: 'Get samples starting from FROM (default: -10mins)',
|
103
|
-
short: '-f FROM',
|
104
|
-
long: '--from FROM',
|
105
|
-
default: '-10mins'
|
106
|
-
|
107
|
-
option :below,
|
108
|
-
description: 'warnings/critical if values below specified thresholds',
|
109
|
-
short: '-b',
|
110
|
-
long: '--below'
|
111
|
-
|
112
|
-
option :no_ssl_verify,
|
113
|
-
description: 'Do not verify SSL certs',
|
114
|
-
short: '-v',
|
115
|
-
long: '--nosslverify'
|
116
|
-
|
117
|
-
option :help,
|
118
|
-
description: 'Show this message',
|
119
|
-
short: '-h',
|
120
|
-
long: '--help'
|
121
|
-
|
122
53
|
# Run checks
|
123
54
|
def run
|
124
55
|
if config[:help]
|
@@ -126,13 +57,19 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
126
57
|
exit
|
127
58
|
end
|
128
59
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
60
|
+
proxy = SensuPluginsGraphite::GraphiteProxy::Proxy.new(config)
|
61
|
+
begin
|
62
|
+
results = proxy.retrieve_data!
|
63
|
+
results.each_pair do |_key, value|
|
64
|
+
@value = value
|
65
|
+
@data = value['data']
|
66
|
+
check_age || check(:critical) || check(:warning)
|
67
|
+
end
|
68
|
+
|
69
|
+
ok("#{name} value okay")
|
70
|
+
rescue SensuPluginsGraphite::GraphiteProxy::ProxyError => e
|
71
|
+
unknown e.message
|
134
72
|
end
|
135
|
-
ok("#{name} value okay")
|
136
73
|
end
|
137
74
|
|
138
75
|
# name used in responses
|
@@ -143,16 +80,14 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
143
80
|
|
144
81
|
# Check the age of the data being processed
|
145
82
|
def check_age
|
146
|
-
|
147
|
-
if (Time.now.to_i - @value['end']) > config[:allowed_graphite_age] # rubocop:disable GuardClause
|
83
|
+
if (Time.now.to_i - @value['end']) > config[:allowed_graphite_age]
|
148
84
|
unknown "Graphite data age is past allowed threshold (#{config[:allowed_graphite_age]} seconds)"
|
149
85
|
end
|
150
86
|
end
|
151
87
|
|
152
88
|
# grab data from graphite
|
153
89
|
def retrieve_data
|
154
|
-
|
155
|
-
unless @raw_data # rubocop:disable GuardClause
|
90
|
+
unless @raw_data
|
156
91
|
begin
|
157
92
|
unless config[:server].start_with?('https://', 'http://')
|
158
93
|
config[:server].prepend('http://')
|
@@ -215,8 +150,7 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
215
150
|
# type:: :warning or :critical
|
216
151
|
# Return alert if required
|
217
152
|
def check(type)
|
218
|
-
|
219
|
-
if config[type] # rubocop:disable GuardClause
|
153
|
+
if config[type]
|
220
154
|
send(type, "#{@value['target']} has passed #{type} threshold (#{@data.last})") if below?(type) || above?(type)
|
221
155
|
end
|
222
156
|
end
|
@@ -241,15 +175,4 @@ class CheckGraphiteData < Sensu::Plugin::Check::CLI
|
|
241
175
|
false
|
242
176
|
end
|
243
177
|
end
|
244
|
-
|
245
|
-
# Returns formatted target with hostname replacing any $ characters
|
246
|
-
def formatted_target
|
247
|
-
if config[:target].include?('$')
|
248
|
-
require 'socket'
|
249
|
-
@formatted = Socket.gethostbyname(Socket.gethostname).first.gsub('.', config[:hostname_sub] || '_')
|
250
|
-
config[:target].gsub('$', @formatted)
|
251
|
-
else
|
252
|
-
URI.escape config[:target]
|
253
|
-
end
|
254
|
-
end
|
255
178
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-graphite-hosts
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin checks the number of hosts within graphite that are sending
|
7
|
+
# data, and alerts if it is below a given threshold
|
8
|
+
#
|
9
|
+
# OUTPUT:
|
10
|
+
# plain text
|
11
|
+
#
|
12
|
+
# PLATFORMS:
|
13
|
+
# Linux
|
14
|
+
#
|
15
|
+
# DEPENDENCIES:
|
16
|
+
# gem: sensu-plugin
|
17
|
+
# gem: openssl
|
18
|
+
#
|
19
|
+
# USAGE:
|
20
|
+
# #YELLOW
|
21
|
+
#
|
22
|
+
# NOTES:
|
23
|
+
#
|
24
|
+
# LICENSE:
|
25
|
+
# Copyright 2014 Sonian, Inc. and contributors. <support@sensuapp.org>
|
26
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
27
|
+
# for details.
|
28
|
+
#
|
29
|
+
|
30
|
+
require 'sensu-plugin/check/cli'
|
31
|
+
require 'json'
|
32
|
+
require 'open-uri'
|
33
|
+
require 'openssl'
|
34
|
+
|
35
|
+
require 'sensu-plugins-graphite/graphite_proxy/options'
|
36
|
+
require 'sensu-plugins-graphite/graphite_proxy/proxy'
|
37
|
+
|
38
|
+
class CheckGraphiteHosts < Sensu::Plugin::Check::CLI
|
39
|
+
include SensuPluginsGraphite::GraphiteProxy::Options
|
40
|
+
|
41
|
+
# Run checks
|
42
|
+
def run
|
43
|
+
if config[:help]
|
44
|
+
puts opt_parser if config[:help]
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
proxy = SensuPluginsGraphite::GraphiteProxy::Proxy.new(config)
|
49
|
+
begin
|
50
|
+
results = proxy.retrieve_data!
|
51
|
+
|
52
|
+
check(:critical, results) || check(:warning, results)
|
53
|
+
ok("#{name} value (#{hosts_with_data(results)}) okay")
|
54
|
+
rescue SensuPluginsGraphite::GraphiteProxy::ProxyError => e
|
55
|
+
unknown e.message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# name used in responses
|
60
|
+
def name
|
61
|
+
base = config[:name]
|
62
|
+
@formatted ? "#{base} (#{@formatted})" : base
|
63
|
+
end
|
64
|
+
|
65
|
+
# return the number of hosts with data in the given set of results
|
66
|
+
def hosts_with_data(resultset)
|
67
|
+
resultset.count { |_host, values| !values['data'].empty? }
|
68
|
+
end
|
69
|
+
|
70
|
+
# type:: :warning or :critical
|
71
|
+
# Return alert if required
|
72
|
+
def check(type, results)
|
73
|
+
# #YELLOW
|
74
|
+
num_hosts = hosts_with_data(results)
|
75
|
+
return unless config[type] && threshold_crossed?(type, num_hosts)
|
76
|
+
|
77
|
+
msg = hosts_threshold_message(config[:target], num_hosts, type)
|
78
|
+
send(type, msg)
|
79
|
+
end
|
80
|
+
|
81
|
+
def threshold_crossed?(type, num_hosts)
|
82
|
+
below?(type, num_hosts) || above?(type, num_hosts)
|
83
|
+
end
|
84
|
+
|
85
|
+
def hosts_threshold_message(target, hosts, type)
|
86
|
+
"Number of hosts sending #{target} (#{hosts}) has passed #{type} threshold (#{config[type]})"
|
87
|
+
end
|
88
|
+
|
89
|
+
# Check if value is below defined threshold
|
90
|
+
def below?(type, val)
|
91
|
+
config[:below] && val < config[type]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Check is value is above defined threshold
|
95
|
+
def above?(type, val)
|
96
|
+
(!config[:below]) && (val > config[type])
|
97
|
+
end
|
98
|
+
end
|
data/bin/check-graphite.rb
CHANGED
@@ -148,7 +148,7 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
148
148
|
|
149
149
|
def graphite_cache(target = nil)
|
150
150
|
# #YELLOW
|
151
|
-
if @graphite_cache.key?(target)
|
151
|
+
if @graphite_cache.key?(target)
|
152
152
|
graphite_value = @graphite_cache[target].select { |value| value[:period] == @period }
|
153
153
|
graphite_value if graphite_value.size > 0
|
154
154
|
end
|
@@ -199,8 +199,6 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
199
199
|
if data.size > 0
|
200
200
|
data.each { |d| @graphite_cache[target] << { target: d['target'], period: @period, datapoints: d['datapoints'] } }
|
201
201
|
graphite_cache target
|
202
|
-
else # rubocop:disable all
|
203
|
-
nil
|
204
202
|
end
|
205
203
|
end
|
206
204
|
|
@@ -220,8 +218,6 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
220
218
|
def get_max_value(values)
|
221
219
|
if values
|
222
220
|
values.map { |i| i[0] ? i[0] : 0 }[0..-2].max
|
223
|
-
else # rubocop:disable all
|
224
|
-
nil
|
225
221
|
end
|
226
222
|
end
|
227
223
|
|
@@ -249,8 +245,6 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
249
245
|
ret.push(values[values_size]) if values[values_size][0]
|
250
246
|
end
|
251
247
|
ret
|
252
|
-
else # rubocop:disable all
|
253
|
-
nil
|
254
248
|
end
|
255
249
|
end
|
256
250
|
|
@@ -291,7 +285,7 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
291
285
|
last_gv = last_graphite_value target
|
292
286
|
if last_gv.is_a?(Hash) && max_gv.is_a?(Hash)
|
293
287
|
# #YELLOW
|
294
|
-
last_gv.each do |target_name, value|
|
288
|
+
last_gv.each do |target_name, value|
|
295
289
|
if value && max_gv[target_name]
|
296
290
|
last = value
|
297
291
|
max = max_gv[target_name]
|
@@ -326,7 +320,7 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
326
320
|
last_value = last_values[target]
|
327
321
|
percent = last_value / avg_value unless last_value.nil? || avg_value.nil?
|
328
322
|
# #YELLOW
|
329
|
-
%w(fatal error warning).each do |type|
|
323
|
+
%w(fatal error warning).each do |type|
|
330
324
|
next unless max_values.key?(type)
|
331
325
|
max_value = max_values[type]
|
332
326
|
var1 = config[:greater_than] ? percent : max_value.to_f
|
@@ -363,7 +357,7 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
363
357
|
# #YELLOW
|
364
358
|
avg_value = values_array.reduce { |sum, el| sum + el if el }.to_f / values_array.size # rubocop:disable SingleLineBlockParams
|
365
359
|
# YELLOW
|
366
|
-
%w(fatal error warning).each do |type|
|
360
|
+
%w(fatal error warning).each do |type|
|
367
361
|
next unless max_values.key?(type)
|
368
362
|
max_value = max_values[type]
|
369
363
|
var1 = config[:greater_than] ? avg_value : max_value.to_f
|
@@ -402,7 +396,7 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
402
396
|
last_value = last_values[target]
|
403
397
|
percent = last_value / percentile_value unless last_value.nil? || percentile_value.nil?
|
404
398
|
# #YELLOW
|
405
|
-
%w(fatal error warning).each do |type|
|
399
|
+
%w(fatal error warning).each do |type|
|
406
400
|
next unless max_values.key?(type)
|
407
401
|
max_value = max_values[type]
|
408
402
|
var1 = config[:greater_than] ? percent : max_value.to_f
|
@@ -434,11 +428,11 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
434
428
|
criticals = []
|
435
429
|
fatal = []
|
436
430
|
# #YELLOW
|
437
|
-
last_targets.each do |target_name, last|
|
431
|
+
last_targets.each do |target_name, last|
|
438
432
|
last_value = last.first
|
439
433
|
unless last_value.nil?
|
440
434
|
# #YELLOW
|
441
|
-
%w(fatal error warning).each do |type|
|
435
|
+
%w(fatal error warning).each do |type|
|
442
436
|
next unless max_values.key?(type)
|
443
437
|
max_value = max_values[type]
|
444
438
|
var1 = config[:greater_than] ? last_value : max_value.to_f
|
@@ -463,14 +457,14 @@ class Graphite < Sensu::Plugin::Check::CLI
|
|
463
457
|
[warnings, criticals, fatal]
|
464
458
|
end
|
465
459
|
|
466
|
-
def run
|
460
|
+
def run
|
467
461
|
targets = config[:target].split(',')
|
468
462
|
@period = config[:period]
|
469
463
|
critical_errors = []
|
470
464
|
warnings = []
|
471
465
|
fatals = []
|
472
466
|
# #YELLOW
|
473
|
-
targets.each do |target|
|
467
|
+
targets.each do |target|
|
474
468
|
if config[:check_function_increasing]
|
475
469
|
inc_warnings, inc_critical, inc_fatal = check_increasing target
|
476
470
|
warnings += inc_warnings
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module SensuPluginsGraphite
|
2
|
+
module GraphiteProxy
|
3
|
+
module Options
|
4
|
+
def self.included(base)
|
5
|
+
add_default_options(base)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.add_default_options(base)
|
9
|
+
default_options.each do |name, vals|
|
10
|
+
base.send(:option, name, vals)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.default_options
|
15
|
+
{
|
16
|
+
target: {
|
17
|
+
description: 'Graphite data target',
|
18
|
+
short: '-t TARGET',
|
19
|
+
long: '--target TARGET',
|
20
|
+
required: true
|
21
|
+
},
|
22
|
+
|
23
|
+
server: {
|
24
|
+
description: 'Server host and port',
|
25
|
+
short: '-s SERVER:PORT',
|
26
|
+
long: '--server SERVER:PORT',
|
27
|
+
required: true
|
28
|
+
},
|
29
|
+
|
30
|
+
username: {
|
31
|
+
description: 'username for basic http authentication',
|
32
|
+
short: '-u USERNAME',
|
33
|
+
long: '--user USERNAME',
|
34
|
+
required: false
|
35
|
+
},
|
36
|
+
|
37
|
+
password: {
|
38
|
+
description: 'user password for basic http authentication',
|
39
|
+
short: '-p PASSWORD',
|
40
|
+
long: '--pass PASSWORD',
|
41
|
+
required: false
|
42
|
+
},
|
43
|
+
|
44
|
+
passfile: {
|
45
|
+
description: 'password file path for basic http authentication',
|
46
|
+
short: '-P PASSWORDFILE',
|
47
|
+
long: '--passfile PASSWORDFILE',
|
48
|
+
required: false
|
49
|
+
},
|
50
|
+
|
51
|
+
no_ssl_verify: {
|
52
|
+
description: 'Do not verify SSL certs',
|
53
|
+
short: '-v',
|
54
|
+
long: '--nosslverify'
|
55
|
+
},
|
56
|
+
|
57
|
+
help: {
|
58
|
+
description: 'Show this message',
|
59
|
+
short: '-h',
|
60
|
+
long: '--help'
|
61
|
+
},
|
62
|
+
|
63
|
+
auth: {
|
64
|
+
description: 'Add an auth token to the HTTP request, in the form of "Name: Value",
|
65
|
+
e.g. --auth yourapitokenvaluegoeshere',
|
66
|
+
short: '-a TOKEN',
|
67
|
+
long: '--auth TOKEN'
|
68
|
+
},
|
69
|
+
|
70
|
+
name: {
|
71
|
+
description: 'Name used in responses',
|
72
|
+
short: '-n NAME',
|
73
|
+
long: '--name NAME',
|
74
|
+
default: 'graphite check'
|
75
|
+
},
|
76
|
+
|
77
|
+
hostname_sub: {
|
78
|
+
description: 'Character used to replace periods (.) in hostname (default: _)',
|
79
|
+
short: '-s CHARACTER',
|
80
|
+
long: '--host-sub CHARACTER'
|
81
|
+
},
|
82
|
+
|
83
|
+
from: {
|
84
|
+
description: 'Get samples starting from FROM (default: -10mins)',
|
85
|
+
short: '-f FROM',
|
86
|
+
long: '--from FROM',
|
87
|
+
default: '-10mins'
|
88
|
+
},
|
89
|
+
|
90
|
+
warning: {
|
91
|
+
description: 'Generate warning if number of hosts is below received value',
|
92
|
+
short: '-w VALUE',
|
93
|
+
long: '--warn VALUE',
|
94
|
+
proc: proc(&:to_f)
|
95
|
+
},
|
96
|
+
|
97
|
+
critical: {
|
98
|
+
description: 'Generate critical if number of hosts is below received value',
|
99
|
+
short: '-c VALUE',
|
100
|
+
long: '--critical VALUE',
|
101
|
+
proc: proc(&:to_f)
|
102
|
+
},
|
103
|
+
|
104
|
+
below: {
|
105
|
+
description: 'alert if number of hosts below specified thresholds',
|
106
|
+
short: '-b',
|
107
|
+
long: '--below'
|
108
|
+
}
|
109
|
+
}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module SensuPluginsGraphite
|
4
|
+
module GraphiteProxy
|
5
|
+
class ProxyError < StandardError
|
6
|
+
attr_accessor :exception
|
7
|
+
|
8
|
+
def initialize(msg, args)
|
9
|
+
self.exception = args[:exception]
|
10
|
+
super msg
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Proxy
|
15
|
+
attr_accessor :config
|
16
|
+
|
17
|
+
def initialize(config)
|
18
|
+
self.config = config
|
19
|
+
end
|
20
|
+
|
21
|
+
def formatted_target
|
22
|
+
if config[:target].include?('$')
|
23
|
+
require 'socket'
|
24
|
+
formatted = Socket.gethostbyname(Socket.gethostname).first.gsub('.', config[:hostname_sub] || '_')
|
25
|
+
config[:target].gsub('$', formatted)
|
26
|
+
else
|
27
|
+
URI.escape config[:target]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def request_auth_options(given_opts)
|
32
|
+
url_opts = {}
|
33
|
+
|
34
|
+
url_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE if given_opts[:no_ssl_verify]
|
35
|
+
|
36
|
+
if given_opts[:username]
|
37
|
+
pass = derive_password(given_opts)
|
38
|
+
url_opts[:http_basic_authentication] = [given_opts[:username], pass.chomp]
|
39
|
+
end # we don't have both username and password trying without
|
40
|
+
|
41
|
+
url_opts['Authorization'] = "Bearer #{given_opts[:auth]}" if given_opts[:auth]
|
42
|
+
|
43
|
+
url_opts
|
44
|
+
end
|
45
|
+
|
46
|
+
def derive_password(given_opts)
|
47
|
+
if given_opts[:passfile]
|
48
|
+
File.open(given_opts[:passfile]).readline
|
49
|
+
elsif given_opts[:password]
|
50
|
+
given_opts[:password]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def format_output(data)
|
55
|
+
output = {}
|
56
|
+
|
57
|
+
data.each do |raw|
|
58
|
+
unless raw['datapoints'].empty?
|
59
|
+
line = output_line(raw)
|
60
|
+
output[line['target']] = line
|
61
|
+
end
|
62
|
+
end
|
63
|
+
output
|
64
|
+
end
|
65
|
+
|
66
|
+
def output_line(raw)
|
67
|
+
raw['datapoints'].delete_if { |v| v.first.nil? }
|
68
|
+
target = raw['target']
|
69
|
+
data = raw['datapoints'].map(&:first)
|
70
|
+
start = raw['datapoints'].first.last
|
71
|
+
dend = raw['datapoints'].last.last
|
72
|
+
step = ((dend - start) / raw['datapoints'].size.to_f).ceil
|
73
|
+
|
74
|
+
{ 'target' => target, 'data' => data, 'start' => start, 'end' => dend, 'step' => step }
|
75
|
+
end
|
76
|
+
|
77
|
+
# grab data from graphite
|
78
|
+
def retrieve_data!
|
79
|
+
unless @raw_data
|
80
|
+
begin
|
81
|
+
unless config[:server].start_with?('https://', 'http://')
|
82
|
+
config[:server].prepend('http://')
|
83
|
+
end
|
84
|
+
|
85
|
+
url = "#{config[:server]}/render?format=json&target=#{formatted_target}&from=#{config[:from]}"
|
86
|
+
|
87
|
+
handle = open(url, request_auth_options(config))
|
88
|
+
|
89
|
+
@raw_data = handle.gets
|
90
|
+
if @raw_data == '[]'
|
91
|
+
unknown 'Empty data received from Graphite - metric probably doesn\'t exists'
|
92
|
+
else
|
93
|
+
json_data = JSON.parse(@raw_data)
|
94
|
+
format_output(json_data)
|
95
|
+
end
|
96
|
+
rescue OpenURI::HTTPError => e
|
97
|
+
raise ProxyError.new('Failed to connect to graphite server', exception: e)
|
98
|
+
rescue NoMethodError => e
|
99
|
+
raise ProxyError.new('No data for time period and/or target', exception: e)
|
100
|
+
rescue Errno::ECONNREFUSED => e
|
101
|
+
raise ProxyError.new('Connection refused when connecting to graphite server', exception: e)
|
102
|
+
rescue Errno::ECONNRESET => e
|
103
|
+
raise ProxyError.new('Connection reset by peer when connecting to graphite server', exception: e)
|
104
|
+
rescue EOFError => e
|
105
|
+
raise ProxyError.new('End of file error when reading from graphite server', exception: e)
|
106
|
+
rescue => e
|
107
|
+
raise ProxyError.new("An unknown error occured: #{e.inspect}", exception: e)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-graphite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu Plugins 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-08-
|
33
|
+
date: 2015-08-27 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: array_stats
|
@@ -241,6 +241,7 @@ executables:
|
|
241
241
|
- check-graphite.rb
|
242
242
|
- check-graphite-stats.rb
|
243
243
|
- check-graphite-replication.rb
|
244
|
+
- check-graphite-hosts.rb
|
244
245
|
- check-graphite-data.rb
|
245
246
|
extensions: []
|
246
247
|
extra_rdoc_files: []
|
@@ -249,6 +250,7 @@ files:
|
|
249
250
|
- LICENSE
|
250
251
|
- README.md
|
251
252
|
- bin/check-graphite-data.rb
|
253
|
+
- bin/check-graphite-hosts.rb
|
252
254
|
- bin/check-graphite-replication.rb
|
253
255
|
- bin/check-graphite-stats.rb
|
254
256
|
- bin/check-graphite.rb
|
@@ -257,6 +259,8 @@ files:
|
|
257
259
|
- bin/handler-graphite-occurrences.rb
|
258
260
|
- bin/mutator-graphite.rb
|
259
261
|
- lib/sensu-plugins-graphite.rb
|
262
|
+
- lib/sensu-plugins-graphite/graphite_proxy/options.rb
|
263
|
+
- lib/sensu-plugins-graphite/graphite_proxy/proxy.rb
|
260
264
|
- lib/sensu-plugins-graphite/version.rb
|
261
265
|
homepage: https://github.com/sensu-plugins/sensu-plugins-graphite
|
262
266
|
licenses:
|
metadata.gz.sig
CHANGED
Binary file
|