pencil 0.2.10 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/pencil +2 -6
- data/docs/pencil_options.md +3 -1
- data/lib/{config.rb → pencil/config.rb} +29 -9
- data/lib/pencil/config.ru +2 -0
- data/lib/pencil/helpers.rb +211 -0
- data/lib/pencil/models/base.rb +78 -0
- data/lib/pencil/models/dashboard.rb +124 -0
- data/lib/pencil/models/graph.rb +394 -0
- data/lib/pencil/models/host.rb +89 -0
- data/lib/pencil/models.rb +3 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_glass_20_333333_1x400.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_glass_40_000000_1x400.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_highlight-soft_15_000000_1x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-bg_inset-soft_30_ff4e0a_1x100.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-icons_222222_256x240.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-icons_4b8e0b_256x240.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-icons_a83300_256x240.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-icons_cccccc_256x240.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/{public → pencil/public}/css/jquery_themes/pencil/jquery-ui-1.8.16.custom.css +0 -0
- data/lib/{public → pencil/public}/css/thedoc.css +1 -0
- data/lib/{public → pencil/public}/favicon.ico +0 -0
- data/lib/{public → pencil/public}/js/cufon.js +0 -0
- data/lib/{public → pencil/public}/js/gotham.font.js +0 -0
- data/lib/{public → pencil/public}/js/jquery-1.6.2.min.js +0 -0
- data/lib/{public → pencil/public}/js/jquery-ui-1.8.16.custom.min.js +0 -0
- data/lib/{public → pencil/public}/js/pencil.js +0 -0
- data/lib/{public → pencil/public}/js/product-design.font.js +0 -0
- data/lib/pencil/public/style.css +307 -0
- data/lib/{rubyfixes.rb → pencil/rubyfixes.rb} +0 -0
- data/lib/pencil/version.rb +3 -0
- data/lib/{views → pencil/views}/cluster.erb +1 -1
- data/lib/{views → pencil/views}/dash-cluster-zoom.erb +2 -2
- data/lib/{views → pencil/views}/dash-cluster.erb +1 -1
- data/lib/{views → pencil/views}/dash-global-zoom.erb +2 -2
- data/lib/{views → pencil/views}/dash-global.erb +1 -1
- data/lib/{views → pencil/views}/global.erb +1 -1
- data/lib/{views → pencil/views}/host.erb +1 -1
- data/lib/{views → pencil/views}/layout.erb +2 -2
- data/lib/{views → pencil/views}/partials/cluster_selector.erb +0 -0
- data/lib/{views → pencil/views}/partials/cluster_switcher.erb +0 -0
- data/lib/{views → pencil/views}/partials/dash_switcher.erb +0 -0
- data/lib/{views → pencil/views}/partials/graph_switcher.erb +0 -0
- data/lib/{views → pencil/views}/partials/hosts_selector.erb +0 -0
- data/lib/{views → pencil/views}/partials/input_boxes.erb +0 -0
- data/lib/{views → pencil/views}/partials/shortcuts.erb +0 -0
- data/lib/{dash.rb → pencil.rb} +14 -17
- metadata +57 -58
- data/VERSION.rb +0 -1
- data/lib/config.ru +0 -2
- data/lib/helpers.rb +0 -209
- data/lib/models/base.rb +0 -73
- data/lib/models/dashboard.rb +0 -111
- data/lib/models/graph.rb +0 -367
- data/lib/models/host.rb +0 -87
- data/lib/models.rb +0 -3
- data/lib/namespace.rb +0 -4
- data/lib/public/style.css +0 -97
data/lib/helpers.rb
DELETED
@@ -1,209 +0,0 @@
|
|
1
|
-
module Dash::Helpers
|
2
|
-
include Dash::Models
|
3
|
-
|
4
|
-
@@prefs = [["Start Time", "start"],
|
5
|
-
["Duration", "duration"],
|
6
|
-
["Width", "width"],
|
7
|
-
["Height", "height"]]
|
8
|
-
|
9
|
-
# convert keys to symbols before lookup
|
10
|
-
def param_lookup(name)
|
11
|
-
sym_hash = {}
|
12
|
-
session.each { |k,v| sym_hash[k.to_sym] = v unless v.empty? }
|
13
|
-
params.each { |k,v| sym_hash[k.to_sym] = v unless v.empty? }
|
14
|
-
settings.config.global_config[:url_opts].merge(sym_hash)[name.to_sym]
|
15
|
-
end
|
16
|
-
|
17
|
-
def cluster_graph(g, cluster, title="wtf")
|
18
|
-
image_url = \
|
19
|
-
@dash.render_cluster_graph(g, cluster,
|
20
|
-
:title => title,
|
21
|
-
:dynamic_url_opts => merge_opts)
|
22
|
-
zoom_url = cluster_graph_link(@dash, g, cluster)
|
23
|
-
return image_url, zoom_url
|
24
|
-
end
|
25
|
-
|
26
|
-
def cluster_graph_link(dash, g, cluster)
|
27
|
-
link = dash.graph_opts[g]["click"] ||
|
28
|
-
"/dash/#{cluster}/#{dash.name}/#{g.name}"
|
29
|
-
return append_query_string(link)
|
30
|
-
end
|
31
|
-
|
32
|
-
def cluster_zoom_graph(g, cluster, host, title)
|
33
|
-
image_url = g.render_url([host.name], [cluster], :title => title,
|
34
|
-
:dynamic_url_opts => merge_opts)
|
35
|
-
zoom_url = cluster_zoom_link(cluster, host)
|
36
|
-
return image_url, zoom_url
|
37
|
-
end
|
38
|
-
|
39
|
-
def cluster_zoom_link(cluster, host)
|
40
|
-
return append_query_string("/host/#{cluster}/#{host}")
|
41
|
-
end
|
42
|
-
|
43
|
-
def suggest_cluster_links(clusters, g)
|
44
|
-
links = []
|
45
|
-
clusters.each do |c|
|
46
|
-
href = append_query_string("/dash/#{c}/#{params[:dashboard]}/#{g.name}")
|
47
|
-
links << "<a href=\"#{href}\">#{c}</a>"
|
48
|
-
end
|
49
|
-
return "zoom (" + links.join(", ") + ")"
|
50
|
-
end
|
51
|
-
|
52
|
-
def suggest_dashboards_links(host, graph)
|
53
|
-
suggested = suggest_dashboards(host, graph)
|
54
|
-
return "" if suggested.length == 0
|
55
|
-
|
56
|
-
links = []
|
57
|
-
suggested.each do |d|
|
58
|
-
links << "<a href=\"/dash/#{host.cluster}/#{append_query_string(d)}\">" +
|
59
|
-
"#{d}</a>"
|
60
|
-
end
|
61
|
-
return "(" + links.join(", ") + ")"
|
62
|
-
end
|
63
|
-
|
64
|
-
# it's mildly annoying that when this set is empty there're no uplinks
|
65
|
-
# consider adding a link up to the cluster (which is best we can do)
|
66
|
-
def suggest_dashboards(host, graph)
|
67
|
-
ret = Set.new
|
68
|
-
|
69
|
-
host.graphs.each do |g|
|
70
|
-
Dashboard.find_by_graph(g).each do |d|
|
71
|
-
valid, _ = d.get_valid_hosts(g, host['cluster'])
|
72
|
-
ret << d.name if valid.member?(host)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
return ret
|
77
|
-
end
|
78
|
-
|
79
|
-
# generate the input box fields, filled in to current parameters if specified
|
80
|
-
def input_boxes
|
81
|
-
@prefs = @@prefs
|
82
|
-
erb :'partials/input_boxes', :layout => false
|
83
|
-
end
|
84
|
-
|
85
|
-
def dash_link(dash, cluster)
|
86
|
-
return append_query_string("/dash/#{cluster}/#{dash.name}")
|
87
|
-
end
|
88
|
-
|
89
|
-
def cluster_link(cluster)
|
90
|
-
return append_query_string("/dash/#{cluster}")
|
91
|
-
end
|
92
|
-
|
93
|
-
# fixme this isn't used anymore, but should
|
94
|
-
def css_url
|
95
|
-
style = File.join(settings.root, "public/style.css")
|
96
|
-
mtime = File.mtime(style).to_i.to_s
|
97
|
-
return \
|
98
|
-
%Q[<link href="/style.css?#{mtime}" rel="stylesheet" type="text/css">]
|
99
|
-
end
|
100
|
-
|
101
|
-
def refresh
|
102
|
-
if settings.config.global_config[:refresh_rate] != false && nowish
|
103
|
-
rate = settings.config.global_config[:refresh_rate] || 60
|
104
|
-
return %Q[<meta http-equiv="refresh" content="#{rate}">]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def hosts_selector(hosts, print_clusters=false)
|
109
|
-
@print_clusters = print_clusters
|
110
|
-
@hosts = hosts
|
111
|
-
erb :'partials/hosts_selector', :layout => false
|
112
|
-
end
|
113
|
-
|
114
|
-
def append_query_string(str)
|
115
|
-
v = str.dup
|
116
|
-
(v << "?#{request.query_string}") unless request.query_string.empty?
|
117
|
-
return v
|
118
|
-
end
|
119
|
-
|
120
|
-
def merge_opts
|
121
|
-
static_opts = ["cluster", "dashboard", "zoom", "host", "session_id"]
|
122
|
-
opts = params.dup
|
123
|
-
session.merge(opts).delete_if { |k,v| static_opts.member?(k) || v.empty? }
|
124
|
-
end
|
125
|
-
|
126
|
-
def shortcuts(str)
|
127
|
-
@str = str
|
128
|
-
erb :'partials/shortcuts', :layout => false
|
129
|
-
end
|
130
|
-
def cluster_switcher(clusters)
|
131
|
-
@clusters = clusters
|
132
|
-
erb :'partials/cluster_switcher', :layout => false
|
133
|
-
end
|
134
|
-
|
135
|
-
def dash_switcher
|
136
|
-
erb :'partials/dash_switcher', :layout => false
|
137
|
-
end
|
138
|
-
|
139
|
-
def graph_switcher
|
140
|
-
erb :'partials/graph_switcher', :layout => false
|
141
|
-
end
|
142
|
-
|
143
|
-
def cluster_selector
|
144
|
-
@clusters = settings.config.clusters.sort + ["global"]
|
145
|
-
erb :'partials/cluster_selector', :layout => false
|
146
|
-
end
|
147
|
-
|
148
|
-
def host_uplink
|
149
|
-
link = "/dash/#{append_query_string(@host.cluster)}"
|
150
|
-
"zoom out: <a href=\"#{link}\">#{@host.cluster}</a>"
|
151
|
-
end
|
152
|
-
|
153
|
-
def graph_uplink
|
154
|
-
link = append_query_string(request.path.split("/")[0..-2].join("/"))
|
155
|
-
"zoom out: <a href=\"#{link}\">#{@dash}</a>"
|
156
|
-
end
|
157
|
-
|
158
|
-
def dash_uplink
|
159
|
-
link = append_query_string(request.path.split("/")[0..-2].join("/"))
|
160
|
-
"zoom out: <a href=\"#{link}\">#{@params[:cluster]}</a>"
|
161
|
-
end
|
162
|
-
|
163
|
-
# fixme this is a hack
|
164
|
-
def header(str)
|
165
|
-
<<FOO
|
166
|
-
<div class="path_container">
|
167
|
-
<h2>#{@title}</h2>
|
168
|
-
<span class="zoom">
|
169
|
-
#{str}
|
170
|
-
</span>
|
171
|
-
</div>
|
172
|
-
<div id="timeslice_container">
|
173
|
-
<h3 id="timeslice">#{range_string}</h3>
|
174
|
-
#{permalink unless @no_graphs}
|
175
|
-
</div>
|
176
|
-
FOO
|
177
|
-
end
|
178
|
-
|
179
|
-
def nowish
|
180
|
-
if settings.config.global_config[:now_threshold] == false
|
181
|
-
return false
|
182
|
-
end
|
183
|
-
threshold = settings.config.global_config[:now_threshold] || 300
|
184
|
-
return @request_time.to_i - @etime.to_i < threshold
|
185
|
-
end
|
186
|
-
|
187
|
-
def range_string
|
188
|
-
format = settings.config.global_config[:date_format] || "%X %x"
|
189
|
-
if @stime && @etime
|
190
|
-
if nowish
|
191
|
-
"timeslice: from #{@stime.strftime(format)}"
|
192
|
-
else
|
193
|
-
"timeslice: #{@stime.strftime(format)} - #{@etime.strftime(format)}"
|
194
|
-
end
|
195
|
-
else
|
196
|
-
"invalid time range"
|
197
|
-
end
|
198
|
-
|
199
|
-
end
|
200
|
-
|
201
|
-
def permalink
|
202
|
-
return "" unless @stime && @duration
|
203
|
-
format = "%F %T" # chronic REALLY understands this
|
204
|
-
url = request.path + "?"
|
205
|
-
url << "&start=#{@stime.strftime(format)}"
|
206
|
-
url << "&duration=#{ChronicDuration.output(@duration)}"
|
207
|
-
"<a id=\"permalink\" href=\"#{url}\">permalink</a>"
|
208
|
-
end
|
209
|
-
end
|
data/lib/models/base.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
module Dash::Models
|
2
|
-
class Base
|
3
|
-
@@objects = Hash.new { |h, k| h[k] = Hash.new }
|
4
|
-
attr_reader :name
|
5
|
-
|
6
|
-
def initialize(name, params={})
|
7
|
-
@name = name
|
8
|
-
@match_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.each { |k, v| yield(k, v) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.all
|
23
|
-
return @@objects[self.name].values
|
24
|
-
end
|
25
|
-
|
26
|
-
def [](key)
|
27
|
-
return @params[key] rescue []
|
28
|
-
end
|
29
|
-
|
30
|
-
def match(glob)
|
31
|
-
return true if glob == '*'
|
32
|
-
# convert glob to a regular expression
|
33
|
-
glob_parts = glob.split('*').collect { |s| Regexp.escape(s) }
|
34
|
-
if glob[0].chr == '*'
|
35
|
-
glob_re = /^.*#{glob_parts.join('.*')}$/
|
36
|
-
elsif glob[-1].chr == '*'
|
37
|
-
glob_re = /^#{glob_parts.join('.*')}.*$/
|
38
|
-
else
|
39
|
-
glob_re = /^#{glob_parts.join('.*')}$/
|
40
|
-
end
|
41
|
-
return @match_name.match(glob_re)
|
42
|
-
end
|
43
|
-
|
44
|
-
def multi_match(globs)
|
45
|
-
ret = false
|
46
|
-
|
47
|
-
globs.each do |glob|
|
48
|
-
ret = match(glob)
|
49
|
-
break if ret
|
50
|
-
end
|
51
|
-
|
52
|
-
return ret
|
53
|
-
end
|
54
|
-
|
55
|
-
def to_s
|
56
|
-
return @name
|
57
|
-
end
|
58
|
-
|
59
|
-
def <=>(other)
|
60
|
-
return to_s <=> other.to_s
|
61
|
-
end
|
62
|
-
|
63
|
-
def update_params(hash)
|
64
|
-
@params.merge!(hash)
|
65
|
-
end
|
66
|
-
|
67
|
-
# compose a metric using a :metric_format
|
68
|
-
# format string with %c for metric, %c for cluster, and %h for host
|
69
|
-
def compose_metric (m, c, h)
|
70
|
-
@params[:metric_format].dup.gsub("%m", m).gsub("%c", c).gsub("%h", h)
|
71
|
-
end
|
72
|
-
end # Dash::Models::Base
|
73
|
-
end # Dash::Models
|
data/lib/models/dashboard.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require "models/base"
|
2
|
-
require "models/graph"
|
3
|
-
require "models/host"
|
4
|
-
require "set"
|
5
|
-
|
6
|
-
module Dash::Models
|
7
|
-
class Dashboard < Base
|
8
|
-
attr_accessor :graphs
|
9
|
-
attr_accessor :graph_opts
|
10
|
-
|
11
|
-
def initialize(name, params={})
|
12
|
-
super
|
13
|
-
|
14
|
-
@graphs = []
|
15
|
-
@graph_opts = {}
|
16
|
-
params["graphs"].each do |name|
|
17
|
-
# graphs map to option hashes
|
18
|
-
if name.instance_of?(Hash) # could be YAML::Omap
|
19
|
-
g = Graph.find(name.keys.first) # should only be one key
|
20
|
-
@graph_opts[g] = name[name.keys.first]||{}
|
21
|
-
else
|
22
|
-
raise "Bad format for graph (must be a hash)"
|
23
|
-
end
|
24
|
-
|
25
|
-
@graphs << g if g
|
26
|
-
end
|
27
|
-
|
28
|
-
@valid_hosts_table = {} # cache calls to get_valid_hosts
|
29
|
-
end
|
30
|
-
|
31
|
-
def clusters
|
32
|
-
clusters = Set.new
|
33
|
-
@graphs.each { |g| clusters += get_valid_hosts(g)[1] }
|
34
|
-
clusters.sort
|
35
|
-
end
|
36
|
-
|
37
|
-
def get_all_hosts(cluster=nil)
|
38
|
-
hosts = Set.new
|
39
|
-
clusters = Set.new
|
40
|
-
@graphs.each do |g|
|
41
|
-
h, c = get_valid_hosts(g, cluster)
|
42
|
-
hosts += h
|
43
|
-
clusters += c
|
44
|
-
end
|
45
|
-
return hosts, clusters
|
46
|
-
end
|
47
|
-
|
48
|
-
def get_valid_hosts(graph, cluster=nil)
|
49
|
-
if @valid_hosts_table[[graph, cluster]]
|
50
|
-
return @valid_hosts_table[[graph, cluster]]
|
51
|
-
end
|
52
|
-
|
53
|
-
clusters = Set.new
|
54
|
-
if cluster
|
55
|
-
hosts = Host.find_by_cluster(cluster)
|
56
|
-
else
|
57
|
-
hosts = Host.all
|
58
|
-
end
|
59
|
-
|
60
|
-
# filter by what matches the graph definition
|
61
|
-
hosts = hosts.select { |h| h.multi_match(graph["hosts"]) }
|
62
|
-
|
63
|
-
# filter if we have a dashboard-level 'hosts' filter
|
64
|
-
if @params["hosts"]
|
65
|
-
hosts = hosts.select { |h| h.multi_match(@params["hosts"]) }
|
66
|
-
end
|
67
|
-
|
68
|
-
hosts.each { |h| clusters << h.cluster }
|
69
|
-
|
70
|
-
@valid_hosts_table[[graph, cluster]] = [hosts, clusters]
|
71
|
-
return hosts, clusters
|
72
|
-
end
|
73
|
-
|
74
|
-
def render_cluster_graph(graph, clusters, opts={})
|
75
|
-
# FIXME: edge case where the dash filter does not filter to a subset of
|
76
|
-
# the hosts filter
|
77
|
-
|
78
|
-
hosts = get_host_wildcards(graph)
|
79
|
-
opts[:sum] = :cluster unless opts[:zoom]
|
80
|
-
graph_url = graph.render_url(hosts.to_a, clusters, opts)
|
81
|
-
return graph_url
|
82
|
-
end
|
83
|
-
|
84
|
-
def get_host_wildcards(graph)
|
85
|
-
return graph_opts[graph]["hosts"] || @params["hosts"] || graph["hosts"]
|
86
|
-
end
|
87
|
-
|
88
|
-
def render_global_graph(graph, opts={})
|
89
|
-
hosts = get_host_wildcards(graph)
|
90
|
-
_, clusters = get_valid_hosts(graph)
|
91
|
-
|
92
|
-
next_url = ""
|
93
|
-
type = opts[:zoom] ? :cluster : :global
|
94
|
-
options = opts.merge({:sum => type})
|
95
|
-
graph_url = graph.render_url(hosts, clusters, options)
|
96
|
-
return graph_url
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.find_by_graph(graph)
|
100
|
-
ret = []
|
101
|
-
Dashboard.each do |name, dash|
|
102
|
-
|
103
|
-
if dash["graphs"].map { |x| x.keys.first }.member?(graph.name)
|
104
|
-
ret << dash
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
return ret
|
109
|
-
end
|
110
|
-
end # Dash::Models::Dashboard
|
111
|
-
end # Dash::Models
|