collectd-plot 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ collectd-plot (0.0.1)
5
+ errand (= 0.7.3)
6
+ gnuplot (= 2.4.1)
7
+ haml (= 3.1.4)
8
+ librrd (= 1.0.2)
9
+ sinatra (= 1.3.2)
10
+ tilt (= 1.3.3)
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ builder (3.0.0)
16
+ colorize (0.5.8)
17
+ cucumber (1.1.9)
18
+ builder (>= 2.1.2)
19
+ diff-lcs (>= 1.1.2)
20
+ gherkin (~> 2.9.0)
21
+ json (>= 1.4.6)
22
+ term-ansicolor (>= 1.0.6)
23
+ diff-lcs (1.1.3)
24
+ errand (0.7.3)
25
+ gherkin (2.9.1)
26
+ json (>= 1.4.6)
27
+ gnuplot (2.4.1)
28
+ haml (3.1.4)
29
+ json (1.6.5)
30
+ librrd (1.0.2)
31
+ nokogiri (1.5.2)
32
+ rack (1.4.1)
33
+ rack-protection (1.2.0)
34
+ rack
35
+ rack-test (0.6.1)
36
+ rack (>= 1.0)
37
+ rspec (2.9.0)
38
+ rspec-core (~> 2.9.0)
39
+ rspec-expectations (~> 2.9.0)
40
+ rspec-mocks (~> 2.9.0)
41
+ rspec-core (2.9.0)
42
+ rspec-expectations (2.9.0)
43
+ diff-lcs (~> 1.1.3)
44
+ rspec-mocks (2.9.0)
45
+ shotgun (0.9)
46
+ rack (>= 1.0)
47
+ sinatra (1.3.2)
48
+ rack (~> 1.3, >= 1.3.6)
49
+ rack-protection (~> 1.2)
50
+ tilt (~> 1.3, >= 1.3.3)
51
+ term-ansicolor (1.0.7)
52
+ tilt (1.3.3)
53
+ webrat (0.7.3)
54
+ nokogiri (>= 1.2.0)
55
+ rack (>= 1.0)
56
+ rack-test (>= 0.5.3)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ collectd-plot!
63
+ colorize
64
+ cucumber
65
+ rack-test
66
+ rspec
67
+ shotgun
68
+ webrat
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+
2
+ # Overview
3
+
4
+ Collectd-Plot is a web interface for Collectd,
5
+ which plots data from RRD files using Gnuplot.
6
+
7
+ # Installation
8
+
9
+ TODO
10
+
11
+ # Development
12
+
13
+ TODO
@@ -0,0 +1,34 @@
1
+ #
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "collectd-plot"
6
+ s.version = "0.0.1"
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = [ "Tim Miller" ]
9
+ s.email = [ "" ]
10
+ s.homepage = "https://github.com/echohead/collectd-plot"
11
+ s.summary = %q{A web interface for Collectd}
12
+ s.description = %q{Plot collectd data using gnuplot, with useful features such as host globbing.}
13
+
14
+ s.required_ruby_version = ">= 1.9.1"
15
+ s.required_rubygems_version = ">= 1.3.7"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency "haml", "= 3.1.4"
23
+ s.add_runtime_dependency "tilt", "= 1.3.3"
24
+ s.add_runtime_dependency "sinatra", "= 1.3.2"
25
+ s.add_runtime_dependency "errand", "= 0.7.3"
26
+ s.add_runtime_dependency "librrd", "= 1.0.2"
27
+ s.add_runtime_dependency "gnuplot", "= 2.4.1"
28
+ s.add_development_dependency "shotgun", ">= 0"
29
+ s.add_development_dependency "rack-test", ">= 0"
30
+ s.add_development_dependency "rspec", ">= 0"
31
+ s.add_development_dependency "cucumber", ">= 0"
32
+ s.add_development_dependency "webrat", ">= 0"
33
+ s.add_development_dependency "colorize", ">= 0"
34
+ end
@@ -0,0 +1,60 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'sinatra'
3
+ require 'haml'
4
+ require 'collectd-plot/rrd_read'
5
+ require 'collectd-plot/plot'
6
+ require 'collectd-plot/plot_properties'
7
+
8
+ module CollectdPlot
9
+
10
+ helpers do
11
+ def link_to url_fragment, mode=:path_only
12
+ case mode
13
+ when :path_only
14
+ base = request.script_name
15
+ when :full_url
16
+ if (request.scheme == 'http' && request.port == 80 ||
17
+ request.scheme == 'https' && request.port == 443)
18
+ port = ""
19
+ else
20
+ port = ":#{request.port}"
21
+ end
22
+ base = "#{request.scheme}://#{request.host}#{port}#{request.script_name}"
23
+ else
24
+ raise "Unknown script_url mode #{mode}"
25
+ end
26
+ "#{base}#{url_fragment}"
27
+ end
28
+ end
29
+
30
+ get '/' do
31
+ @hosts = RRDRead.list_hosts
32
+ haml :index
33
+ end
34
+
35
+ get '/hosts/:h' do |h|
36
+ @host = h
37
+ @metrics = RRDRead.list_metrics_for(@host)
38
+ haml :host
39
+ end
40
+
41
+ get '/hosts/:h/metric/:m' do |h, m|
42
+ content_type 'image/png'
43
+ props = PlotProperties.new(:host => h, :metric => m)
44
+ data = RRDRead.get_data(props)
45
+ Plot.render(data, props)
46
+ end
47
+
48
+ get '/plot' do
49
+ content_type 'image/png'
50
+ props = PlotProperties.new(params)
51
+ data = RRDRead.get_data(props)
52
+ Plot.render(data, props)
53
+ end
54
+
55
+ get '/sandbox' do
56
+ content_type 'image/png'
57
+ CollectdPlot::Plot.example
58
+ end
59
+
60
+ end
@@ -0,0 +1,91 @@
1
+ require 'gnuplot'
2
+
3
+ module CollectdPlot
4
+ module Plot
5
+
6
+ def self.rand_filename()
7
+ "/tmp/#{(0...10).map{65.+(rand(25)).chr}.join}.png"
8
+ end
9
+
10
+
11
+ def self.render(data, props)
12
+ cmd = ''
13
+ png_file = rand_filename
14
+ Gnuplot::Plot.new(cmd) do |plot|
15
+ plot.terminal 'png'
16
+ plot.output png_file
17
+
18
+ #plot.xrange '[0:10]'
19
+ plot.title "#{props.metric} for #{props.host}"
20
+ plot.grid
21
+ plot.xrange "[#{props.start}:#{props.finish}]"
22
+ x = (props.start.to_i..props.finish.to_i).to_a
23
+
24
+ data.each_pair do |h, d|
25
+ plot.data << Gnuplot::DataSet.new( [x, d] ) do |ds|
26
+ ds.linewidth = 4
27
+ ds.title = props.host
28
+ end
29
+ end
30
+ end
31
+ cmd << "\n\n\n"
32
+
33
+ script = rand_filename
34
+ File.open(script, 'w') { |f| f.write cmd }
35
+ puts `gnuplot #{script}`
36
+ puts `cat #{script} > gnuplot`
37
+ f = File.open(png_file, "rb")
38
+ png = f.read
39
+ f.close
40
+ File.delete png_file
41
+ File.delete script
42
+ png
43
+ end
44
+
45
+
46
+ def self.example
47
+ cmd = ''
48
+ png_file = rand_filename
49
+ Gnuplot::Plot.new(cmd) do |plot|
50
+ plot.terminal "png"
51
+ plot.output png_file
52
+
53
+ plot.xrange "[0:10]"
54
+ plot.title "Sin Wave Example"
55
+ plot.xlabel "x"
56
+ plot.ylabel "y"
57
+ plot.grid
58
+
59
+ x = (0..50).collect { |v| v.to_f }
60
+ y = x.collect { |v| v ** 2 }
61
+ z = x.collect { |v| v * Math.sin(v) }
62
+
63
+ plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
64
+ ds.with = "linespoints"
65
+ ds.title = "quadratic"
66
+ ds.linewidth = 4
67
+ end
68
+ plot.data << Gnuplot::DataSet.new( [x, z] ) do |ds|
69
+ ds.with = "linespoints"
70
+ ds.title = "linear"
71
+ ds.linewidth = 4
72
+ end
73
+ # plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds|
74
+ # ds.with = "lines"
75
+ # end
76
+ end
77
+ cmd << "\n\n\n"
78
+
79
+ script = rand_filename
80
+ File.open(script, 'w') { |f| f.write cmd }
81
+ puts `gnuplot #{script}`
82
+ puts `cat #{script} > gnuplot`
83
+ f = File.open(png_file, "rb")
84
+ png = f.read
85
+ f.close
86
+ File.delete png_file
87
+ File.delete script
88
+ png
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,20 @@
1
+
2
+
3
+ module CollectdPlot
4
+ class PlotProperties
5
+ attr_accessor :host # may be a glob
6
+ attr_accessor :metric
7
+ attr_accessor :start
8
+ attr_accessor :finish
9
+ attr_accessor :instance
10
+
11
+ def initialize(params = {})
12
+ self.host = params[:host] or raise ("no host")
13
+ self.metric = params[:metric] or raise ("no metric")
14
+ self.instance = params[:instance]
15
+ self.start = params[:start] || (Time.now.to_i - 86400)
16
+ self.finish = params[:finish] || Time.now.to_i
17
+ self.instance = params[:instance] || "TODO"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,60 @@
1
+ require 'errand'
2
+
3
+ module CollectdPlot
4
+ module RRDRead
5
+ RRDDIR = '/var/lib/collectd/rrd/'
6
+
7
+ def self.list_hosts
8
+ Dir.glob("#{RRDDIR}/*").map { |p| File.basename p }
9
+ end
10
+
11
+ def self.regexp_hosts(glob)
12
+ Dir.glob("#{RRDDIR}/*").each { |d| puts d }
13
+ end
14
+
15
+ def self.list_metrics_for(h)
16
+ Dir.glob("#{RRDDIR}/#{h}/*").map { |m| File.basename m }
17
+ end
18
+
19
+ def self.get_data(props)
20
+ data = {}
21
+ rrd_name = "#{RRDDIR}#{props.host}/load/load.rrd"
22
+ rrd = Errand.new(:filename => rrd_name)
23
+
24
+ puts rrd.fetch(:function => 'AVERAGE', :start => props.start, :finish => props.finish).inspect
25
+ rrd_data = rrd.fetch(:function => 'AVERAGE', :start => props.start, :finish => props.finish)[:data]
26
+ res = {}
27
+ rrd_data.each_pair do |source, metric|
28
+ metric.map! do |datapoint|
29
+ case
30
+ when datapoint && datapoint.nan?
31
+ @tripped = true
32
+ @last_valid
33
+ when @tripped
34
+ @last_valid
35
+ else
36
+ @last_valid = datapoint
37
+ end
38
+ end
39
+ data[props.host] = metric
40
+ end
41
+ data
42
+ end
43
+ =begin
44
+ props.host_a
45
+ props[
46
+ # Last value is always wack. Set to 0, so the timescale isn't off by 1.
47
+ metric[-1] = 0.0
48
+
49
+ res[d[:host]] ||= {}
50
+ res[d[:host]][d[:plugin]] ||= {}
51
+ res[d[:host]][d[:plugin]][d[:instance]] ||= {}
52
+ res[d[:host]][d[:plugin]][d[:instance]][source] ||= {}
53
+ res[d[:host]][d[:plugin]][d[:instance]][source][:start] ||= d[:start].to_i
54
+ res[d[:host]][d[:plugin]][d[:instance]][source][:finish] ||= d[:finish].to_i
55
+ res[d[:host]][d[:plugin]][d[:instance]][source][:data] ||= metric
56
+ end
57
+ res
58
+ =end
59
+ end
60
+ end
@@ -0,0 +1,444 @@
1
+ /* resets */
2
+ body {
3
+ font-size: 62.5%;
4
+ }
5
+
6
+ * {
7
+ margin: 0;
8
+ padding: 0;
9
+ }
10
+
11
+ a {
12
+ text-decoration: none;
13
+ }
14
+
15
+ input:focus {
16
+ outline: none;
17
+ }
18
+
19
+ /* styles */
20
+
21
+ a { color: #3465a4; padding: 2px 0px; }
22
+ a:hover { text-decoration: underline; }
23
+ a:visited { color: #75507b; }
24
+ a:hover:visited { text-decoration: underline; }
25
+
26
+ p {
27
+ margin: 0 0 1em;
28
+ }
29
+
30
+ body {
31
+ font-family: Bitstream Vera Serif, Baskerville, Garamond, serif;
32
+ font-size: 1.2em;
33
+ }
34
+
35
+ div#header {
36
+ margin-bottom: 16px;
37
+ border-bottom: 2px solid #C5D6ED;
38
+ background-color: #3465a4;
39
+ background: -moz-linear-gradient(100% 100% 90deg, #244671, #4C94F0);
40
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4C94F0), to(#244671));
41
+ -moz-box-shadow: -7px 0 7px rgba(0,0,0,0.4);
42
+ -webkit-box-shadow: -7px 0 7px rgba(0,0,0,0.4);
43
+ }
44
+
45
+ div#nav {
46
+ color: white;
47
+ font-family: Bitstream Vera Sans, Helvetica Neue, sans-serif;
48
+ text-align: right;
49
+ font-size: 16px;
50
+ }
51
+
52
+ div#nav ul {
53
+ padding: 8px 0px;
54
+ }
55
+
56
+ div#nav ul li {
57
+ display: inline;
58
+ padding: 8px 0px;
59
+ }
60
+
61
+ div#nav ul li a {
62
+ padding: 8px 16px;
63
+ color: white;
64
+ text-shadow: 0 2px 1px rgba(0,0,0,0.5);
65
+ font-weight: bold;
66
+ }
67
+
68
+ div#nav ul li a:hover {
69
+ text-shadow: 0 2px 1px rgba(255,255,255,0.1);
70
+ background: -webkit-gradient(linear, left top, left bottom, from(#529EFF), to(#274C7A));
71
+ background: -moz-linear-gradient(top, #529EFF, #274C7A);
72
+ text-decoration: none;
73
+ }
74
+
75
+ div#nav span.title {
76
+ font-weight: bold;
77
+ }
78
+
79
+
80
+ div#content, div#nav {
81
+ width: 950px;
82
+ margin: auto;
83
+ }
84
+
85
+ div#hosts {
86
+ clear: left;
87
+ }
88
+
89
+ div#profile-meta, div#profile-preview {
90
+ float: left;
91
+ margin-left: 25px;
92
+ width: 450px;
93
+ }
94
+
95
+ div#profile-meta input.text {
96
+ border: 1px solid #bbb;
97
+ font-size: 16px;
98
+ padding: 4px;
99
+ width: 20em;
100
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
101
+ -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
102
+ }
103
+
104
+ div#profile-meta input.create.profile {
105
+ -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
106
+ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5);
107
+ -moz-border-radius: 5px;
108
+ -webkit-border-radius: 5px;
109
+ background: #888;
110
+ color: white;
111
+ padding: 5px 10px 6px;
112
+ text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
113
+ border-bottom: 1px solid rgba(0,0,0,0.25);
114
+ position: relative;
115
+ cursor: pointer;
116
+ font-weight: bold;
117
+ background-image: -webkit-gradient(
118
+ linear,
119
+ left bottom,
120
+ left top,
121
+ color-stop(0.1, rgb(136,136,136)),
122
+ color-stop(0.5, rgb(153,153,153))
123
+ );
124
+ background-image: -moz-linear-gradient(
125
+ center bottom,
126
+ rgb(136,136,136) 10%,
127
+ rgb(153,153,153) 50%
128
+ );
129
+ }
130
+
131
+ /*
132
+ * BUILDER
133
+ */
134
+
135
+ div.builder {
136
+ float: left;
137
+ width: 450px;
138
+ margin-left: 25px;
139
+ margin-bottom: 24px;
140
+ }
141
+
142
+ div.builder input.text {
143
+ border: 1px solid #bbb;
144
+ font-size: 16px;
145
+ padding: 4px;
146
+ width: 20em;
147
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
148
+ -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
149
+ }
150
+
151
+ div.builder div.tokenWrapper {
152
+ border: 1px solid #bbb;
153
+ font-size: 16px;
154
+ padding: 4px;
155
+ padding-top: 0;
156
+ width: 350px;
157
+ height: 20px;
158
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
159
+ -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
160
+ }
161
+
162
+ div.builder div.tokenWrapper div.token {
163
+ float: left;
164
+ margin: 2px 4px 2px 0px;
165
+ font-family: Lucida Grande, sans-serif;
166
+ font-size: 16px;
167
+ }
168
+
169
+ div.builder div.tokenWrapper div.token.finalized {
170
+ padding: 0 2px;
171
+ background-color: #D1E5FF;
172
+ color: black;
173
+ border: 1px solid #2F5A92;
174
+ font-size: 14px;
175
+ }
176
+
177
+ div.builder div.tokenWrapper div.token.finalized.selected {
178
+ background-color: #2F5A92;
179
+ color: white;
180
+ }
181
+
182
+ div.builder div.tokenWrapper div.token input.token {
183
+ border: 0;
184
+ font-size: 16px;
185
+ width: 80px;
186
+ }
187
+
188
+ div.builder input.text:focus {
189
+ border: 1px solid #666;
190
+ }
191
+
192
+ div.builder img.icon {
193
+ float: right;
194
+ }
195
+
196
+ div.builder h5 {
197
+ margin-top: 8px;
198
+ margin-left: 8px;
199
+ }
200
+
201
+ div.builder ul.results {
202
+ font-family: Lucida Grande, sans-serif;
203
+ font-size: 16px;
204
+ position: absolute;
205
+ z-index: 10;
206
+ }
207
+
208
+ div.builder ul.results li {
209
+ list-style-type: none;
210
+ padding: 4px 5px;
211
+ border-left: 1px #BBBBBB solid;
212
+ border-right: 1px #BBBBBB solid;
213
+ border-bottom: 1px #BBBBBB solid;
214
+ background-color: white;
215
+ width: 348px;
216
+ }
217
+
218
+ div.builder ul.results li.active {
219
+ background-color: #4C94F0;
220
+ color: white;
221
+ }
222
+
223
+ div.builder ul.results li.all {
224
+ color: gray;
225
+ }
226
+
227
+ div.builder ul.results li.all.active {
228
+ background-color: #A0BD29;
229
+ color: white;
230
+ }
231
+
232
+
233
+
234
+ /*
235
+ * GRAPHS + PROFILE VIEWER
236
+ */
237
+
238
+ div#graphs {
239
+ clear: both;
240
+ padding: 0 2em;
241
+ /* border-top: 1px dashed #babdb6; */
242
+ margin: 16px 0;
243
+ }
244
+
245
+ div.graph {
246
+ margin: 32px 0 48px;
247
+ }
248
+
249
+ h1, h2, h3, h4, h5 {
250
+ font-family: Bitstream Vera Sans, Helvetica Neue, sans-serif;
251
+ }
252
+
253
+ h2 {
254
+ font-weight: bold;
255
+ color: #333;
256
+ border-bottom: 4px solid #888;
257
+ margin-bottom: 12px;
258
+ }
259
+
260
+ h1 {
261
+ font-size: 4em;
262
+ }
263
+
264
+ h1 span.project-name {
265
+ padding: 0 0.1em 0.1em;
266
+ background-color: #3465a4;
267
+ color: white;
268
+ }
269
+
270
+ a#edit {
271
+ float: right;
272
+ display: block;
273
+ }
274
+
275
+ div#chart-builder-slider {
276
+ clear: both;
277
+ overflow-x: hidden;
278
+ overflow-y: hidden;
279
+ }
280
+
281
+ div#profile {
282
+ clear: both;
283
+ }
284
+
285
+ h2#profile_name {
286
+ margin: 36px 0;
287
+ }
288
+
289
+ h4.error {
290
+ margin: 8px 0;
291
+ }
292
+
293
+ div.graph pre {
294
+ line-height: 1.6em;
295
+ font-size: 90%;
296
+ margin-top: -10px;
297
+ }
298
+
299
+ div#bottom_nav {
300
+ margin: 32px 0;
301
+ border-top: 1px dotted #aaa;
302
+ padding-top: 12px;
303
+ font-size: 85%;
304
+ }
305
+
306
+ div#footer {
307
+ clear: both;
308
+ font-size: 0.6em;
309
+ color: gray;
310
+ text-align: center;
311
+ margin-bottom: 2em;
312
+ }
313
+
314
+ div#nothing {
315
+ margin-top: 1em;
316
+ }
317
+
318
+
319
+ div#profiles {
320
+ float: left;
321
+ margin-left: 25px;
322
+ width: 450px;
323
+ }
324
+
325
+ div#profiles div#sort {
326
+ text-align: right;
327
+ font-size: 85%;
328
+ color: #888;
329
+ }
330
+
331
+ div#profiles ul li {
332
+ margin-bottom: 8px;
333
+ padding-left: 24px;
334
+ margin-left: -24px;
335
+ list-style-type: none;
336
+ }
337
+
338
+ div#profiles ul li.active {
339
+ background: url("/images/active.png") no-repeat scroll 10px;
340
+ }
341
+
342
+ div#profiles ul {
343
+ margin-bottom: 16px;
344
+ }
345
+
346
+ div#profiles p.create {
347
+ border-top: 1px dotted #aaa;
348
+ padding-top: 8px;
349
+ margin-top: 24px;
350
+ font-size: 85%;
351
+ }
352
+
353
+ .mask {
354
+ position: absolute;
355
+ opacity: 0.7;
356
+ filter: alpha(opacity=90);
357
+ -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90);
358
+ z-index: 999;
359
+ background: #000;
360
+ }
361
+
362
+ div#shortcuts {
363
+ font-family: Bitstream Vera Sans, Helvetica Neue, sans-serif;
364
+ z-index: 1000;
365
+ width: 600px;
366
+ position: absolute;
367
+ top: 100px;
368
+ left: 50%;
369
+ margin-left: -300px;
370
+ background-color: white;
371
+ padding: 8px;
372
+ }
373
+
374
+ div#shortcuts table td, div#shortcuts table th {
375
+ padding: 4px 8px;
376
+ }
377
+
378
+ div#shortcuts table th {
379
+ text-align: left;
380
+ }
381
+
382
+
383
+ .button {
384
+ -moz-border-radius: 5px;
385
+ -webkit-border-radius: 5px;
386
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
387
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
388
+ background-color: #637020;
389
+ background-repeat: repeat-x;
390
+ background: -moz-linear-gradient(100% 100% 90deg, #244671, #4C94F0);
391
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4C94F0), to(#244671));
392
+ border: medium none;
393
+ color: white;
394
+ cursor: pointer;
395
+ font-family: Lucida Grande,sans-serif;
396
+ font-weight: bold;
397
+ padding: 4px;
398
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
399
+ }
400
+
401
+ .button:hover, .button:focus {
402
+ text-shadow: 0 2px 1px rgba(255,255,255,0.1);
403
+ background: -webkit-gradient(linear, left top, left bottom, from(#529EFF), to(#274C7A));
404
+ background: -moz-linear-gradient(top, #529EFF, #274C7A);
405
+ outline: none;
406
+ }
407
+
408
+ input#show {
409
+ float: right;
410
+ font-size: 80%;
411
+ padding: 4px 8px;
412
+ font-family: 'Bitstream Vera Sans', 'Helvetica Neue', sans-serif;
413
+ margin-bottom: 16px;
414
+ margin-left: 16px;
415
+ }
416
+
417
+ input#save {
418
+ float: right;
419
+ font-size: 80%;
420
+ padding: 4px 8px;
421
+ font-family: 'Bitstream Vera Sans', 'Helvetica Neue', sans-serif;
422
+ margin-bottom: 16px;
423
+ margin-left: 16px;
424
+ }
425
+
426
+ button::-moz-focus-inner,
427
+ input[type="reset"]::-moz-focus-inner,
428
+ input[type="button"]::-moz-focus-inner,
429
+ input[type="submit"]::-moz-focus-inner,
430
+ input[type="file"] > input[type="button"]::-moz-focus-inner {
431
+ border: none;
432
+ }
433
+
434
+ input#profile_name {
435
+ border: 1px solid #bbb;
436
+ font-size: 16px;
437
+ padding: 4px;
438
+ padding-top: 0;
439
+ width: 200px;
440
+ height: 20px;
441
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
442
+ -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
443
+ float: right;
444
+ }
@@ -0,0 +1,7 @@
1
+
2
+ %table
3
+ %tbody
4
+ - @metrics.each do |m|
5
+ %tr
6
+ %td
7
+ %a{:href => link_to("/hosts/#{@host}/metric/#{m}")}= m
@@ -0,0 +1,7 @@
1
+
2
+ %table
3
+ %tbody
4
+ - @hosts.each do |h|
5
+ %tr
6
+ %td
7
+ %a{:href => link_to("/hosts/#{h}")}= h
@@ -0,0 +1,27 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title= "Collectd-Plot"
5
+ %link{:rel => "icon", :type => "image/gif", :href => "/favicon.gif"}
6
+ %link{:rel => 'stylesheet', :href => '/stylesheets/screen.css', :type => 'text/css'}
7
+
8
+ %body
9
+ %div#wrapper
10
+ %div#header
11
+ %div#nav
12
+ %ul
13
+ %li
14
+ %a{:href => link_to("/profiles")} profiles
15
+ %li
16
+ %a{:href => link_to("/builder")} builder
17
+
18
+ %div#content
19
+ = yield
20
+
21
+ %div#footer
22
+ Collectd-Plot
23
+ |
24
+ %a{:href => link_to("/profiles")} Profiles
25
+ |
26
+ %a{:href => link_to("/builder")} Builder
27
+
metadata ADDED
@@ -0,0 +1,239 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: collectd-plot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ prerelease: false
10
+ platform: ruby
11
+ authors:
12
+ - Tim Miller
13
+ autorequire: !!null
14
+ bindir: bin
15
+ cert_chain: []
16
+ date: 2012-04-08 00:00:00.000000000 +00:00
17
+ default_executable: !!null
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: haml
21
+ requirement: &14890980 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - =
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.4
27
+ segments:
28
+ - 3
29
+ - 1
30
+ - 4
31
+ type: :runtime
32
+ prerelease: false
33
+ version_requirements: *14890980
34
+ - !ruby/object:Gem::Dependency
35
+ name: tilt
36
+ requirement: &14890100 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - =
40
+ - !ruby/object:Gem::Version
41
+ version: 1.3.3
42
+ segments:
43
+ - 1
44
+ - 3
45
+ - 3
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *14890100
49
+ - !ruby/object:Gem::Dependency
50
+ name: sinatra
51
+ requirement: &14889180 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - =
55
+ - !ruby/object:Gem::Version
56
+ version: 1.3.2
57
+ segments:
58
+ - 1
59
+ - 3
60
+ - 2
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: *14889180
64
+ - !ruby/object:Gem::Dependency
65
+ name: errand
66
+ requirement: &14836780 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - =
70
+ - !ruby/object:Gem::Version
71
+ version: 0.7.3
72
+ segments:
73
+ - 0
74
+ - 7
75
+ - 3
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: *14836780
79
+ - !ruby/object:Gem::Dependency
80
+ name: librrd
81
+ requirement: &14835820 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - =
85
+ - !ruby/object:Gem::Version
86
+ version: 1.0.2
87
+ segments:
88
+ - 1
89
+ - 0
90
+ - 2
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: *14835820
94
+ - !ruby/object:Gem::Dependency
95
+ name: gnuplot
96
+ requirement: &14834820 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - =
100
+ - !ruby/object:Gem::Version
101
+ version: 2.4.1
102
+ segments:
103
+ - 2
104
+ - 4
105
+ - 1
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: *14834820
109
+ - !ruby/object:Gem::Dependency
110
+ name: shotgun
111
+ requirement: &14833760 !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ segments:
118
+ - 0
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: *14833760
122
+ - !ruby/object:Gem::Dependency
123
+ name: rack-test
124
+ requirement: &14832840 !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ segments:
131
+ - 0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *14832840
135
+ - !ruby/object:Gem::Dependency
136
+ name: rspec
137
+ requirement: &14831980 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ segments:
144
+ - 0
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: *14831980
148
+ - !ruby/object:Gem::Dependency
149
+ name: cucumber
150
+ requirement: &14831220 !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ segments:
157
+ - 0
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: *14831220
161
+ - !ruby/object:Gem::Dependency
162
+ name: webrat
163
+ requirement: &14830200 !ruby/object:Gem::Requirement
164
+ none: false
165
+ requirements:
166
+ - - ! '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ segments:
170
+ - 0
171
+ type: :development
172
+ prerelease: false
173
+ version_requirements: *14830200
174
+ - !ruby/object:Gem::Dependency
175
+ name: colorize
176
+ requirement: &14829420 !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ segments:
183
+ - 0
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: *14829420
187
+ description: Plot collectd data using gnuplot, with useful features such as host globbing.
188
+ email:
189
+ - ''
190
+ executables: []
191
+ extensions: []
192
+ extra_rdoc_files: []
193
+ files:
194
+ - Gemfile
195
+ - Gemfile.lock
196
+ - README.md
197
+ - collectd-plot.gemspec
198
+ - lib/collectd-plot.rb
199
+ - lib/collectd-plot/plot.rb
200
+ - lib/collectd-plot/plot_properties.rb
201
+ - lib/collectd-plot/rrd_read.rb
202
+ - lib/public/stylesheets/screen.css
203
+ - lib/views/host.haml
204
+ - lib/views/index.haml
205
+ - lib/views/layout.haml
206
+ has_rdoc: true
207
+ homepage: https://github.com/echohead/collectd-plot
208
+ licenses: []
209
+ post_install_message: !!null
210
+ rdoc_options: []
211
+ require_paths:
212
+ - lib
213
+ required_ruby_version: !ruby/object:Gem::Requirement
214
+ none: false
215
+ requirements:
216
+ - - ! '>='
217
+ - !ruby/object:Gem::Version
218
+ version: 1.9.1
219
+ segments:
220
+ - 1
221
+ - 9
222
+ - 1
223
+ required_rubygems_version: !ruby/object:Gem::Requirement
224
+ none: false
225
+ requirements:
226
+ - - ! '>='
227
+ - !ruby/object:Gem::Version
228
+ version: 1.3.7
229
+ segments:
230
+ - 1
231
+ - 3
232
+ - 7
233
+ requirements: []
234
+ rubyforge_project: !!null
235
+ rubygems_version: 1.3.7
236
+ signing_key: !!null
237
+ specification_version: 3
238
+ summary: A web interface for Collectd
239
+ test_files: []