This repository has been archived by the owner on Nov 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handle_alerts.rb
executable file
·138 lines (108 loc) · 3.29 KB
/
handle_alerts.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
#!/usr/bin/env ruby1.9
# this file is designed to be run by collectd by:
# <Plugin exec>
# NotificationExec "user" "/path/to/handle_alerts.rb"
# </Plugin>
#
# input time are supposed to be in GMT
#
# alerts will be logged in file and emails will be sent
# to each configured recipients
#
begin
# Require the preresolved locked set of gems.
require File.expand_path('../.bundle/environment', __FILE__)
rescue LoadError
# Fallback on doing the resolve at runtime.
require "bundler"
Bundler.setup
end
Bundler.require(:default, :notifications)
require 'logger'
require 'yaml'
module Config
def self._data
@config ||= YAML.parse_file( File.join(File.dirname(__FILE__), 'config/alerts_conf.yml') )
end
def self.timezone
@tz ||= TZInfo::Timezone.get(_data['timezone'].value)
end
def self.email_recipients
@email_list ||= _data['emails']['recipients'].value.map(&:value)
end
def self.from_email
@email_from ||= _data['emails']['from'].value
end
def self.smtp_host
@smtp_host ||= _data['emails']['host'].value
end
def self.logger
log_file = Config._data['logger']['path'].value
@logger ||= Logger.new( STDOUT )
end
end
MmMail::Transport::DefaultConfig.host = Config::smtp_host
def send_email(subject, body)
Config::email_recipients.each do |recipient|
MmMail.mail(
:to => recipient,
:from => Config::from_email,
:subject => subject,
:body => body,
)
end
end
class Notification
FLOAT_VALUES = [:value, :warn_min, :warn_max, :failure_min, :failure_max].freeze
attr_accessor :severity, :time, :host, :plugin, :plugin_instance, :type, :type_instance, :datasource, :value,
:warn_min, :warn_max, :failure_min, :failure_max, :message
def initialize(md)
md.names.each do |key|
if FLOAT_VALUES.include?(key.to_sym)
send("#{key}=", md[key.to_sym].to_f)
else
send("#{key}=", md[key.to_sym])
end
end
t = Time.at(self.time.to_i)
self.time = Config::timezone.utc_to_local(t)
end
end
module NotificationHandler
REGEXP = %r{^\
Severity: (?<severity>[^\n]+)\n\
Time: (?<time>[0-9]+)\n\
(?:Host: (?<host>[^\n]+)\n)?\
(?:Plugin: (?<plugin>[^\n]+)\n)?\
(?:PluginInstance: (?<plugin_instance>[^\n]+)\n)?\
(?:Type: (?<type>[^\n]+)\n)?\
(?:TypeInstance: (?<type_instance>[^\n]+)\n)?\
(?:DataSource: (?<datasource>[^\n]+)\n)?\
(?:CurrentValue: (?<value>[^\n]+)\n)?\
(?:WarningMin: (?<warn_min>[^\n]+)\n)?\
(?:WarningMax: (?<warn_max>[^\n]+)\n)?\
(?:FailureMin: (?<failure_min>[^\n]+)\n)?\
(?:FailureMax: (?<failure_max>[^\n]+)\n)?\
\n+\
(?:(?<message>[^\n]+)\n)?$}
def parse(str)
m = REGEXP.match(str)
m ? Notification.new(m) : nil
end
def receive_data(data)
# puts "DATA: #{data}"
if ev = parse(data)
Config::logger.debug("[#{ev.time.strftime('%H:%m:%S')} - #{ev.host}] #{ev.severity} ")
send_email("[%%%] #{ev.host} - #{ev.plugin}:#{ev.type}:#{ev.type_instance} - #{ev.severity}", %{\
Current Value: #{ev.value}
Warning thresholds: #{ev.warn_min} - #{ev.warn_max}
Failure thresholds: #{ev.failure_min} - #{ev.failure_max}
Message: #{ev.message}
})
end
end
end
# EM::kqueue = true
EM::run do
EM::open_datagram_socket('127.0.0.1', 6000, NotificationHandler)
end