aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mauve/alert.rb67
-rw-r--r--lib/mauve/mauve_resolv.rb23
-rw-r--r--lib/mauve/source_list.rb20
-rw-r--r--views/alert.haml4
4 files changed, 89 insertions, 25 deletions
diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb
index 3c9fbdc..ace20cc 100644
--- a/lib/mauve/alert.rb
+++ b/lib/mauve/alert.rb
@@ -94,6 +94,9 @@ module Mauve
property :will_clear_at, EpochTime
property :will_raise_at, EpochTime
property :will_unacknowledge_at, EpochTime
+
+ property :cached_alert_group, String
+
has n, :changes, :model => AlertChanged
has n, :histories, :through => :alerthistory
@@ -102,6 +105,8 @@ module Mauve
before :valid?, :do_set_timestamps
before :save, :do_sanitize_html
before :save, :take_copy_of_changes
+ before :save, :update_alert_group_cache
+
after :save, :notify_if_needed
after :destroy, :destroy_associations
@@ -136,17 +141,50 @@ module Mauve
end
end
+ def update_alert_group_cache
+ if @alert_group.nil? or self.updated_at < @alert_group.last_resolved_at
+ #
+ # Find the alert group
+ #
+ alert_group = AlertGroup.matches(self).first
+ else
+ alert_group = @alert_group
+ end
+
+ #
+ # Cache the name
+ #
+ if alert_group.is_a?(AlertGroup)
+ attribute_set("cached_alert_group", alert_group.name)
+ else
+ attribute_set("cached_alert_group", nil)
+ end
+
+ true
+ end
+
#
# @return [Mauve::AlertGroup] The first matching AlertGroup for this alert
def alert_group
- @alert_group ||= AlertGroup.matches(self).first
+ #
+ # Find the AlertGroup by name if we've got a cached value
+ #
+ @alert_group = AlertGroup.all.find{|a| self.cached_alert_group == a.name} if @alert_group.nil? and self.cached_alert_group
+
+ #
+ # If we've not found the alert group by name, or the object hasn't been
+ # saved since the alert group was last resolved, look for it again.
+ #
+ @alert_group = AlertGroup.matches(self).first if @alert_group.nil? or self.updated_at < (Time.now - 1800)
+
+ @alert_group
end
# Pick out the source lists that match this alert by subject.
#
# @return [Array] All the SourceList matches
def source_lists
- Mauve::Configuration.current.source_lists.select{|label, list| list.includes?(self.subject)}.collect{|sl| sl.first}
+ Mauve::Configuration.current.source_lists.collect{|label, list| self.in_source_list?(label) ? label : nil}.compact
end
# Checks to see if included in a named source list
@@ -156,7 +194,30 @@ module Mauve
def in_source_list?(listname)
list = Mauve::Configuration.current.source_lists[listname]
return false unless list.is_a?(SourceList)
- list.includes?(self.subject)
+ self.subject_hosts_and_ips.any?{|host| list.includes?(host) }
+ end
+
+ def subject_hosts_and_ips
+ if @subject_hosts_and_ips.nil? or @subject_hosts_and_ips_last_resolved_at.nil? or (Time.now - 1800) > @subject_hosts_and_ips_last_resolved_at
+ host = self.subject
+ #
+ # Pick out hostnames from URIs.
+ #
+ if host =~ /^[a-z][a-z0-9+-]+:\/\//
+ begin
+ uri = URI.parse(host)
+ host = uri.host unless uri.host.nil?
+ rescue URI::InvalidURIError => ex
+ # ugh
+ logger.warn "Did not recognise URI #{host}"
+ end
+ end
+
+ @subject_hosts_and_ips = ([host] + MauveResolv.get_ips_for(host)).flatten
+ @subject_hosts_and_ips_last_resolved_at = Time.now
+ end
+
+ @subject_hosts_and_ips
end
# Returns the alert level
diff --git a/lib/mauve/mauve_resolv.rb b/lib/mauve/mauve_resolv.rb
index c6460e3..a9c7526 100644
--- a/lib/mauve/mauve_resolv.rb
+++ b/lib/mauve/mauve_resolv.rb
@@ -15,23 +15,26 @@ module Mauve
# @return [Array] Array of IP addresses, as Strings.
#
def get_ips_for(host)
- record_types = %w(A AAAA)
+ pp host
ips = []
-
- %w(A AAAA).each do |type|
- begin
- Resolv::DNS.open do |dns|
- dns.getresources(host, Resolv::DNS::Resource::IN.const_get(type)).each do |a|
- ips << a.address.to_s
- end
+ @count ||= 0
+ Resolv::DNS.open do |dns|
+ %w(A AAAA).each do |type|
+ @count += 1
+ begin
+ ips += dns.getresources(host, Resolv::DNS::Resource::IN.const_get(type)).collect{|a| a.address.to_s}
+ rescue Resolv::ResolvError, Resolv::ResolvTimeout => e
+ logger.warn("#{host} could not be resolved because #{e.message}.")
end
- rescue Resolv::ResolvError, Resolv::ResolvTimeout => e
- logger.warn("#{host} could not be resolved because #{e.message}.")
end
end
ips
end
+ def count
+ @count ||= 0
+ end
+
# @return [Log4r::Logger]
def logger
@logger ||= Log4r::Logger.new(self.to_s)
diff --git a/lib/mauve/source_list.rb b/lib/mauve/source_list.rb
index b8c89cc..63a7aa6 100644
--- a/lib/mauve/source_list.rb
+++ b/lib/mauve/source_list.rb
@@ -19,7 +19,7 @@ module Mauve
#
class SourceList
- attr_reader :label, :list
+ attr_reader :label, :list, :last_resolved_at
## Default contructor.
def initialize (label)
@@ -153,15 +153,15 @@ module Mauve
end
end
- return false unless @resolved_list.any?{|l| l.is_a?(IPAddr)}
-
- ips = MauveResolv.get_ips_for(host).collect{|i| IPAddr.new(i)}
-
- return false if ips.empty?
-
- return @resolved_list.select{|i| i.is_a?(IPAddr)}.any? do |list_ip|
- ips.any?{|ip| list_ip.include?(ip)}
- end
+# return false unless @resolved_list.any?{|l| l.is_a?(IPAddr)}
+#
+# ips = MauveResolv.get_ips_for(host).collect{|i| IPAddr.new(i)}
+#
+# return false if ips.empty?
+#
+# return @resolved_list.select{|i| i.is_a?(IPAddr)}.any? do |list_ip|
+# ips.any?{|ip| list_ip.include?(ip)}
+# end
return false
end
diff --git a/views/alert.haml b/views/alert.haml
index 220f871..b16047a 100644
--- a/views/alert.haml
+++ b/views/alert.haml
@@ -18,8 +18,8 @@
%th{:title => "ID set by the source of the alert."} Alert ID
%td= @alert.alert_id
%tr
- %th{:title => "The groups in the Mauve server configuration that match this alert"} Alert groups
- %td= Mauve::AlertGroup.matches(@alert).map{|g| g.name}.join("; ")
+ %th{:title => "The group in the Mauve server configuration that match this alert"} Alert groups
+ %td= @alert.alert_group
%tr
%th{:title => "The level of the first group in the Mauve server configuration that matched this alert"} Alert level
%td= @alert.level.to_s.upcase