-
Notifications
You must be signed in to change notification settings - Fork 117
/
sensu-handler.rb
167 lines (141 loc) · 4.44 KB
/
sensu-handler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
require 'net/http'
require 'json'
require 'sensu-plugin/utils'
require 'mixlib/cli'
module Sensu
class Handler
include Sensu::Plugin::Utils
include Mixlib::CLI
attr_accessor :argv
def initialize(argv = ARGV)
super()
self.argv = parse_options(argv)
end
# Implementing classes should override this.
def handle
puts 'ignoring event -- no handler defined'
end
# Filters exit the proccess if the event should not be handled.
# Implementation of the default filters is below.
def filter
filter_disabled
filter_repeated
filter_silenced
filter_dependencies
end
# This works just like Plugin::CLI's autorun.
@@autorun = self
class << self
def method_added(name)
if name == :handle
@@autorun = self
end
end
end
def self.disable_autorun
@@autorun = false
end
at_exit do
if @@autorun
handler = @@autorun.new
handler.read_event(STDIN)
handler.filter
handler.handle
end
end
# Helpers and filters.
def event_summary(trim_at=100)
summary = @event['check']['notification'] || @event['check']['description']
if summary.nil?
source = @event['check']['source'] || @event['client']['name']
event_context = [source, @event['check']['name']].join('/')
output = @event['check']['output'].chomp
output = output.length > trim_at ? output[0..trim_at] + '...' : output
summary = [event_context, output].join(' : ')
end
summary
end
def bail(msg)
puts msg + ': ' + @event['client']['name'] + '/' + @event['check']['name']
exit 0
end
def api_request(method, path, &blk)
http = Net::HTTP.new(settings['api']['host'], settings['api']['port'])
req = net_http_req_class(method).new(path)
if settings['api']['user'] && settings['api']['password']
req.basic_auth(settings['api']['user'], settings['api']['password'])
end
yield(req) if block_given?
http.request(req)
end
def filter_disabled
if @event['check']['alert'] == false
bail 'alert disabled'
end
end
def filter_repeated
defaults = {
'occurrences' => 1,
'interval' => 30,
'refresh' => 1800
}
if settings['sensu_plugin'].is_a?(Hash)
defaults.merge!(settings['sensu_plugin'])
end
occurrences = (@event['check']['occurrences'] || defaults['occurrences']).to_i
interval = (@event['check']['interval'] || defaults['interval']).to_i
refresh = (@event['check']['refresh'] || defaults['refresh']).to_i
if @event['occurrences'] < occurrences
bail 'not enough occurrences'
end
if @event['occurrences'] > occurrences && @event['action'] == 'create'
number = refresh.fdiv(interval).to_i
unless number == 0 || @event['occurrences'] % number == 0
bail 'only handling every ' + number.to_s + ' occurrences'
end
end
end
def stash_exists?(path)
api_request(:GET, '/stash' + path).code == '200'
end
def filter_silenced
stashes = [
['client', '/silence/' + @event['client']['name']],
['check', '/silence/' + @event['client']['name'] + '/' + @event['check']['name']],
['check', '/silence/all/' + @event['check']['name']]
]
stashes.each do |(scope, path)|
begin
timeout(2) do
if stash_exists?(path)
bail scope + ' alerts silenced'
end
end
rescue Timeout::Error
puts 'timed out while attempting to query the sensu api for a stash'
end
end
end
def event_exists?(client, check)
api_request(:GET, '/event/' + client + '/' + check).code == '200'
end
def filter_dependencies
if @event['check'].has_key?('dependencies')
if @event['check']['dependencies'].is_a?(Array)
@event['check']['dependencies'].each do |dependency|
begin
timeout(2) do
check, client = dependency.split('/').reverse
if event_exists?(client || @event['client']['name'], check)
bail 'check dependency event exists'
end
end
rescue Timeout::Error
puts 'timed out while attempting to query the sensu api for an event'
end
end
end
end
end
end
end