pencil 0.2.10 → 0.3.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/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
|