hostmon 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hostmon +4 -0
- data/examples/config.yml +14 -0
- data/examples/reports/bad_exit_status/cluster1/mach1/report_2012-06-28-16:49:32.yaml +11 -0
- data/examples/reports/bad_exit_status/cluster2/mach1/report_2012-06-14-15:06:12.yaml +11 -0
- data/examples/reports/bad_exit_status/cluster2/mach2/report_2012-06-14-15:06:12.yaml +11 -0
- data/examples/reports/foo/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
- data/examples/reports/foo/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/foo/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/missing_prelude/cluster1/mach1/report_2012-06-28-16:49:32.yaml +12 -0
- data/examples/reports/missing_prelude/cluster2/mach1/report_2012-06-14-15:06:12.yaml +12 -0
- data/examples/reports/missing_prelude/cluster2/mach2/report_2012-06-14-15:06:12.yaml +12 -0
- data/examples/reports/network/config/bootproto_dhcp/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
- data/examples/reports/network/config/bootproto_dhcp/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/network/config/bootproto_dhcp/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/network/ethernet_bonded/cluster1/mach1/report_2012-06-28-16:49:32.yaml +31 -0
- data/examples/reports/network/ethernet_bonded/cluster2/mach1/report_2012-06-14-15:06:12.yaml +22 -0
- data/examples/reports/network/ethernet_bonded/cluster2/mach2/report_2012-06-14-15:06:12.yaml +22 -0
- data/examples/reports/nonexec/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
- data/examples/reports/nonexec/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/nonexec/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
- data/examples/reports/yum/badcheck/cluster1/mach1/report_2012-06-28-16:49:32.yaml +13 -0
- data/examples/reports/yum/badcheck/cluster2/mach1/report_2012-06-14-15:06:12.yaml +13 -0
- data/examples/reports/yum/badcheck/cluster2/mach2/report_2012-06-14-15:06:12.yaml +13 -0
- data/lib/hostmon.rb +208 -0
- data/lib/hostmon/config.rb +47 -0
- data/lib/hostmon/helpers.rb +174 -0
- data/lib/hostmon/models.rb +4 -0
- data/lib/hostmon/models/base.rb +39 -0
- data/lib/hostmon/models/check.rb +45 -0
- data/lib/hostmon/models/host.rb +211 -0
- data/lib/hostmon/models/report.rb +108 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_20_333333_1x400.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_40_000000_1x400.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_highlight-soft_15_000000_1x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_inset-soft_30_ff4e0a_1x100.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_222222_256x240.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_4b8e0b_256x240.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_a83300_256x240.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_cccccc_256x240.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/hostmon/public/css/jquery_themes/hostmon/jquery-ui-1.8.16.custom.css +568 -0
- data/lib/hostmon/public/favicon.ico +0 -0
- data/lib/hostmon/public/js/cufon.js +7 -0
- data/lib/hostmon/public/js/gotham.font.js +40 -0
- data/lib/hostmon/public/js/hostmon.js +89 -0
- data/lib/hostmon/public/js/jquery-1.6.2.min.js +18 -0
- data/lib/hostmon/public/js/jquery-ui-1.8.16.custom.min.js +791 -0
- data/lib/hostmon/public/js/product-design.font.js +8 -0
- data/lib/hostmon/public/style.css +311 -0
- data/lib/hostmon/rubyfixes.rb +12 -0
- data/lib/hostmon/version.rb +3 -0
- data/lib/hostmon/views/check.erb +23 -0
- data/lib/hostmon/views/check_status.erb +16 -0
- data/lib/hostmon/views/cluster.erb +19 -0
- data/lib/hostmon/views/host.erb +15 -0
- data/lib/hostmon/views/host_status.erb +16 -0
- data/lib/hostmon/views/layout.erb +61 -0
- data/lib/hostmon/views/partials/check_status_selector.erb +6 -0
- data/lib/hostmon/views/partials/host_status_selector.erb +6 -0
- data/lib/hostmon/views/partials/hosts_selector.erb +9 -0
- data/lib/hostmon/views/partials/report.erb +7 -0
- data/lib/hostmon/views/partials/search.erb +18 -0
- data/lib/hostmon/views/partials/status_selector.erb +7 -0
- data/lib/hostmon/views/search_all.erb +25 -0
- data/lib/hostmon/views/search_checks.erb +12 -0
- data/lib/hostmon/views/search_host.erb +7 -0
- data/lib/hostmon/views/status.erb +15 -0
- data/lib/hostmon/views/view.erb +49 -0
- metadata +152 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "hostmon/models"
|
3
|
+
|
4
|
+
module Hostmon
|
5
|
+
class Config
|
6
|
+
include Hostmon::Models
|
7
|
+
attr_reader :global_config, :report_dir, :conf_file, :amqp_config
|
8
|
+
attr_reader :bugzilla_config
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
port = 9292
|
12
|
+
@conf_file = "./config.yml"
|
13
|
+
|
14
|
+
optparse = OptionParser.new do |o|
|
15
|
+
o.on("-f", "--config-file FILE",
|
16
|
+
"location of the config directory (default .)") do |arg|
|
17
|
+
@conf_file = arg
|
18
|
+
end
|
19
|
+
o.on("-p", "--port PORT", "port to bind to (default 9292)") do |arg|
|
20
|
+
port = arg.to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
optparse.parse!
|
25
|
+
reload!
|
26
|
+
@global_config[:port] = port
|
27
|
+
end
|
28
|
+
|
29
|
+
def reload!
|
30
|
+
raw = File.read(@conf_file)
|
31
|
+
raise "failed to load #{@conf_file}" unless yaml = YAML.load(raw)
|
32
|
+
|
33
|
+
@global_config = yaml[:main]
|
34
|
+
@bugzilla_config = yaml[:bugzilla] || false
|
35
|
+
@amqp_config = yaml[:amqp] || {}
|
36
|
+
# do some sanity checking of other configuration parameters
|
37
|
+
[:report_dir].each do |c|
|
38
|
+
if not @global_config[c]
|
39
|
+
raise "Missing config name '#{c.to_s}'"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@global_config[:saved_reports] ||= 1
|
44
|
+
@report_dir = @global_config[:report_dir]
|
45
|
+
end
|
46
|
+
end # Hostmon::Config
|
47
|
+
end # Hostmon
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Hostmon::Helpers
|
2
|
+
include Hostmon::Models
|
3
|
+
|
4
|
+
#fixme failing vs failed
|
5
|
+
def cluster_link(cluster)
|
6
|
+
"/cluster/#{cluster}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def append_query_string(str)
|
10
|
+
v = str.dup
|
11
|
+
# CGI::escapeHTML()?
|
12
|
+
unless request.query_string.empty?
|
13
|
+
v << "?#{request.query_string.gsub("&", "&")}"
|
14
|
+
end
|
15
|
+
return v
|
16
|
+
end
|
17
|
+
|
18
|
+
def color(status)
|
19
|
+
map = {:CHECK_OK => "green",
|
20
|
+
:CHECK_FAILED => "red"}
|
21
|
+
"[" + status.map do |s|
|
22
|
+
"<span style=\"color:#{map[s]||'orange'}\">#{s}</span>"
|
23
|
+
end.join(', ') + "]"
|
24
|
+
end
|
25
|
+
|
26
|
+
def rstatus(report)
|
27
|
+
j = report.ok? ? "ok" : "error"
|
28
|
+
"<#{j}>#{color(report.status)}</#{j}> #{bugzilla_link(report) if j=="error" } #{bugzilla_search_link(report) if j=="error" }"
|
29
|
+
end
|
30
|
+
|
31
|
+
def css_url
|
32
|
+
style = File.join(settings.root, "public/style.css")
|
33
|
+
mtime = File.mtime(style).to_i.to_s
|
34
|
+
return \
|
35
|
+
%Q[<link href="/style.css?#{mtime}" rel="stylesheet" type="text/css">]
|
36
|
+
end
|
37
|
+
|
38
|
+
def aggregate_bugzilla(check)
|
39
|
+
return "" unless settings.config.bugzilla_config
|
40
|
+
url = settings.config.bugzilla_config[:bugzilla_url]
|
41
|
+
h_url = settings.config.bugzilla_config[:hostlint_url]
|
42
|
+
failing = check.hosts_failing.map(&:first).size
|
43
|
+
failing += check.hosts_check_failing.map(&:first).size
|
44
|
+
succeeding = check.hosts_ok.map(&:first).size
|
45
|
+
fields = { :short_desc => "[hostlint] hosts failing #{check}",
|
46
|
+
:comment => "#{failing.size}/#{failing + succeeding} hosts failing at report time (#{Time.now}).
|
47
|
+
See #{h_url}/check/#{check}",
|
48
|
+
:keyword => ""
|
49
|
+
}
|
50
|
+
url_parts = []
|
51
|
+
fields.each do |k, v|
|
52
|
+
[v].flatten.each do |v2|
|
53
|
+
url_parts << "#{URI.escape(k.to_s)}=#{URI.escape(v2.to_s)}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
url += "&" + url_parts.join("&")
|
57
|
+
"<a href=\"#{url}\" target=\"_blank\" style=\"font-size:small;\">[file an aggregate bug]</a>"
|
58
|
+
end
|
59
|
+
|
60
|
+
def bugzilla_link(report)
|
61
|
+
return "" unless settings.config.bugzilla_config
|
62
|
+
|
63
|
+
# info should have host, cluster, report_time
|
64
|
+
url = settings.config.bugzilla_config[:bugzilla_url]
|
65
|
+
h_url = settings.config.bugzilla_config[:hostlint_url]
|
66
|
+
desc = "[hostlint ##{report.hostlint_id}] " +
|
67
|
+
"#{report.host}.#{report.cluster}: #{report.name}"
|
68
|
+
fields = { :short_desc => desc,
|
69
|
+
:comment => "hostlint link: #{h_url}/report/#{report.name}##{report.hostlint_id}
|
70
|
+
#{report.body}",
|
71
|
+
:keyword => ""
|
72
|
+
}
|
73
|
+
url_parts = []
|
74
|
+
fields.each do |k, v|
|
75
|
+
[v].flatten.each do |v2|
|
76
|
+
url_parts << "#{URI.escape(k.to_s)}=#{URI.escape(v2.to_s)}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
url += "&" + url_parts.join("&")
|
80
|
+
"<a href=\"#{url}\" target=\"_blank\" style=\"font-size:small;\">file a bug</a>"
|
81
|
+
end
|
82
|
+
|
83
|
+
def bugzilla_search_link(check)
|
84
|
+
return "" unless settings.config.bugzilla_config
|
85
|
+
|
86
|
+
url = settings.config.bugzilla_config[:bugzilla_search_url]
|
87
|
+
desc = "[hostlint ##{check.hostlint_id}] " +
|
88
|
+
"#{check.host}.#{check.cluster}: #{check.name}"
|
89
|
+
fields = { :short_desc => desc }
|
90
|
+
url_parts = []
|
91
|
+
fields.each do |k, v|
|
92
|
+
[v].flatten.each do |v2|
|
93
|
+
url_parts << "#{URI.escape(k.to_s)}=#{URI.escape(v2.to_s)}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
url += "&" + url_parts.join("&")
|
97
|
+
"<a href=\"#{url}\" target=\"_blank\" style=\"font-size:small;\">search</a>"
|
98
|
+
end
|
99
|
+
|
100
|
+
# when single cluster view, don't display cluster in hostname
|
101
|
+
def hostlink(host, single=false)
|
102
|
+
str = "<a href=\"/host/#{host.cluster}/#{host}\">#{host}"
|
103
|
+
str << ".#{host.cluster}" unless single
|
104
|
+
str << "</a>"
|
105
|
+
end
|
106
|
+
|
107
|
+
def checklink(check)
|
108
|
+
"<a href=\"/check/#{check}\">#{check}</a>"
|
109
|
+
end
|
110
|
+
|
111
|
+
def hosts_selector(hosts)
|
112
|
+
@hosts = hosts
|
113
|
+
erb :'partials/hosts_selector', :layout => false
|
114
|
+
end
|
115
|
+
|
116
|
+
def status_selector()
|
117
|
+
erb :'partials/status_selector', :layout => false
|
118
|
+
end
|
119
|
+
|
120
|
+
def stats_helper(check)
|
121
|
+
total = ok = failed = check_failed = 0
|
122
|
+
Check.find(check).host_map.each do |h, r|
|
123
|
+
r = r.last
|
124
|
+
total += 1
|
125
|
+
if r.ok?
|
126
|
+
ok += 1
|
127
|
+
elsif r.failed?
|
128
|
+
failed += 1
|
129
|
+
else
|
130
|
+
check_failed += 1
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
ol = append_query_string("/check/#{check}/#{Host::OK}")
|
135
|
+
fl = append_query_string("/check/#{check}/#{Host::FAIL}")
|
136
|
+
cfl = append_query_string("/check/#{check}/#{Host::EXEC_FAIL}")
|
137
|
+
|
138
|
+
"<span><a style=\"color:green\" href=\"#{ol}\">#{ok}</a></span>" +
|
139
|
+
"/<span><a style=\"color:red\" href=\"#{fl}\">#{failed}</a></span>" +
|
140
|
+
"/<span><a style=\"color:orange\" href=\"#{cfl}\">#{check_failed}</a></span>" +
|
141
|
+
" <span>(#{total})</span>"
|
142
|
+
end
|
143
|
+
|
144
|
+
# fixme de-duplication
|
145
|
+
def host_helper(host)
|
146
|
+
ok = host.succeeding.size
|
147
|
+
failed = host.failing.size
|
148
|
+
check_failed = host.checks_failing.size
|
149
|
+
total = ok + failed + check_failed
|
150
|
+
if failed + check_failed != 0
|
151
|
+
|
152
|
+
ol = append_query_string("/host/#{host.cluster}/#{host}/#{Host::OK}")
|
153
|
+
fl = append_query_string("/host/#{host.cluster}/#{host}/#{Host::FAIL}")
|
154
|
+
cfl = append_query_string("/host/#{host.cluster}/#{host}/#{Host::EXEC_FAIL}")
|
155
|
+
|
156
|
+
"<span><a style=\"color:green\" href=\"#{ol}\">#{ok}</a></span>" +
|
157
|
+
"/<span><a style=\"color:red\" href=\"#{fl}\">#{failed}</a></span>" +
|
158
|
+
"/<span><a style=\"color:orange\" href=\"#{cfl}\">#{check_failed}</a></span>" +
|
159
|
+
" <span>(#{total})</span>"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_status_to_hosts_map
|
164
|
+
bucket = {}
|
165
|
+
@hosts.each do |h|
|
166
|
+
type = @status == Host::OK ? :checks_succeeding : :checks_failing
|
167
|
+
h.send(type).each do |c|
|
168
|
+
bucket[c.name] ||= []
|
169
|
+
bucket[c.name] << h
|
170
|
+
end
|
171
|
+
end
|
172
|
+
bucket
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Hostmon::Models
|
2
|
+
# fixme define [] for find
|
3
|
+
class Base
|
4
|
+
@@objects = Hash.new { |h, k| h[k] = Hash.new }
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name, params={})
|
8
|
+
@name = name
|
9
|
+
@params = params
|
10
|
+
@@objects[self.class.to_s][name] = self
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(name)
|
14
|
+
return @@objects[self.name][name] rescue []
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.each(&block)
|
18
|
+
h = @@objects[self.name] rescue {}
|
19
|
+
h.sort.each { |k, v| yield(k, v) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.all
|
23
|
+
return @@objects[self.name].values.sort
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
return @params[key] rescue []
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
return @name
|
32
|
+
end
|
33
|
+
|
34
|
+
def <=>(other)
|
35
|
+
return to_s <=> other.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
end # Hostmon::Models::Base
|
39
|
+
end # Hostmon::Models
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Hostmon::Models
|
2
|
+
class Check < Base
|
3
|
+
attr_reader :name
|
4
|
+
attr_accessor :host_map
|
5
|
+
|
6
|
+
def self.absorb (name, host)
|
7
|
+
unless c = find(name)
|
8
|
+
c = new(name)
|
9
|
+
end
|
10
|
+
c.host_map[host] = host.check_reports(name)
|
11
|
+
c
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(name)
|
15
|
+
super(name)
|
16
|
+
@host_map = {} #Host => reports
|
17
|
+
end
|
18
|
+
|
19
|
+
def host_status
|
20
|
+
ok = []
|
21
|
+
failed = []
|
22
|
+
check_failed = []
|
23
|
+
@host_map.each do |h, r|
|
24
|
+
if r.last.ok?
|
25
|
+
ok << [h, r.last]
|
26
|
+
elsif r.last.failed?
|
27
|
+
failed << [h, r.last]
|
28
|
+
else
|
29
|
+
check_failed << [h, r.last]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return ok, failed, check_failed
|
33
|
+
end
|
34
|
+
|
35
|
+
def hosts_ok
|
36
|
+
host_status[0] # .map(&:first)
|
37
|
+
end
|
38
|
+
def hosts_failing
|
39
|
+
host_status[1] # .map(&:first)
|
40
|
+
end
|
41
|
+
def hosts_check_failing
|
42
|
+
host_status[2] # .map(&:first)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require "hostmon/models/base"
|
2
|
+
|
3
|
+
module Hostmon::Models
|
4
|
+
class Host < Base
|
5
|
+
OK = "OK"
|
6
|
+
FAIL = "FAIL"
|
7
|
+
EXEC_FAIL = "EXEC_FAIL"
|
8
|
+
def self.statuses
|
9
|
+
[OK, FAIL, EXEC_FAIL]
|
10
|
+
end
|
11
|
+
|
12
|
+
@@clusters = Set.new
|
13
|
+
|
14
|
+
@@saved_reports = 1
|
15
|
+
def self.saved_reports
|
16
|
+
@@saved_reports
|
17
|
+
end
|
18
|
+
def self.saved_reports= (i)
|
19
|
+
@@saved_reports = i
|
20
|
+
end
|
21
|
+
|
22
|
+
@@checks = Set.new
|
23
|
+
@@check_map = {}
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def clusters # attr_*
|
27
|
+
@@clusters
|
28
|
+
end
|
29
|
+
def hosts_failing(check)
|
30
|
+
@@check_map[check][FAIL]||Set.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def hosts_succeeding(check)
|
34
|
+
@@check_map[check][OK]||Set.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_map
|
38
|
+
@@check_map
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_by_name_and_cluster(name, cluster)
|
42
|
+
Host.each do |host_name, host|
|
43
|
+
next unless host.name == name
|
44
|
+
return host if host.cluster == cluster
|
45
|
+
end
|
46
|
+
return nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_by_cluster(cluster)
|
50
|
+
ret = []
|
51
|
+
Host.each do |name, host|
|
52
|
+
ret << host if host.cluster == cluster
|
53
|
+
end
|
54
|
+
return ret
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :hostname, :checks, :cluster, :status_map, :report
|
59
|
+
attr_accessor :reports, :report_time
|
60
|
+
|
61
|
+
def checks
|
62
|
+
@reports.map(&:first)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# return reports for checks that the host passes
|
67
|
+
def succeeding
|
68
|
+
ok_reports = Set.new
|
69
|
+
@reports.each do |n, r|
|
70
|
+
if r.last.ok?
|
71
|
+
ok_reports << r.last
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ok_reports.sort
|
75
|
+
end
|
76
|
+
|
77
|
+
# return reports for checks that the host fails
|
78
|
+
def failing
|
79
|
+
failing_reports = Set.new
|
80
|
+
@reports.each do |n, r|
|
81
|
+
if r.last.failed?
|
82
|
+
failing_reports << r.last
|
83
|
+
end
|
84
|
+
end
|
85
|
+
failing_reports.sort
|
86
|
+
end
|
87
|
+
|
88
|
+
# return reports for checks that failed to execute properly
|
89
|
+
def checks_failing
|
90
|
+
failing = Set.new
|
91
|
+
@reports.each do |n, r|
|
92
|
+
if r.last.check_failed?
|
93
|
+
failing << r.last
|
94
|
+
end
|
95
|
+
end
|
96
|
+
failing.sort
|
97
|
+
end
|
98
|
+
|
99
|
+
# hacks
|
100
|
+
def to_s
|
101
|
+
@hostname
|
102
|
+
end
|
103
|
+
|
104
|
+
def name
|
105
|
+
@hostname
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize(h, c)
|
109
|
+
# needed to disambiguate
|
110
|
+
super(h+'.'+c)
|
111
|
+
@hostname = h
|
112
|
+
@cluster = c
|
113
|
+
@report_time = nil
|
114
|
+
end
|
115
|
+
|
116
|
+
def key
|
117
|
+
"#{@cluster}#{@name}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def eql?(other)
|
121
|
+
key == other.key
|
122
|
+
end
|
123
|
+
|
124
|
+
def ==(other)
|
125
|
+
key == other.key
|
126
|
+
end
|
127
|
+
|
128
|
+
# fixme this is just silly
|
129
|
+
def sname
|
130
|
+
@hostname + "." + @cluster
|
131
|
+
end
|
132
|
+
|
133
|
+
# fixme @params is always empty right now
|
134
|
+
def <=>(other)
|
135
|
+
if @params[:host_sort] == "builtin"
|
136
|
+
return key <=> other.key
|
137
|
+
elsif @params[:host_sort] == "numeric"
|
138
|
+
regexp = /\d+/
|
139
|
+
match = @name.match(regexp)
|
140
|
+
match2 = other.name.match(regexp)
|
141
|
+
if match.pre_match != match2.pre_match
|
142
|
+
return match.pre_match <=> match2.pre_match
|
143
|
+
else
|
144
|
+
return match[0].to_i <=> match2[0].to_i
|
145
|
+
end
|
146
|
+
else
|
147
|
+
# http://www.bofh.org.uk/2007/12/16/comprehensible-sorting-in-ruby
|
148
|
+
sensible = lambda do |k|
|
149
|
+
k.sname.split(
|
150
|
+
/((?:(?:^|\s)[-+])?(?:\.\d+|\d+(?:\.\d+?(?:[eE]\d+)?(?:$|(?![eE\.])))?))/ms
|
151
|
+
).map { |v| Float(v) rescue v.downcase }
|
152
|
+
end
|
153
|
+
return sensible.call(self) <=> sensible.call(other)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def hash
|
158
|
+
key.hash
|
159
|
+
end
|
160
|
+
|
161
|
+
# process and update (or create) a host and return it
|
162
|
+
# fixme saved_reports unbounded
|
163
|
+
# fixme special case for 0 (only store in memory)
|
164
|
+
def self.absorb(report)
|
165
|
+
h = report.host
|
166
|
+
c = report.cluster
|
167
|
+
unless host = find_by_name_and_cluster(h, c)
|
168
|
+
host = new(h, c)
|
169
|
+
puts "new host #{h}"
|
170
|
+
end
|
171
|
+
host.reports ||= Hash.new {|hsh,k| hsh[k] = Array.new}
|
172
|
+
|
173
|
+
# fixme slightly offensive
|
174
|
+
if host.reports[report.name].size < @@saved_reports
|
175
|
+
host.reports[report.name] << report
|
176
|
+
host.reports[report.name].sort! {|a,b| a.timestamp <=> b.timestamp }
|
177
|
+
report.write
|
178
|
+
elsif report.timestamp < host.reports[report.name].first.timestamp
|
179
|
+
return host
|
180
|
+
else
|
181
|
+
pp host.reports[report.name].size
|
182
|
+
pp @@saved_reports
|
183
|
+
host.reports[report.name] << report
|
184
|
+
host.reports[report.name].sort! {|a,b| a.timestamp <=> b.timestamp }
|
185
|
+
while host.reports[report.name].size > @@saved_reports
|
186
|
+
shift = host.reports[report.name].shift
|
187
|
+
shift.delete
|
188
|
+
end
|
189
|
+
report.write
|
190
|
+
end
|
191
|
+
####################
|
192
|
+
|
193
|
+
time = report.timestamp
|
194
|
+
if (!host.report_time) || (host.report_time < time)
|
195
|
+
host.report_time = time
|
196
|
+
end
|
197
|
+
@@clusters << host.cluster
|
198
|
+
host
|
199
|
+
end
|
200
|
+
|
201
|
+
def check_reports(check_name)
|
202
|
+
reports[check_name]
|
203
|
+
end
|
204
|
+
|
205
|
+
# temporary
|
206
|
+
def inspect
|
207
|
+
@hostname
|
208
|
+
end
|
209
|
+
|
210
|
+
end # Hostmon::Models::Host
|
211
|
+
end # Hostmon::Models
|