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
|
# encoding: UTF-8
require 'mauve/alert'
require 'log4r'
module Mauve
class AlertGroup < Struct.new(:name, :includes, :acknowledgement_time, :level, :notifications)
#
# Define some constants, and the ordering.
#
URGENT = :urgent
NORMAL = :normal
LOW = :low
LEVELS = [LOW, NORMAL, URGENT]
class << self
def matches(alert)
grps = all.select { |alert_group| alert_group.includes?(alert) }
#
# Make sure we always match the last (and therefore default) group.
#
grps << all.last unless grps.include?(all.last)
grps
end
def logger
Log4r::Logger.new self.to_s
end
def all
return [] if Configuration.current.nil?
Configuration.current.alert_groups
end
# Find all alerts that match
#
# @deprecated Buggy method, use Alert.get_all().
#
# This method returns all the alerts in all the alert_groups. Only
# the first one should be returned thus making this useless. If you want
# a list of all the alerts matching a level, use Alert.get_all().
#
def all_alerts_by_level(level)
Configuration.current.alert_groups.map do |alert_group|
alert_group.level == level ? alert_group.current_alerts : []
end.flatten.uniq
end
end
def initialize(name)
self.name = name
self.level = :normal
self.includes = Proc.new { true }
end
def inspect
"#<AlertGroup:#{name} (level #{level})>"
end
# The list of current raised alerts in this group.
#
def current_alerts
Alert.all(:cleared_at => nil, :raised_at.not => nil).select { |a| includes?(a) }
end
# Decides whether a given alert belongs in this group according to its
# includes { } clause
#
# @param [Alert] alert An alert to test for belongness to group.
# @return [Boolean] Success or failure.
def includes?(alert)
unless alert.is_a?(Alert)
logger.error "Got given a #{alert.class} instead of an Alert!"
logger.debug caller.join("\n")
return false
end
alert.instance_eval(&self.includes) ? true : false
end
alias matches_alert? includes?
def logger ; self.class.logger ; end
# Signals that a given alert (which is assumed to belong in this group)
# has undergone a significant change. We resend this to every notify list.
#
def notify(alert)
#
# If there are no notifications defined.
#
if notifications.nil?
logger.warn("No notifications found for #{self.inspect}")
return
end
#
# The notifications are specified in the config file.
#
notifications.each do |notification|
notification.notify(alert)
end
end
#
# This sorts by priority (urgent first), and then alphabetically, so the
# first match is the most urgent.
#
def <=>(other)
[LEVELS.index(self.level), self.name] <=> [LEVELS.index(other.level), other.name]
end
end
end
|