riemann-dash 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/riemann/dash/controller/index.rb +46 -1
- data/lib/riemann/dash/public/dash.js +6 -3
- data/lib/riemann/dash/public/persistence.js +2 -2
- data/lib/riemann/dash/public/subs.js +117 -12
- data/lib/riemann/dash/public/toastr.css +174 -0
- data/lib/riemann/dash/public/toastr.js +207 -0
- data/lib/riemann/dash/public/util.js +31 -0
- data/lib/riemann/dash/public/views/gauge.js +4 -4
- data/lib/riemann/dash/public/views/grid.js +11 -11
- data/lib/riemann/dash/public/views/title.js +4 -2
- data/lib/riemann/dash/version.rb +1 -1
- data/lib/riemann/dash/views/css.scss +83 -57
- data/lib/riemann/dash/views/index.erubis +200 -6
- data/lib/riemann/dash.rb +7 -38
- metadata +35 -66
- data/lib/riemann/dash/controller/websockets.rb +0 -50
- data/lib/riemann/dash/helper/renderer.rb +0 -266
- data/lib/riemann/dash/views/websockets.erubis +0 -201
data/lib/riemann/dash.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'riemann/client'
|
3
2
|
require 'sinatra/base'
|
4
3
|
|
5
4
|
module Riemann
|
@@ -13,24 +12,11 @@ module Riemann
|
|
13
12
|
|
14
13
|
def self.config
|
15
14
|
@config ||= {
|
16
|
-
:client => {},
|
17
|
-
:age_scale => 60 * 30,
|
18
|
-
:state_order => {
|
19
|
-
'critical' => 3,
|
20
|
-
'warning' => 2,
|
21
|
-
'ok' => 1
|
22
|
-
},
|
23
|
-
:strftime => '%H:%M:%S',
|
24
15
|
:controllers => [File.join(File.dirname(__FILE__), 'dash', 'controller')],
|
25
|
-
:helpers => [File.join(File.dirname(__FILE__), 'dash', 'helper')],
|
26
16
|
:views => File.join(File.dirname(__FILE__), 'dash', 'views')
|
27
17
|
}
|
28
18
|
end
|
29
19
|
|
30
|
-
def self.client
|
31
|
-
@client ||= Riemann::Client.new(config[:client])
|
32
|
-
end
|
33
|
-
|
34
20
|
def self.load(filename)
|
35
21
|
unless load_config(filename || 'config.rb')
|
36
22
|
# Configuration failed; load a default view.
|
@@ -38,7 +24,6 @@ module Riemann
|
|
38
24
|
end
|
39
25
|
|
40
26
|
config[:controllers].each { |d| load_controllers d }
|
41
|
-
config[:helpers].each { |d| load_helpers d }
|
42
27
|
set :views, File.expand_path(config[:views])
|
43
28
|
|
44
29
|
# Fallback pub dir
|
@@ -55,12 +40,13 @@ module Riemann
|
|
55
40
|
end
|
56
41
|
end
|
57
42
|
|
58
|
-
# Load controllers.
|
59
|
-
# Controllers can be regular old one-file-per-class, but
|
60
|
-
# more modularity, this method will allow you to
|
61
|
-
# in their own files. For example, get
|
62
|
-
# controller/posts/_/edit.rb. The sorting
|
63
|
-
# files in the correct order to handle
|
43
|
+
# Load controllers.
|
44
|
+
# Controllers can be regular old one-file-per-class, but
|
45
|
+
# if you prefer a little more modularity, this method will allow you to
|
46
|
+
# define all controller methods in their own files. For example, get
|
47
|
+
# "/posts/*/edit" can live in controller/posts/_/edit.rb. The sorting
|
48
|
+
# system provided here requires files in the correct order to handle
|
49
|
+
# wildcards appropriately.
|
64
50
|
def self.load_controllers(dir)
|
65
51
|
rbs = []
|
66
52
|
Find.find(
|
@@ -104,27 +90,10 @@ module Riemann
|
|
104
90
|
end
|
105
91
|
end
|
106
92
|
|
107
|
-
# Load helpers
|
108
|
-
def self.load_helpers(dir)
|
109
|
-
Find.find(
|
110
|
-
File.expand_path(dir)
|
111
|
-
) do |path|
|
112
|
-
require path if path =~ /\.rb$/
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
93
|
# Add an additional public directory.
|
117
94
|
def self.public_dir(dir)
|
118
95
|
require 'riemann/dash/rack/static'
|
119
96
|
use Riemann::Dash::Static, :root => dir
|
120
97
|
end
|
121
|
-
|
122
|
-
def client
|
123
|
-
self.class.client
|
124
|
-
end
|
125
|
-
|
126
|
-
def query(*a)
|
127
|
-
self.class.client.query(*a).events || []
|
128
|
-
end
|
129
98
|
end
|
130
99
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riemann-dash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: riemann-client
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &11919920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,15 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.0.7
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 0.0.7
|
24
|
+
version_requirements: *11919920
|
30
25
|
- !ruby/object:Gem::Dependency
|
31
26
|
name: erubis
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &11918520 !ruby/object:Gem::Requirement
|
33
28
|
none: false
|
34
29
|
requirements:
|
35
30
|
- - ! '>='
|
@@ -37,15 +32,10 @@ dependencies:
|
|
37
32
|
version: 2.7.0
|
38
33
|
type: :runtime
|
39
34
|
prerelease: false
|
40
|
-
version_requirements:
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: 2.7.0
|
35
|
+
version_requirements: *11918520
|
46
36
|
- !ruby/object:Gem::Dependency
|
47
37
|
name: sinatra
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &11917660 !ruby/object:Gem::Requirement
|
49
39
|
none: false
|
50
40
|
requirements:
|
51
41
|
- - ! '>='
|
@@ -53,15 +43,10 @@ dependencies:
|
|
53
43
|
version: 1.3.2
|
54
44
|
type: :runtime
|
55
45
|
prerelease: false
|
56
|
-
version_requirements:
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 1.3.2
|
46
|
+
version_requirements: *11917660
|
62
47
|
- !ruby/object:Gem::Dependency
|
63
48
|
name: sass
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirement: &11916360 !ruby/object:Gem::Requirement
|
65
50
|
none: false
|
66
51
|
requirements:
|
67
52
|
- - ! '>='
|
@@ -69,15 +54,10 @@ dependencies:
|
|
69
54
|
version: 3.1.14
|
70
55
|
type: :runtime
|
71
56
|
prerelease: false
|
72
|
-
version_requirements:
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ! '>='
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: 3.1.14
|
57
|
+
version_requirements: *11916360
|
78
58
|
- !ruby/object:Gem::Dependency
|
79
59
|
name: thin
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirement: &11914740 !ruby/object:Gem::Requirement
|
81
61
|
none: false
|
82
62
|
requirements:
|
83
63
|
- - ! '>='
|
@@ -85,28 +65,18 @@ dependencies:
|
|
85
65
|
version: 1.3.1
|
86
66
|
type: :runtime
|
87
67
|
prerelease: false
|
88
|
-
version_requirements:
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: 1.3.1
|
68
|
+
version_requirements: *11914740
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: multi_json
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirement: &11540560 !ruby/object:Gem::Requirement
|
97
72
|
none: false
|
98
73
|
requirements:
|
99
|
-
- -
|
74
|
+
- - =
|
100
75
|
- !ruby/object:Gem::Version
|
101
76
|
version: 1.3.6
|
102
77
|
type: :runtime
|
103
78
|
prerelease: false
|
104
|
-
version_requirements:
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - '='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: 1.3.6
|
79
|
+
version_requirements: *11540560
|
110
80
|
description:
|
111
81
|
email: aphyr@aphyr.com
|
112
82
|
executables:
|
@@ -115,38 +85,37 @@ extensions: []
|
|
115
85
|
extra_rdoc_files: []
|
116
86
|
files:
|
117
87
|
- lib/riemann/dash.rb
|
118
|
-
- lib/riemann/dash/
|
119
|
-
- lib/riemann/dash/public/
|
120
|
-
- lib/riemann/dash/public/
|
121
|
-
- lib/riemann/dash/public/toolbar.js
|
122
|
-
- lib/riemann/dash/public/subs.js
|
123
|
-
- lib/riemann/dash/public/underscore-min.js
|
88
|
+
- lib/riemann/dash/rack/static.rb
|
89
|
+
- lib/riemann/dash/public/format.js
|
90
|
+
- lib/riemann/dash/public/view.js
|
124
91
|
- lib/riemann/dash/public/jquery-1.7.2.min.js
|
92
|
+
- lib/riemann/dash/public/mustache.js
|
125
93
|
- lib/riemann/dash/public/x.png
|
126
|
-
- lib/riemann/dash/public/
|
127
|
-
- lib/riemann/dash/public/
|
94
|
+
- lib/riemann/dash/public/util.js
|
95
|
+
- lib/riemann/dash/public/jquery-ui-1.9.0.custom.min.js
|
96
|
+
- lib/riemann/dash/public/underscore-min.js
|
97
|
+
- lib/riemann/dash/public/persistence.js
|
98
|
+
- lib/riemann/dash/public/subs.js
|
99
|
+
- lib/riemann/dash/public/jquery.simplemodal.1.4.3.min.js
|
128
100
|
- lib/riemann/dash/public/views/help.js
|
129
|
-
- lib/riemann/dash/public/views/title.js
|
130
101
|
- lib/riemann/dash/public/views/grid.js
|
102
|
+
- lib/riemann/dash/public/views/title.js
|
131
103
|
- lib/riemann/dash/public/views/gauge.js
|
132
|
-
- lib/riemann/dash/public/jquery.
|
104
|
+
- lib/riemann/dash/public/jquery.quickfit.js
|
105
|
+
- lib/riemann/dash/public/toastr.js
|
106
|
+
- lib/riemann/dash/public/toolbar.js
|
107
|
+
- lib/riemann/dash/public/toastr.css
|
133
108
|
- lib/riemann/dash/public/dash.js
|
134
|
-
- lib/riemann/dash/public/format.js
|
135
109
|
- lib/riemann/dash/public/profile.js
|
136
|
-
- lib/riemann/dash/public/mustache.js
|
137
|
-
- lib/riemann/dash/public/persistence.js
|
138
|
-
- lib/riemann/dash/public/util.js
|
139
110
|
- lib/riemann/dash/public/clock.js
|
140
111
|
- lib/riemann/dash/public/jquery.json-2.2.min.js
|
141
|
-
- lib/riemann/dash/
|
112
|
+
- lib/riemann/dash/public/keys.js
|
113
|
+
- lib/riemann/dash/version.rb
|
142
114
|
- lib/riemann/dash/controller/index.rb
|
143
|
-
- lib/riemann/dash/controller/
|
115
|
+
- lib/riemann/dash/controller/css.rb
|
116
|
+
- lib/riemann/dash/views/css.scss
|
144
117
|
- lib/riemann/dash/views/layout.erubis
|
145
118
|
- lib/riemann/dash/views/index.erubis
|
146
|
-
- lib/riemann/dash/views/css.scss
|
147
|
-
- lib/riemann/dash/views/websockets.erubis
|
148
|
-
- lib/riemann/dash/helper/renderer.rb
|
149
|
-
- lib/riemann/dash/rack/static.rb
|
150
119
|
- bin/riemann-dash
|
151
120
|
- LICENSE
|
152
121
|
- README.markdown
|
@@ -170,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
139
|
version: '0'
|
171
140
|
requirements: []
|
172
141
|
rubyforge_project: riemann-dash
|
173
|
-
rubygems_version: 1.8.
|
142
|
+
rubygems_version: 1.8.10
|
174
143
|
signing_key:
|
175
144
|
specification_version: 3
|
176
145
|
summary: HTTP dashboard for the distributed event system Riemann.
|
@@ -1,50 +0,0 @@
|
|
1
|
-
class Riemann::Dash
|
2
|
-
require 'multi_json'
|
3
|
-
require 'fileutils'
|
4
|
-
require 'set'
|
5
|
-
|
6
|
-
WS_CONFIG_FILE = "ws/config.json"
|
7
|
-
|
8
|
-
get '/ws' do
|
9
|
-
erb :websockets, :layout => false
|
10
|
-
end
|
11
|
-
|
12
|
-
get '/ws/config', :provides => 'json' do
|
13
|
-
if File.exists? WS_CONFIG_FILE
|
14
|
-
send_file WS_CONFIG_FILE, :type => :json
|
15
|
-
else
|
16
|
-
MultiJson.encode({})
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
post '/ws/config' do
|
21
|
-
# Read update
|
22
|
-
request.body.rewind
|
23
|
-
update = MultiJson.decode(request.body.read)
|
24
|
-
|
25
|
-
# Read old config
|
26
|
-
if File.exists? WS_CONFIG_FILE
|
27
|
-
old = MultiJson.decode File.read WS_CONFIG_FILE
|
28
|
-
else
|
29
|
-
old = {}
|
30
|
-
end
|
31
|
-
|
32
|
-
new = {}
|
33
|
-
|
34
|
-
# Server
|
35
|
-
new['server'] = update['server'] or old['server']
|
36
|
-
|
37
|
-
p update['workspaces']
|
38
|
-
new['workspaces'] = update['workspaces'] or old['workspaces']
|
39
|
-
|
40
|
-
# Save new config
|
41
|
-
FileUtils.mkdir_p 'ws'
|
42
|
-
File.open(WS_CONFIG_FILE, 'w') do |f|
|
43
|
-
f.write(MultiJson.encode(new))
|
44
|
-
end
|
45
|
-
|
46
|
-
# Return current config
|
47
|
-
content_type "application/json"
|
48
|
-
MultiJson.encode(new)
|
49
|
-
end
|
50
|
-
end
|
@@ -1,266 +0,0 @@
|
|
1
|
-
module Riemann
|
2
|
-
class Dash
|
3
|
-
helpers do
|
4
|
-
include ::Rack::Utils
|
5
|
-
|
6
|
-
alias_method :h, :escape_html
|
7
|
-
|
8
|
-
# Returns a scalar factor from 0.2 to 1, where 0.2 is "on the order of
|
9
|
-
# age_scale ago", and 1 is "very recent"
|
10
|
-
def age_fraction(time)
|
11
|
-
return 1 if time.nil?
|
12
|
-
|
13
|
-
x = 1 - ((Time.now.to_f - time) / Dash.config[:age_scale])
|
14
|
-
if x < 0.2
|
15
|
-
0.2
|
16
|
-
elsif x > 1
|
17
|
-
1
|
18
|
-
else
|
19
|
-
x
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Finds the longest common prefix of a list of strings.
|
24
|
-
# i.e. 'abc, 'ab', 'abdf' => 'ab'
|
25
|
-
def longest_common_prefix(strings, prefix = '')
|
26
|
-
return strings.first if strings.size <= 1
|
27
|
-
|
28
|
-
first = strings[0][0,1] or return prefix
|
29
|
-
tails = strings[1..-1].inject([strings[0][1..-1]]) do |tails, string|
|
30
|
-
if string[0,1] != first
|
31
|
-
return prefix
|
32
|
-
else
|
33
|
-
tails << string[1..-1]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
longest_common_prefix(tails, prefix + first)
|
38
|
-
end
|
39
|
-
|
40
|
-
# An overview of states
|
41
|
-
def state_list(states)
|
42
|
-
ul(states.map { |s| state_short s })
|
43
|
-
end
|
44
|
-
|
45
|
-
def state_grid(states = Dash.client.query)
|
46
|
-
h2('States by Host') +
|
47
|
-
table(
|
48
|
-
*Event.partition(states, :host).map do |host, states|
|
49
|
-
tr(
|
50
|
-
th(host, :class => 'host'),
|
51
|
-
*Event.sort(states, :service).map do |state|
|
52
|
-
state_short state
|
53
|
-
end
|
54
|
-
)
|
55
|
-
end
|
56
|
-
)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Renders a state as the given HTML tag with a % width corresponding to
|
60
|
-
# metric / max.
|
61
|
-
def state_bar(s, opts = {})
|
62
|
-
opts = {:tag => 'div', :max => 1}.merge opts
|
63
|
-
|
64
|
-
return '' unless s
|
65
|
-
x = s.metric
|
66
|
-
|
67
|
-
# Text
|
68
|
-
text = case x
|
69
|
-
when Float
|
70
|
-
'%.2f' % x
|
71
|
-
when Integer
|
72
|
-
x.to_s
|
73
|
-
else
|
74
|
-
s.state || '?'
|
75
|
-
end
|
76
|
-
|
77
|
-
# Size
|
78
|
-
size = case x
|
79
|
-
when 0
|
80
|
-
0
|
81
|
-
when nil
|
82
|
-
100
|
83
|
-
else
|
84
|
-
begin
|
85
|
-
x * 100 / opts[:max]
|
86
|
-
rescue ZeroDivisionError
|
87
|
-
0
|
88
|
-
end
|
89
|
-
end
|
90
|
-
size = "%.2f" % size
|
91
|
-
|
92
|
-
time = Time.at(s.time).strftime(Dash.config[:strftime])
|
93
|
-
|
94
|
-
tag opts[:tag], h(text),
|
95
|
-
:class => "state #{s.state}",
|
96
|
-
:style => "opacity: #{age_fraction s.time}; width: #{size}%",
|
97
|
-
:title => "#{s.state}\n#{s.description}\n\n(at #{time})"
|
98
|
-
end
|
99
|
-
|
100
|
-
# Renders a set of states in a chart. Each row is a given host, each
|
101
|
-
# service is a column. Each state is shown as a bar with an inferred
|
102
|
-
# maximum for the entire service, so you can readily compare multiple
|
103
|
-
# hosts.
|
104
|
-
#
|
105
|
-
# Takes a a set of states and options:
|
106
|
-
# title: the title of the chart. Inferred to be the longest common
|
107
|
-
# prefix of all services.
|
108
|
-
# maxima: maps each service to the maximum value used to display its
|
109
|
-
# bar.
|
110
|
-
# service_names: maps each service to a friendly name. Default service
|
111
|
-
# names have common prefixes removed.
|
112
|
-
# hosts: an array of hosts for rows. Default is every host present in
|
113
|
-
# states, sorted.
|
114
|
-
# transpose: Hosts go across, services go down. Enables :global_maxima.
|
115
|
-
# global_maximum: Compute default maxima for services globally,
|
116
|
-
# instead of a different maximum for each service.
|
117
|
-
def state_chart(states, opts = {})
|
118
|
-
o = {
|
119
|
-
:maxima => {},
|
120
|
-
:service_names => {}
|
121
|
-
}.merge opts
|
122
|
-
if o[:transpose] and not o.include?(:global_maximum)
|
123
|
-
o[:global_maximum] = true
|
124
|
-
end
|
125
|
-
|
126
|
-
# Get all services
|
127
|
-
services = states.map { |s| s.service }.compact.uniq.sort
|
128
|
-
|
129
|
-
# Figure out what name to use for each service.
|
130
|
-
prefix = longest_common_prefix services
|
131
|
-
service_names = services.inject({}) do |names, service|
|
132
|
-
names[service] = service[prefix.length..-1]
|
133
|
-
names
|
134
|
-
end.merge o[:service_names]
|
135
|
-
|
136
|
-
# Compute maximum for each service
|
137
|
-
maxima = if o[:global_maximum]
|
138
|
-
max = states.map(&:metric).compact.max
|
139
|
-
services.inject({}) do |m, s|
|
140
|
-
m[s] = max
|
141
|
-
m
|
142
|
-
end.merge o[:maxima]
|
143
|
-
else
|
144
|
-
states.inject(Hash.new(0)) do |m, s|
|
145
|
-
if s.metric && !(s.metric.nan?)
|
146
|
-
m[s.service] = [s.metric, m[s.service]].max
|
147
|
-
end
|
148
|
-
m
|
149
|
-
end.merge o[:maxima]
|
150
|
-
end
|
151
|
-
|
152
|
-
# Compute union of all hosts for these states, if no
|
153
|
-
# list of hosts explicitly given.
|
154
|
-
hosts = o[:hosts] || states.map do |state|
|
155
|
-
state.host
|
156
|
-
end
|
157
|
-
hosts = hosts.uniq.sort { |a, b|
|
158
|
-
if !a
|
159
|
-
-1
|
160
|
-
elsif !b
|
161
|
-
1
|
162
|
-
else
|
163
|
-
a <=> b
|
164
|
-
end
|
165
|
-
}
|
166
|
-
|
167
|
-
# Construct index
|
168
|
-
by = states.inject({}) do |index, s|
|
169
|
-
index[[s.host, s.service]] = s
|
170
|
-
index
|
171
|
-
end
|
172
|
-
|
173
|
-
# Title
|
174
|
-
title = o[:title] || prefix.capitalize rescue 'Unknown'
|
175
|
-
|
176
|
-
if o[:transpose]
|
177
|
-
h2(title) +
|
178
|
-
table(
|
179
|
-
tr(
|
180
|
-
th,
|
181
|
-
*hosts.map do |host|
|
182
|
-
th host
|
183
|
-
end
|
184
|
-
),
|
185
|
-
*services.map do |service|
|
186
|
-
tr(
|
187
|
-
th(service_names[service]),
|
188
|
-
*hosts.map do |host|
|
189
|
-
s = by[[host, service]]
|
190
|
-
td(
|
191
|
-
s ? state_bar(s, :max => maxima[service]) : nil
|
192
|
-
)
|
193
|
-
end
|
194
|
-
)
|
195
|
-
end << {:class => 'chart'} # ruby 1.8.7 this is your fault
|
196
|
-
)
|
197
|
-
else
|
198
|
-
h2(title) +
|
199
|
-
table(
|
200
|
-
tr(
|
201
|
-
th,
|
202
|
-
*services.map do |service|
|
203
|
-
th service_names[service]
|
204
|
-
end
|
205
|
-
),
|
206
|
-
*hosts.map do |host|
|
207
|
-
tr(
|
208
|
-
th(host),
|
209
|
-
*services.map do |service|
|
210
|
-
s = by[[host, service]]
|
211
|
-
td(
|
212
|
-
s ? state_bar(s, :max => maxima[service]) : nil
|
213
|
-
)
|
214
|
-
end
|
215
|
-
)
|
216
|
-
end <<
|
217
|
-
{:class => 'chart'}
|
218
|
-
)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# Renders a state as a short tag.
|
223
|
-
def state_short(s, opts={:tag => 'li'})
|
224
|
-
if s
|
225
|
-
"<#{opts[:tag]} class=\"state #{s.state}\" style=\"opacity: #{age_fraction s.time}\" title=\"#{h s.description}\">#{h s.host} #{h s.service}</#{opts[:tag]}>"
|
226
|
-
else
|
227
|
-
"<#{opts[:tag]} class=\"service\"></#{opts[:tag]}>"
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
# Renders a time to an HTML tag.
|
232
|
-
def time(unix)
|
233
|
-
t = Time.at(unix)
|
234
|
-
"<time datetime=\"#{t.iso8601}\">#{t.strftime(Dash.config[:strftime])}</time>"
|
235
|
-
end
|
236
|
-
|
237
|
-
# Renders an HTML tag
|
238
|
-
def tag(tag, *a)
|
239
|
-
if Hash === a.last
|
240
|
-
opts = a.pop
|
241
|
-
else
|
242
|
-
opts = {}
|
243
|
-
end
|
244
|
-
|
245
|
-
attrs = opts.map do |k,v|
|
246
|
-
"#{k}=\"#{h v}\""
|
247
|
-
end.join ' '
|
248
|
-
|
249
|
-
content = if block_given?
|
250
|
-
a << yield
|
251
|
-
else
|
252
|
-
a
|
253
|
-
end.flatten.join("\n")
|
254
|
-
|
255
|
-
s = "<#{tag} #{attrs}>#{content}</#{tag}>"
|
256
|
-
end
|
257
|
-
|
258
|
-
# Specific tag aliases
|
259
|
-
%w(div span h1 h2 h3 h4 h5 h6 ul ol li table th tr td u i b).each do |tag|
|
260
|
-
class_eval "def #{tag}(*a, &block)
|
261
|
-
tag #{tag.inspect}, *a, &block
|
262
|
-
end"
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|