hostmon 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/bin/hostmon +4 -0
  2. data/examples/config.yml +14 -0
  3. data/examples/reports/bad_exit_status/cluster1/mach1/report_2012-06-28-16:49:32.yaml +11 -0
  4. data/examples/reports/bad_exit_status/cluster2/mach1/report_2012-06-14-15:06:12.yaml +11 -0
  5. data/examples/reports/bad_exit_status/cluster2/mach2/report_2012-06-14-15:06:12.yaml +11 -0
  6. data/examples/reports/foo/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
  7. data/examples/reports/foo/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
  8. data/examples/reports/foo/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
  9. data/examples/reports/missing_prelude/cluster1/mach1/report_2012-06-28-16:49:32.yaml +12 -0
  10. data/examples/reports/missing_prelude/cluster2/mach1/report_2012-06-14-15:06:12.yaml +12 -0
  11. data/examples/reports/missing_prelude/cluster2/mach2/report_2012-06-14-15:06:12.yaml +12 -0
  12. data/examples/reports/network/config/bootproto_dhcp/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
  13. data/examples/reports/network/config/bootproto_dhcp/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
  14. data/examples/reports/network/config/bootproto_dhcp/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
  15. data/examples/reports/network/ethernet_bonded/cluster1/mach1/report_2012-06-28-16:49:32.yaml +31 -0
  16. data/examples/reports/network/ethernet_bonded/cluster2/mach1/report_2012-06-14-15:06:12.yaml +22 -0
  17. data/examples/reports/network/ethernet_bonded/cluster2/mach2/report_2012-06-14-15:06:12.yaml +22 -0
  18. data/examples/reports/nonexec/cluster1/mach1/report_2012-06-28-16:49:32.yaml +10 -0
  19. data/examples/reports/nonexec/cluster2/mach1/report_2012-06-14-15:06:12.yaml +10 -0
  20. data/examples/reports/nonexec/cluster2/mach2/report_2012-06-14-15:06:12.yaml +10 -0
  21. data/examples/reports/yum/badcheck/cluster1/mach1/report_2012-06-28-16:49:32.yaml +13 -0
  22. data/examples/reports/yum/badcheck/cluster2/mach1/report_2012-06-14-15:06:12.yaml +13 -0
  23. data/examples/reports/yum/badcheck/cluster2/mach2/report_2012-06-14-15:06:12.yaml +13 -0
  24. data/lib/hostmon.rb +208 -0
  25. data/lib/hostmon/config.rb +47 -0
  26. data/lib/hostmon/helpers.rb +174 -0
  27. data/lib/hostmon/models.rb +4 -0
  28. data/lib/hostmon/models/base.rb +39 -0
  29. data/lib/hostmon/models/check.rb +45 -0
  30. data/lib/hostmon/models/host.rb +211 -0
  31. data/lib/hostmon/models/report.rb +108 -0
  32. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
  33. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
  34. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_20_333333_1x400.png +0 -0
  35. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_40_000000_1x400.png +0 -0
  36. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
  37. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
  38. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_highlight-soft_15_000000_1x100.png +0 -0
  39. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
  40. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-bg_inset-soft_30_ff4e0a_1x100.png +0 -0
  41. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_222222_256x240.png +0 -0
  42. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_4b8e0b_256x240.png +0 -0
  43. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_a83300_256x240.png +0 -0
  44. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_cccccc_256x240.png +0 -0
  45. data/lib/hostmon/public/css/jquery_themes/hostmon/images/ui-icons_ffffff_256x240.png +0 -0
  46. data/lib/hostmon/public/css/jquery_themes/hostmon/jquery-ui-1.8.16.custom.css +568 -0
  47. data/lib/hostmon/public/favicon.ico +0 -0
  48. data/lib/hostmon/public/js/cufon.js +7 -0
  49. data/lib/hostmon/public/js/gotham.font.js +40 -0
  50. data/lib/hostmon/public/js/hostmon.js +89 -0
  51. data/lib/hostmon/public/js/jquery-1.6.2.min.js +18 -0
  52. data/lib/hostmon/public/js/jquery-ui-1.8.16.custom.min.js +791 -0
  53. data/lib/hostmon/public/js/product-design.font.js +8 -0
  54. data/lib/hostmon/public/style.css +311 -0
  55. data/lib/hostmon/rubyfixes.rb +12 -0
  56. data/lib/hostmon/version.rb +3 -0
  57. data/lib/hostmon/views/check.erb +23 -0
  58. data/lib/hostmon/views/check_status.erb +16 -0
  59. data/lib/hostmon/views/cluster.erb +19 -0
  60. data/lib/hostmon/views/host.erb +15 -0
  61. data/lib/hostmon/views/host_status.erb +16 -0
  62. data/lib/hostmon/views/layout.erb +61 -0
  63. data/lib/hostmon/views/partials/check_status_selector.erb +6 -0
  64. data/lib/hostmon/views/partials/host_status_selector.erb +6 -0
  65. data/lib/hostmon/views/partials/hosts_selector.erb +9 -0
  66. data/lib/hostmon/views/partials/report.erb +7 -0
  67. data/lib/hostmon/views/partials/search.erb +18 -0
  68. data/lib/hostmon/views/partials/status_selector.erb +7 -0
  69. data/lib/hostmon/views/search_all.erb +25 -0
  70. data/lib/hostmon/views/search_checks.erb +12 -0
  71. data/lib/hostmon/views/search_host.erb +7 -0
  72. data/lib/hostmon/views/status.erb +15 -0
  73. data/lib/hostmon/views/view.erb +49 -0
  74. 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("&", "&amp;")}"
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 += "&amp;" + url_parts.join("&amp;")
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 += "&amp;" + url_parts.join("&amp;")
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 += "&amp;" + url_parts.join("&amp;")
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,4 @@
1
+ require "hostmon/models/base"
2
+ require "hostmon/models/host"
3
+ require "hostmon/models/check"
4
+ require "hostmon/models/report"
@@ -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