sensu-plugins-sensu 0.0.1
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE +22 -0
- data/README.md +23 -0
- data/bin/check-aggregate.rb +171 -0
- data/bin/handler-sensu.rb +137 -0
- data/bin/metrics-aggregate.rb +125 -0
- data/bin/metrics-delete-expired-stashes.rb +98 -0
- data/lib/sensu-plugins-sensu/version.rb +10 -0
- data/lib/sensu-plugins-sensu.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +266 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f86081dba08f9fa8f133e9c0c4c7097d1ba4d38
|
4
|
+
data.tar.gz: 1b5ce7b0978a1616b2dade615099f3e6246fc364
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1d0536f1912ebaa5f9e387f38667aede3a4cd10ac030e9e9423051c3329ba08f05ff9b38b8773d24eed37d4d480a0548dae185e9b91dba5f97ed73079f61ec2
|
7
|
+
data.tar.gz: d445ec33c7970ded7b6b1380e7cae8e6461426d5e06c0eb851430cf4f71dfbbef15ce5fe242bc5318040ac3f27bff805301f1b8870d7763b91dae61a11bfd361
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#Change Log
|
2
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
3
|
+
|
4
|
+
This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
|
5
|
+
|
6
|
+
## Unreleased][unreleased]
|
7
|
+
|
8
|
+
## [0.0.1] - 2015-06-04
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- initial release
|
12
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
## Sensu-Plugins-sensu
|
2
|
+
|
3
|
+
[](https://travis-ci.org/sensu-plugins/sensu-plugins-sensu)
|
4
|
+
[](http://badge.fury.io/rb/sensu-plugins-sensu)
|
5
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-sensu)
|
6
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-sensu)
|
7
|
+
[](https://gemnasium.com/sensu-plugins/sensu-plugins-sensu)
|
8
|
+
|
9
|
+
## Functionality
|
10
|
+
|
11
|
+
## Files
|
12
|
+
* bin/check-aggregate.rb
|
13
|
+
* bin/metrics-aggregate.rb
|
14
|
+
* bin/metrics-delete-expired-stashes.rb
|
15
|
+
* bin/handler-sensu.rb
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
[Installation and Setup](https://github.com/sensu-plugins/documentation/blob/master/user_docs/installation_instructions.md)
|
22
|
+
|
23
|
+
## Notes
|
@@ -0,0 +1,171 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Check Aggregate
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# Authors
|
7
|
+
# ===
|
8
|
+
# Sean Porter, @portertech
|
9
|
+
#
|
10
|
+
# Copyright 2012 Sonian, Inc.
|
11
|
+
#
|
12
|
+
# Released under the same terms as Sensu (the MIT license); see
|
13
|
+
# LICENSE for details.
|
14
|
+
|
15
|
+
require 'sensu-plugin/check/cli'
|
16
|
+
require 'rest-client'
|
17
|
+
require 'json'
|
18
|
+
|
19
|
+
class CheckAggregate < Sensu::Plugin::Check::CLI
|
20
|
+
option :api,
|
21
|
+
short: '-a URL',
|
22
|
+
long: '--api URL',
|
23
|
+
description: 'Sensu API URL',
|
24
|
+
default: 'http://localhost:4567'
|
25
|
+
|
26
|
+
option :user,
|
27
|
+
short: '-u USER',
|
28
|
+
long: '--user USER',
|
29
|
+
description: 'Sensu API USER'
|
30
|
+
|
31
|
+
option :password,
|
32
|
+
short: '-p PASSWORD',
|
33
|
+
long: '--password PASSWORD',
|
34
|
+
description: 'Sensu API PASSWORD'
|
35
|
+
|
36
|
+
option :timeout,
|
37
|
+
short: '-t SECONDS',
|
38
|
+
long: '--timeout SECONDS',
|
39
|
+
description: 'Sensu API connection timeout in SECONDS',
|
40
|
+
proc: proc(&:to_i),
|
41
|
+
default: 30
|
42
|
+
|
43
|
+
option :check,
|
44
|
+
short: '-c CHECK',
|
45
|
+
long: '--check CHECK',
|
46
|
+
description: 'Aggregate CHECK name',
|
47
|
+
required: true
|
48
|
+
|
49
|
+
option :age,
|
50
|
+
short: '-A SECONDS',
|
51
|
+
long: '--age SECONDS',
|
52
|
+
description: 'Minimum aggregate age in SECONDS, time since check request issued',
|
53
|
+
default: 30,
|
54
|
+
proc: proc(&:to_i)
|
55
|
+
|
56
|
+
option :limit,
|
57
|
+
short: '-l LIMIT',
|
58
|
+
long: '--limit LIMIT',
|
59
|
+
description: 'Limit of aggregates you want the API to return',
|
60
|
+
proc: proc(&:to_i)
|
61
|
+
|
62
|
+
option :summarize,
|
63
|
+
short: '-s',
|
64
|
+
long: '--summarize',
|
65
|
+
boolean: true,
|
66
|
+
description: 'Summarize check result output',
|
67
|
+
default: false
|
68
|
+
|
69
|
+
option :warning,
|
70
|
+
short: '-W PERCENT',
|
71
|
+
long: '--warning PERCENT',
|
72
|
+
description: 'PERCENT non-ok before warning',
|
73
|
+
proc: proc(&:to_i)
|
74
|
+
|
75
|
+
option :critical,
|
76
|
+
short: '-C PERCENT',
|
77
|
+
long: '--critical PERCENT',
|
78
|
+
description: 'PERCENT non-ok before critical',
|
79
|
+
proc: proc(&:to_i)
|
80
|
+
|
81
|
+
option :pattern,
|
82
|
+
short: '-P PATTERN',
|
83
|
+
long: '--pattern PATTERN',
|
84
|
+
description: 'A PATTERN to detect outliers'
|
85
|
+
|
86
|
+
option :message,
|
87
|
+
short: '-M MESSAGE',
|
88
|
+
long: '--message MESSAGE',
|
89
|
+
description: 'A custom error MESSAGE'
|
90
|
+
|
91
|
+
def api_request(resource)
|
92
|
+
request = RestClient::Resource.new(config[:api] + resource, timeout: config[:timeout],
|
93
|
+
user: config[:user],
|
94
|
+
password: config[:password])
|
95
|
+
JSON.parse(request.get, symbolize_names: true)
|
96
|
+
rescue RestClient::ResourceNotFound
|
97
|
+
warning "Resource not found: #{resource}"
|
98
|
+
rescue Errno::ECONNREFUSED
|
99
|
+
warning 'Connection refused'
|
100
|
+
rescue RestClient::RequestFailed
|
101
|
+
warning 'Request failed'
|
102
|
+
rescue RestClient::RequestTimeout
|
103
|
+
warning 'Connection timed out'
|
104
|
+
rescue RestClient::Unauthorized
|
105
|
+
warning 'Missing or incorrect Sensu API credentials'
|
106
|
+
rescue JSON::ParserError
|
107
|
+
warning 'Sensu API returned invalid JSON'
|
108
|
+
end
|
109
|
+
|
110
|
+
def acquire_aggregate
|
111
|
+
uri = "/aggregates/#{config[:check]}"
|
112
|
+
issued = api_request(uri + "?age=#{config[:age]}" + (config[:limit] ? "&limit=#{config[:limit]}" : ''))
|
113
|
+
# #YELLOW
|
114
|
+
unless issued.empty? # rubocop:disable UnlessElse
|
115
|
+
issued_sorted = issued.sort
|
116
|
+
time = issued_sorted.pop
|
117
|
+
# #YELLOW
|
118
|
+
unless time.nil? # rubocop:disable UnlessElse
|
119
|
+
uri += "/#{time}"
|
120
|
+
uri += '?summarize=output' if config[:summarize]
|
121
|
+
api_request(uri)
|
122
|
+
else
|
123
|
+
warning "No aggregates older than #{config[:age]} seconds"
|
124
|
+
end
|
125
|
+
else
|
126
|
+
warning "No aggregates for #{config[:check]}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def compare_thresholds(aggregate)
|
131
|
+
percent_non_zero = (100 - (aggregate[:ok].to_f / aggregate[:total].to_f) * 100).to_i
|
132
|
+
message = config[:message] || 'Number of non-zero results exceeds threshold'
|
133
|
+
message += " (#{percent_non_zero}% non-zero)"
|
134
|
+
if config[:critical] && percent_non_zero >= config[:critical]
|
135
|
+
critical message
|
136
|
+
elsif config[:warning] && percent_non_zero >= config[:warning]
|
137
|
+
warning message
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def compare_pattern(aggregate)
|
142
|
+
# #YELLOW
|
143
|
+
if config[:summarize] && config[:pattern] # rubocop:disable GuardClause
|
144
|
+
regex = Regexp.new(config[:pattern])
|
145
|
+
mappings = {}
|
146
|
+
message = config[:message] || 'One of these is not like the others!'
|
147
|
+
# #YELLOW
|
148
|
+
aggregate[:outputs].each do |output, _count| # rubocop:disable Style/Next
|
149
|
+
matched = regex.match(output.to_s)
|
150
|
+
unless matched.nil?
|
151
|
+
key = matched[1]
|
152
|
+
value = matched[2..-1]
|
153
|
+
if mappings.key?(key)
|
154
|
+
# #YELLOW
|
155
|
+
unless mappings[key] == value # rubocop:disable IfUnlessModifier, BlockNesting
|
156
|
+
critical message + " (#{key})"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
mappings[key] = value
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def run
|
166
|
+
aggregate = acquire_aggregate
|
167
|
+
compare_thresholds(aggregate)
|
168
|
+
compare_pattern(aggregate)
|
169
|
+
ok 'Aggregate looks GOOD'
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
##################
|
4
|
+
# Sensu Remediator
|
5
|
+
##################
|
6
|
+
#
|
7
|
+
# This plugin reads configuration from a check definition
|
8
|
+
# and triggers appropriate remediation actions (defined as
|
9
|
+
# other checks) via the Sensu API, when the occurrences and
|
10
|
+
# severities reach certain values.
|
11
|
+
#
|
12
|
+
# The severities should be a list of integers.
|
13
|
+
#
|
14
|
+
# The occurrences should be an array of Integers, or strings,
|
15
|
+
# where the strings are dash seperated integers or plus
|
16
|
+
# suffixed integers.
|
17
|
+
#
|
18
|
+
# By default, the remediation checks will be triggered on the
|
19
|
+
# the client where the check is failing. An array of
|
20
|
+
# subscriptions may be specified via a 'trigger_on' property
|
21
|
+
# outside of the 'remediation' dictionary (in the 'check' dictionary).
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
#
|
25
|
+
# {
|
26
|
+
# "checks": {
|
27
|
+
# "check_something": {
|
28
|
+
# "command": "ps aux | grep cron",
|
29
|
+
# "interval": 60,
|
30
|
+
# "subscribers": ["application_server"],
|
31
|
+
# "handler": ["debug", "irc", "remediator"],
|
32
|
+
# "remediation": {
|
33
|
+
# "light_remediation": {
|
34
|
+
# "occurrences": [1, 2],
|
35
|
+
# "severities": [1]
|
36
|
+
# },
|
37
|
+
# "medium_remediation": {
|
38
|
+
# "occurrences": ["3-10"],
|
39
|
+
# "severities": [1]
|
40
|
+
# },
|
41
|
+
# "heavy_remediation": {
|
42
|
+
# "occurrences": ["1+"],
|
43
|
+
# "severities": [2]
|
44
|
+
# }
|
45
|
+
# }
|
46
|
+
# },
|
47
|
+
# "light_remediation": {
|
48
|
+
# "command": "/bin/something",
|
49
|
+
# "subscribers": [],
|
50
|
+
# "handler": ["debug", "irc"],
|
51
|
+
# "publish": false,
|
52
|
+
# },
|
53
|
+
# "medium_remediation": {
|
54
|
+
# "command": "/bin/something_else",
|
55
|
+
# "subscribers": [],
|
56
|
+
# "handler": ["debug", "irc"],
|
57
|
+
# "publish": false,
|
58
|
+
# },
|
59
|
+
# "heavy_remediation": {
|
60
|
+
# "command": "sudo reboot",
|
61
|
+
# "subscribers": [],
|
62
|
+
# "handler": ["debug", "irc"],
|
63
|
+
# "publish": false,
|
64
|
+
# }
|
65
|
+
# }
|
66
|
+
# }
|
67
|
+
# ===
|
68
|
+
#
|
69
|
+
# Copyright 2012 Nick Stielau <nick.stielau@gamil.com>
|
70
|
+
#
|
71
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
72
|
+
# for details.
|
73
|
+
|
74
|
+
require 'sensu-handler'
|
75
|
+
require 'English'
|
76
|
+
|
77
|
+
class Remediator < Sensu::Handler
|
78
|
+
# Override filter_repeated from Sensu::Handler.
|
79
|
+
# Remediations are not alerts.
|
80
|
+
def filter_repeated; end
|
81
|
+
|
82
|
+
def handle
|
83
|
+
client = @event['client']['name']
|
84
|
+
remediations = @event['check']['remediation']
|
85
|
+
occurrences = @event['occurrences']
|
86
|
+
severity = @event['check']['status'].to_i
|
87
|
+
puts "REMEDIATION: Evaluating remediation: #{client} "\
|
88
|
+
"#{remediations.inspect} #=#{occurrences} sev=#{severity}"
|
89
|
+
|
90
|
+
remediation_checks = parse_remediations(remediations, occurrences, severity)
|
91
|
+
|
92
|
+
subscribers = @event['check']['trigger_on'] ? @event['check']['trigger_on'] : [client]
|
93
|
+
remediation_checks.each do |remediation_check|
|
94
|
+
puts "REMEDIATION: Triggering remediation check '#{remediation_check}' "\
|
95
|
+
"for #{[client].inspect}"
|
96
|
+
response = trigger_remediation(remediation_check, subscribers)
|
97
|
+
puts "REMEDIATION: Received API Response (#{response.code}): "\
|
98
|
+
"#{response.body}, exiting."
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Examine the defined remediations and return an array of
|
103
|
+
# checks that should be triggered given the current occurrence
|
104
|
+
# count and severity.
|
105
|
+
def parse_remediations(remediations, occurrences, severity)
|
106
|
+
remediations_to_trigger = []
|
107
|
+
|
108
|
+
remediations.each do |check, conditions|
|
109
|
+
# Check remediations matching the current severity
|
110
|
+
next unless (conditions['severities'] || []).include?(severity)
|
111
|
+
|
112
|
+
# Check for remediations matching the current occurrence count
|
113
|
+
trigger = false
|
114
|
+
(conditions['occurrences'] || []).each do |value|
|
115
|
+
trigger = case
|
116
|
+
when value.is_a?(Integer) && occurrences == value then true
|
117
|
+
when value.to_s =~ /^\d+$/ && occurrences == $LAST_MATCH_INFO.to_a.first.to_i then true
|
118
|
+
# #YELLOW
|
119
|
+
when value.to_s =~ /^(\d+)-(\d+)$/ && Range.new($LAST_MATCH_INFO.to_a[1].to_i, $LAST_MATCH_INFO.to_a[2].to_i).to_a.include?(occurrences) then true # rubocop:disable LineLength
|
120
|
+
when value.to_s.match(/^(\d+)\+$/) && Range.new($LAST_MATCH_INFO.to_a[1].to_i, 9999).include?(occurrences) then true
|
121
|
+
else false
|
122
|
+
end
|
123
|
+
break if trigger
|
124
|
+
end
|
125
|
+
|
126
|
+
remediations_to_trigger << check if trigger
|
127
|
+
end
|
128
|
+
remediations_to_trigger
|
129
|
+
end
|
130
|
+
|
131
|
+
# Issue a check via the API
|
132
|
+
def trigger_remediation(check, subscribers)
|
133
|
+
api_request(:POST, '/request') do |req|
|
134
|
+
req.body = JSON.dump('check' => check, 'subscribers' => subscribers)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Aggregate Metrics
|
4
|
+
#
|
5
|
+
# Walks the /aggregates API to return metrics for
|
6
|
+
# the aggregated output states of each check.
|
7
|
+
#
|
8
|
+
# sensu.aggregates.some_aggregated_check.ok 125 1380251999
|
9
|
+
# sensu.aggregates.some_aggregated_check.warning 0 1380251999
|
10
|
+
# sensu.aggregates.some_aggregated_check.critical 0 1380251999
|
11
|
+
# sensu.aggregates.some_aggregated_check.unknown 0 1380251999
|
12
|
+
# sensu.aggregates.some_aggregated_check.total 125 1380251999
|
13
|
+
# ===
|
14
|
+
#
|
15
|
+
# Authors
|
16
|
+
# ===
|
17
|
+
# Sean Porter, @portertech
|
18
|
+
# Nick Stielau, @nstielau
|
19
|
+
#
|
20
|
+
# Copyright 2013 Nick Stielau
|
21
|
+
# Copyright 2012 Sonian, Inc.
|
22
|
+
#
|
23
|
+
# Released under the same terms as Sensu (the MIT license); see
|
24
|
+
# LICENSE for details.
|
25
|
+
|
26
|
+
require 'sensu-plugin/metric/cli'
|
27
|
+
require 'rest-client'
|
28
|
+
require 'json'
|
29
|
+
|
30
|
+
class AggregateMetrics < Sensu::Plugin::Metric::CLI::Graphite
|
31
|
+
option :api,
|
32
|
+
short: '-a URL',
|
33
|
+
long: '--api URL',
|
34
|
+
description: 'Sensu API URL',
|
35
|
+
default: 'http://localhost:4567'
|
36
|
+
|
37
|
+
option :user,
|
38
|
+
short: '-u USER',
|
39
|
+
long: '--user USER',
|
40
|
+
description: 'Sensu API USER'
|
41
|
+
|
42
|
+
option :password,
|
43
|
+
short: '-p PASSOWRD',
|
44
|
+
long: '--password PASSWORD',
|
45
|
+
description: 'Sensu API PASSWORD'
|
46
|
+
|
47
|
+
option :timeout,
|
48
|
+
short: '-t SECONDS',
|
49
|
+
long: '--timeout SECONDS',
|
50
|
+
description: 'Sensu API connection timeout in SECONDS',
|
51
|
+
proc: proc(&:to_i),
|
52
|
+
default: 30
|
53
|
+
|
54
|
+
option :age,
|
55
|
+
short: '-A SECONDS',
|
56
|
+
long: '--age SECONDS',
|
57
|
+
description: 'Minimum aggregate age in SECONDS, time since check request issued',
|
58
|
+
default: 30,
|
59
|
+
proc: proc(&:to_i)
|
60
|
+
|
61
|
+
option :scheme,
|
62
|
+
description: 'Metric naming scheme',
|
63
|
+
long: '--scheme SCHEME',
|
64
|
+
default: "#{Socket.gethostname}.sensu.aggregates"
|
65
|
+
|
66
|
+
option :debug,
|
67
|
+
long: '--debug',
|
68
|
+
description: 'Verbose output'
|
69
|
+
|
70
|
+
def api_request(resource)
|
71
|
+
request = RestClient::Resource.new(config[:api] + resource, timeout: config[:timeout],
|
72
|
+
user: config[:user],
|
73
|
+
password: config[:password])
|
74
|
+
JSON.parse(request.get, symbolize_names: true)
|
75
|
+
rescue RestClient::ResourceNotFound
|
76
|
+
warning "Resource not found: #{resource}"
|
77
|
+
rescue Errno::ECONNREFUSED
|
78
|
+
warning 'Connection refused'
|
79
|
+
rescue RestClient::RequestFailed
|
80
|
+
warning 'Request failed'
|
81
|
+
rescue RestClient::RequestTimeout
|
82
|
+
warning 'Connection timed out'
|
83
|
+
rescue RestClient::Unauthorized
|
84
|
+
warning 'Missing or incorrect Sensu API credentials'
|
85
|
+
rescue JSON::ParserError
|
86
|
+
warning 'Sensu API returned invalid JSON'
|
87
|
+
end
|
88
|
+
|
89
|
+
def acquire_checks
|
90
|
+
uri = '/aggregates'
|
91
|
+
checks = api_request(uri)
|
92
|
+
puts "Checks: #{checks.inspect}" if config[:debug]
|
93
|
+
checks
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_aggregate(check)
|
97
|
+
uri = "/aggregates/#{check}"
|
98
|
+
issued = api_request(uri + "?age=#{config[:age]}")
|
99
|
+
# #YELLOW
|
100
|
+
unless issued.empty? # rubocop:disable UnlessElse
|
101
|
+
issued_sorted = issued.sort
|
102
|
+
time = issued_sorted.pop
|
103
|
+
# #YELLOW
|
104
|
+
unless time.nil? # rubocop:disable UnlessElse
|
105
|
+
uri += "/#{time}"
|
106
|
+
[time, api_request(uri)]
|
107
|
+
else
|
108
|
+
warning "No aggregates older than #{config[:age]} seconds"
|
109
|
+
end
|
110
|
+
else
|
111
|
+
warning "No aggregates for #{check}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def run
|
116
|
+
acquire_checks.each do |check|
|
117
|
+
timestamp, aggregate = get_aggregate(check[:check])
|
118
|
+
puts "#{check[:check]} aggregates: #{aggregate}" if config[:debug]
|
119
|
+
aggregate.each do |result, count|
|
120
|
+
output "#{config[:scheme]}.#{check[:check]}.#{result}", count, timestamp
|
121
|
+
end
|
122
|
+
end
|
123
|
+
ok
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Delete stashes when their 'expires' timestamp is exceeded
|
4
|
+
# ===
|
5
|
+
#
|
6
|
+
# Copyright 2013 Needle, Inc (ops@needle.com)
|
7
|
+
#
|
8
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
9
|
+
# for details.
|
10
|
+
|
11
|
+
require 'sensu-plugin/metric/cli'
|
12
|
+
require 'sensu-plugin/utils'
|
13
|
+
require 'rest-client'
|
14
|
+
require 'json'
|
15
|
+
require 'socket'
|
16
|
+
|
17
|
+
include Sensu::Plugin::Utils
|
18
|
+
|
19
|
+
class CheckSilenced < Sensu::Plugin::Metric::CLI::Graphite
|
20
|
+
default_host = settings['api']['host'] rescue 'localhost' # rubocop:disable RescueModifier
|
21
|
+
|
22
|
+
option :host,
|
23
|
+
short: '-h HOST',
|
24
|
+
long: '--host HOST',
|
25
|
+
description: 'Hostname for sensu-api endpoint',
|
26
|
+
default: default_host
|
27
|
+
|
28
|
+
option :port,
|
29
|
+
short: '-p PORT',
|
30
|
+
long: '--port PORT',
|
31
|
+
description: 'Port for sensu-api endpoint',
|
32
|
+
default: 4567
|
33
|
+
|
34
|
+
option :use_ssl,
|
35
|
+
short: '--ssl',
|
36
|
+
long: '--use-ssl',
|
37
|
+
description: 'Use ssl when connecting to sensu-api endpoint',
|
38
|
+
default: false
|
39
|
+
|
40
|
+
option :scheme,
|
41
|
+
short: '-s SCHEME',
|
42
|
+
long: '--scheme SCHEME',
|
43
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
44
|
+
default: "#{Socket.gethostname}.sensu.stashes.expired"
|
45
|
+
|
46
|
+
option :filter,
|
47
|
+
short: '-f PREFIX',
|
48
|
+
long: '--filter PREFIX',
|
49
|
+
description: 'Stash prefix filter',
|
50
|
+
default: 'silence'
|
51
|
+
|
52
|
+
option :noop,
|
53
|
+
short: '-n',
|
54
|
+
long: '--noop',
|
55
|
+
description: 'Do not delete expired stashes',
|
56
|
+
default: false
|
57
|
+
|
58
|
+
def api
|
59
|
+
endpoint = URI.parse("http://#{@config[:host]}:#{@config[:port]}")
|
60
|
+
@config[:use_ssl?] ? endpoint.scheme = 'https' : endpoint.scheme = 'http'
|
61
|
+
@api ||= RestClient::Resource.new(endpoint, timeout: 45)
|
62
|
+
end
|
63
|
+
|
64
|
+
def acquire_stashes
|
65
|
+
all_stashes = JSON.parse(api['/stashes'].get)
|
66
|
+
filtered_stashes = []
|
67
|
+
all_stashes.each do |stash|
|
68
|
+
filtered_stashes << stash if stash['path'].match(/^#{@config[:filter]}\/.*/)
|
69
|
+
end
|
70
|
+
return filtered_stashes
|
71
|
+
rescue Errno::ECONNREFUSED
|
72
|
+
warning 'Connection refused'
|
73
|
+
rescue RestClient::RequestTimeout
|
74
|
+
warning 'Connection timed out'
|
75
|
+
rescue JSON::ParserError
|
76
|
+
warning 'Sensu API returned invalid JSON'
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete_stash(stash)
|
80
|
+
api["/stash/#{stash['path']}"].delete
|
81
|
+
end
|
82
|
+
|
83
|
+
def run
|
84
|
+
@config = config
|
85
|
+
stashes = acquire_stashes
|
86
|
+
now = Time.now.to_i
|
87
|
+
@count = 0
|
88
|
+
if stashes.count > 0
|
89
|
+
stashes.each do |stash|
|
90
|
+
if stash['content'].key?('expires') && now - stash['content']['expires'] > 0
|
91
|
+
delete_stash(stash) unless config[:noop]
|
92
|
+
@count += 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
ok "#{config[:scheme]}.sensu.stashes.expired", @count
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'sensu-plugins-sensu/version'
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sensu-plugins-sensu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sensu-Plugins and contributors
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDgDCCAmigAwIBAgIBATANBgkqhkiG9w0BAQUFADBDMRIwEAYDVQQDDAltYXR0
|
14
|
+
am9uZXMxGDAWBgoJkiaJk/IsZAEZFgh5aWVsZGJvdDETMBEGCgmSJomT8ixkARkW
|
15
|
+
A2NvbTAeFw0xNTAxMjgyMTAyNTFaFw0xNjAxMjgyMTAyNTFaMEMxEjAQBgNVBAMM
|
16
|
+
CW1hdHRqb25lczEYMBYGCgmSJomT8ixkARkWCHlpZWxkYm90MRMwEQYKCZImiZPy
|
17
|
+
LGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyTSzVYnO
|
18
|
+
CLgyrIyT1mBQakArQyW8xhi6MlDqyzXHJGeERT790U6EgoBVeS4XoK0ptFZNR8Tf
|
19
|
+
zko0w+Nv47TarSCgkPOaxY+mxWnAVR10dOmfeLr7huiMyps+YD56/EF2FqQ3jf/+
|
20
|
+
qohENfKD91qy1ieEy+Fn7Pf74ltbNKUdkb9a9eFXQ0DQ4ip5vik7DzjQkUTj4lca
|
21
|
+
k6ArwnmHX4YDhZoYtrQJ8jVktN0/+NtA40M5qkCYHNe5tUW25b/tKVYuioxG6b2Z
|
22
|
+
oIzaZxRLxf6HVAWpCVRT/F5+/yjigkX4u++eYacfLGleXQzoK7BL65vHGMJygWEE
|
23
|
+
0TKGqFOrl/L0AQIDAQABo38wfTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV
|
24
|
+
HQ4EFgQUEf6a8Td7MrSZc8ImbLFZAENPbz0wIQYDVR0RBBowGIEWbWF0dGpvbmVz
|
25
|
+
QHlpZWxkYm90LmNvbTAhBgNVHRIEGjAYgRZtYXR0am9uZXNAeWllbGRib3QuY29t
|
26
|
+
MA0GCSqGSIb3DQEBBQUAA4IBAQBbzXAYA3BVGw8DZ0YYoY1VHPNEcH5qPIApmHO8
|
27
|
+
rvSmuUT0yMEi7u00H/5uHRFf4LleGT/+sTdyXKsNPGT9kdRuQEgwi+vf7Zfvd8aX
|
28
|
+
UF/+4VkEYf/8rV8Ere6u2QaWPgApdMV6JjKr1fAwCTd8AuGXNaWItiPPMseSQzLJ
|
29
|
+
JKP4hVvbc1d+oS925B1lcBiqn2aYvElbyNAVmQPywNNqkWmvtlqj9ZVJfV5HQLdu
|
30
|
+
8sHuVruarogxxKPBzlL2is4EUb6oN/RdpGx2l4254+nyR+abg//Ed27Ym0PkB4lk
|
31
|
+
HP0m8WSjZmFr109pE/sVsM5jtOCvogyujQOjNVGN4gz1wwPr
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2015-07-04 00:00:00.000000000 Z
|
34
|
+
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: sensu-plugin
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.1.0
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.1.0
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rest-client
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.8.0
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.8.0
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: json
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.3
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.8.3
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: english
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.6.3
|
84
|
+
type: :runtime
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.6.3
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: bundler
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.7'
|
98
|
+
type: :development
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '1.7'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: codeclimate-test-reporter
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0.4'
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0.4'
|
119
|
+
- !ruby/object:Gem::Dependency
|
120
|
+
name: github-markup
|
121
|
+
requirement: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '1.3'
|
126
|
+
type: :development
|
127
|
+
prerelease: false
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '1.3'
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: pry
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0.10'
|
140
|
+
type: :development
|
141
|
+
prerelease: false
|
142
|
+
version_requirements: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0.10'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: rubocop
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - '='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0.30'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - '='
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0.30'
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
name: rspec
|
163
|
+
requirement: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '3.1'
|
168
|
+
type: :development
|
169
|
+
prerelease: false
|
170
|
+
version_requirements: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '3.1'
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: rake
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - "~>"
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '10.0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - "~>"
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '10.0'
|
189
|
+
- !ruby/object:Gem::Dependency
|
190
|
+
name: redcarpet
|
191
|
+
requirement: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - "~>"
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '3.2'
|
196
|
+
type: :development
|
197
|
+
prerelease: false
|
198
|
+
version_requirements: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - "~>"
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '3.2'
|
203
|
+
- !ruby/object:Gem::Dependency
|
204
|
+
name: yard
|
205
|
+
requirement: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - "~>"
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0.8'
|
210
|
+
type: :development
|
211
|
+
prerelease: false
|
212
|
+
version_requirements: !ruby/object:Gem::Requirement
|
213
|
+
requirements:
|
214
|
+
- - "~>"
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0.8'
|
217
|
+
description: Sensu sensu plugins
|
218
|
+
email: "<sensu-users@googlegroups.com>"
|
219
|
+
executables:
|
220
|
+
- metrics-delete-expired-stashes.rb
|
221
|
+
- metrics-aggregate.rb
|
222
|
+
- handler-sensu.rb
|
223
|
+
- check-aggregate.rb
|
224
|
+
extensions: []
|
225
|
+
extra_rdoc_files: []
|
226
|
+
files:
|
227
|
+
- CHANGELOG.md
|
228
|
+
- LICENSE
|
229
|
+
- README.md
|
230
|
+
- bin/check-aggregate.rb
|
231
|
+
- bin/handler-sensu.rb
|
232
|
+
- bin/metrics-aggregate.rb
|
233
|
+
- bin/metrics-delete-expired-stashes.rb
|
234
|
+
- lib/sensu-plugins-sensu.rb
|
235
|
+
- lib/sensu-plugins-sensu/version.rb
|
236
|
+
homepage: https://github.com/sensu-plugins/sensu-plugins-sensu
|
237
|
+
licenses:
|
238
|
+
- MIT
|
239
|
+
metadata:
|
240
|
+
maintainer: sensu-plugin
|
241
|
+
development_status: active
|
242
|
+
production_status: unstable - testing recommended
|
243
|
+
release_draft: 'false'
|
244
|
+
release_prerelease: 'false'
|
245
|
+
post_install_message: You can use the embedded Ruby by setting EMBEDDED_RUBY=true
|
246
|
+
in /etc/default/sensu
|
247
|
+
rdoc_options: []
|
248
|
+
require_paths:
|
249
|
+
- lib
|
250
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - ">="
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 1.9.3
|
255
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
|
+
requirements:
|
257
|
+
- - ">="
|
258
|
+
- !ruby/object:Gem::Version
|
259
|
+
version: '0'
|
260
|
+
requirements: []
|
261
|
+
rubyforge_project:
|
262
|
+
rubygems_version: 2.4.6
|
263
|
+
signing_key:
|
264
|
+
specification_version: 4
|
265
|
+
summary: Sensu plugins for sensu
|
266
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|