diff options
-rw-r--r-- | lib/mauve/alert.rb | 67 | ||||
-rw-r--r-- | lib/mauve/mauve_resolv.rb | 23 | ||||
-rw-r--r-- | lib/mauve/source_list.rb | 20 | ||||
-rw-r--r-- | views/alert.haml | 4 |
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 |