autograph 0.1.2 → 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/Rakefile +5 -1
- data/VERSION +1 -1
- data/bin/autograph +5 -0
- data/lib/autograph/configuration.rb +5 -1
- data/lib/autograph/graph_renderers/base_renderer.rb +8 -2
- data/lib/autograph/graph_renderers/flot_renderer.rb +50 -0
- data/lib/autograph/graph_renderers/gchart_renderer.rb +15 -15
- data/lib/autograph/graph_renderers/scruffy_renderer.rb +14 -10
- data/lib/autograph/html_report.rb +1 -0
- data/lib/autograph/report.html.erb +3 -2
- data/lib/autograph.rb +1 -0
- metadata +6 -5
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
gem.authors = ["Nick Stielau"]
|
13
13
|
gem.add_runtime_dependency 'builder', '= 2.1.2'
|
14
14
|
gem.add_runtime_dependency 'ruport', '= 1.6.3'
|
15
|
-
gem.add_runtime_dependency 'scruffy', '= 0.2.
|
15
|
+
gem.add_runtime_dependency 'scruffy', '= 0.2.5'
|
16
16
|
gem.add_runtime_dependency 'gchart', '= 1.0.0'
|
17
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
18
|
end
|
@@ -29,5 +29,9 @@ Rake::TestTask.new(:test) do |test|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
|
32
|
+
task :install_local do
|
33
|
+
`sudo gem install --local ./pkg/autograph-0.1.2.gem --no-ri --no-rdoc`
|
34
|
+
end
|
35
|
+
|
32
36
|
task :test => :check_dependencies
|
33
37
|
task :default => :test
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bin/autograph
CHANGED
@@ -50,6 +50,11 @@ opt_parse_opts = OptionParser.new do |opts|
|
|
50
50
|
command_parts << "--test"
|
51
51
|
end
|
52
52
|
|
53
|
+
opts.on("--graph-renderer RENDERER", "The class to use as a graph renderer (#{BaseRenderer::AVAILABLE_GRAPH_RENDERERS.join(', ')}).") do |opt|
|
54
|
+
options['graph_renderer'] = opt
|
55
|
+
command_parts << "--graph-renderer '#{opt}'"
|
56
|
+
end
|
57
|
+
|
53
58
|
opts.separator ""
|
54
59
|
opts.separator "Httperf Knobs:"
|
55
60
|
|
@@ -58,6 +58,10 @@ class Configuration
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def graph_renderer_class
|
61
|
-
|
61
|
+
begin
|
62
|
+
Object.const_get(@conf['graph_renderer'].to_s)
|
63
|
+
rescue => e
|
64
|
+
abort("#{@conf['graph_renderer'].to_s} is not one of the available graph renderers (#{BaseRenderer::AVAILABLE_GRAPH_RENDERERS.join(', ')})")
|
65
|
+
end
|
62
66
|
end
|
63
67
|
end
|
@@ -5,6 +5,8 @@ class BaseRenderer
|
|
5
5
|
attr :path, true
|
6
6
|
attr :series
|
7
7
|
|
8
|
+
AVAILABLE_GRAPH_RENDERERS = %W(ScruffyRenderer GChartRenderer)
|
9
|
+
|
8
10
|
def initialize
|
9
11
|
@series = []
|
10
12
|
end
|
@@ -21,6 +23,9 @@ class BaseRenderer
|
|
21
23
|
series.map{|s| s.y_values.max}.max
|
22
24
|
end
|
23
25
|
|
26
|
+
def self.header_html
|
27
|
+
end
|
28
|
+
|
24
29
|
def self.generate_graphs(reports, configuration)
|
25
30
|
graphs = {}
|
26
31
|
reports.each do |uri, report|
|
@@ -41,7 +46,7 @@ class BaseRenderer
|
|
41
46
|
request_rate = GraphSeries.new(:line, report.column('rate'), report.column('conn/s').map{|x| x.to_f}, "Requests for '#{uri}'")
|
42
47
|
request_rate_graph.add_series(request_rate)
|
43
48
|
|
44
|
-
graphs[uri] << request_rate_graph
|
49
|
+
graphs[uri] << request_rate_graph
|
45
50
|
|
46
51
|
response_time_graph = configuration.graph_renderer_class.new
|
47
52
|
response_time_graph.path = uri
|
@@ -57,7 +62,7 @@ class BaseRenderer
|
|
57
62
|
response_time = GraphSeries.new(:line, report.column('rate'), report.column('reply time'), "Requests for '#{uri}'")
|
58
63
|
response_time_graph.add_series(response_time)
|
59
64
|
|
60
|
-
graphs[uri] << response_time_graph
|
65
|
+
graphs[uri] << response_time_graph
|
61
66
|
end
|
62
67
|
|
63
68
|
max_rate_graph = configuration.graph_renderer_class.new
|
@@ -70,6 +75,7 @@ class BaseRenderer
|
|
70
75
|
max_request_rate = GraphSeries.new(:bar, [key], [max], "Max Request Rate for '#{key}'")
|
71
76
|
max_rate_graph.add_series(max_request_rate)
|
72
77
|
end
|
78
|
+
|
73
79
|
graphs['summary_graph'] = max_rate_graph
|
74
80
|
graphs
|
75
81
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class FlotRenderer < BaseRenderer
|
2
|
+
def to_html
|
3
|
+
data = []
|
4
|
+
graph_type = ''
|
5
|
+
if series[0].type.to_sym == :bar
|
6
|
+
graph_type = "bars"
|
7
|
+
series.each_with_index do |s, i|
|
8
|
+
data << "[#{i}, #{s.y_values[0]}]"
|
9
|
+
end
|
10
|
+
else
|
11
|
+
graph_type = "lines"
|
12
|
+
1.upto(series[0].x_values.size.to_i - 1) do |index|
|
13
|
+
data << "[#{series[0].x_values[index]}, #{series[0].y_values[index]}]"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
html = <<GRAPH_HTML
|
18
|
+
<div style="with:600px;height:350px;" id="#{graph_name}"></div>
|
19
|
+
<script language="javascript" type="text/javascript">
|
20
|
+
//#{series.inspect}
|
21
|
+
$('.report').show();
|
22
|
+
$.plot($("##{graph_name}"), [
|
23
|
+
{
|
24
|
+
data: [#{data.join(",")}],
|
25
|
+
#{graph_type}: { show: true, fill: true }
|
26
|
+
}
|
27
|
+
]);
|
28
|
+
$('.report').hide();
|
29
|
+
show_report('overview');
|
30
|
+
</script>
|
31
|
+
GRAPH_HTML
|
32
|
+
html
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.header_html
|
36
|
+
html = <<HEADER_HTML
|
37
|
+
<script type="text/javascript" src="http://127.0.0.1:1234/jquery.js"></script>
|
38
|
+
<script type="text/javascript" src="http://127.0.0.1:1234/jquery.flot.js"></script>
|
39
|
+
HEADER_HTML
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def format_file_name(desired_name)
|
44
|
+
desired_name.to_s.gsub("/","_").gsub("=","_").gsub("?","_")
|
45
|
+
end
|
46
|
+
|
47
|
+
def graph_name
|
48
|
+
@graph_name ||= "graph_#{format_file_name(path || 'overview')}_#{(rand * 100).to_i}"
|
49
|
+
end
|
50
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'gchart'
|
2
2
|
|
3
3
|
class GChartRenderer < BaseRenderer
|
4
|
-
|
4
|
+
|
5
5
|
def to_html
|
6
|
-
|
7
|
-
render_graph.to_url
|
6
|
+
render_graph
|
7
|
+
"<img src='#{render_graph.to_url}'/>"
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
private
|
11
11
|
def available_colors
|
12
12
|
[:red, :yellow, :green, :blue, :black]
|
@@ -15,16 +15,16 @@ private
|
|
15
15
|
def render_graph
|
16
16
|
chart_type = series[0].type.to_s
|
17
17
|
chart_type = 'line' if chart_type == 'area'
|
18
|
-
|
18
|
+
|
19
19
|
chart = GChart.send(chart_type) do |g|
|
20
20
|
|
21
21
|
x_values = series[0].x_values
|
22
22
|
y_values = series[0].y_values
|
23
23
|
|
24
24
|
x_values = series.map{|s| s.x_values} if chart_type.to_sym == :bar
|
25
|
-
|
25
|
+
|
26
26
|
series_data = series.map{|s| s.y_values}
|
27
|
-
|
27
|
+
|
28
28
|
g.data = series_data
|
29
29
|
|
30
30
|
# chg, grid lines
|
@@ -41,9 +41,9 @@ private
|
|
41
41
|
:chm => "o,0066FF,0,-1.0,6",
|
42
42
|
:chma => "20,20,20,30|80,20",
|
43
43
|
:chdlp => "bv"}
|
44
|
-
|
45
|
-
if chart_type.to_sym == :bar
|
46
|
-
extras = extras.merge({:chm => '', :chbh => 'a,20,20'})
|
44
|
+
|
45
|
+
if chart_type.to_sym == :bar
|
46
|
+
extras = extras.merge({:chm => '', :chbh => 'a,20,20'})
|
47
47
|
# chm=N*f0*,000000,1,-1,11|N*f0*,000000,2,-1,11|N*f1*,000000,3,-1,11|N*f2*,FF0000,0,0,18
|
48
48
|
g.grouped = true
|
49
49
|
end
|
@@ -61,15 +61,15 @@ private
|
|
61
61
|
a.labels = (0..(y_values.max.to_i)).to_a.select{|y| y % interval == 0}
|
62
62
|
a.text_color = :black
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
if chart_type.to_sym == :bar
|
66
|
-
g.orientation = :vertical
|
67
|
-
end
|
68
|
-
|
66
|
+
g.orientation = :vertical
|
67
|
+
end
|
68
|
+
|
69
69
|
colors = available_colors
|
70
70
|
g.colors = series.map{|s| colors.pop}
|
71
71
|
|
72
|
-
g.legend = series.map{|s| s.label}
|
72
|
+
g.legend = series.map{|s| s.label.gsub("'", "")}
|
73
73
|
|
74
74
|
g.title = title
|
75
75
|
|
@@ -1,15 +1,21 @@
|
|
1
1
|
require 'scruffy'
|
2
2
|
|
3
3
|
class ScruffyRenderer < BaseRenderer
|
4
|
-
|
4
|
+
SCRUFFY_HEIGHT=360
|
5
|
+
SCRUFFY_WIDTH=600
|
6
|
+
|
5
7
|
def to_html
|
6
8
|
render_graph
|
7
|
-
"<
|
9
|
+
"<iframe width=\"#{SCRUFFY_WIDTH}\" height=\"#{SCRUFFY_HEIGHT}\" src=\"./#{graph_file_name}\"></iframe>"
|
8
10
|
end
|
9
|
-
|
11
|
+
|
10
12
|
private
|
11
13
|
def format_file_name(desired_name)
|
12
|
-
desired_name.gsub("/","_").gsub("=","_").gsub("?","_")
|
14
|
+
desired_name.to_s.gsub("/","_").gsub("=","_").gsub("?","_")
|
15
|
+
end
|
16
|
+
|
17
|
+
def graph_file_name
|
18
|
+
@graph_name ||= "graph_#{format_file_name(path || 'overview')}_#{(rand * 100).to_i}.svg"
|
13
19
|
end
|
14
20
|
|
15
21
|
def render_graph
|
@@ -17,15 +23,13 @@ private
|
|
17
23
|
graph.title = title
|
18
24
|
graph.renderer = Scruffy::Renderers::Standard.new(:values => series[0].x_values.size + 1)
|
19
25
|
graph.point_markers = series[0].x_values
|
20
|
-
|
26
|
+
|
21
27
|
series.each do |s|
|
22
28
|
graph.add s.type.to_sym, s.label, s.y_values
|
23
29
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
graph.render :to => @file_name, :min_value => 0, :max_value => find_max_y_value
|
28
|
-
|
30
|
+
|
31
|
+
graph.render :to => graph_file_name, :min_value => 0, :max_value => find_max_y_value, :width => SCRUFFY_WIDTH, :height => SCRUFFY_HEIGHT
|
32
|
+
|
29
33
|
graph
|
30
34
|
end
|
31
35
|
end
|
@@ -9,6 +9,7 @@ class HtmlReport
|
|
9
9
|
command_run = configuration["command_run"]
|
10
10
|
notes = configuration["notes"]
|
11
11
|
summary_graph = graphs['summary_graph']
|
12
|
+
graph_header_html = configuration.graph_renderer_class.header_html
|
12
13
|
|
13
14
|
output_file = HtmlReport.determine_output_file(configuration['output_file'], configuration['output_dir'])
|
14
15
|
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<head>
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
6
6
|
<title><%= title %></title>
|
7
|
+
<%= graph_header_html %>
|
7
8
|
<style type="text/css">
|
8
9
|
body,
|
9
10
|
html {
|
@@ -132,7 +133,7 @@
|
|
132
133
|
<h2>Report Detail</h2>
|
133
134
|
|
134
135
|
<div id="overview" class='report'>
|
135
|
-
|
136
|
+
<%= summary_graph.to_html %>
|
136
137
|
</div>
|
137
138
|
|
138
139
|
<div id="graph_discussion" class='report' style="display:none;">
|
@@ -151,7 +152,7 @@ Discussion on what these graphs mean.
|
|
151
152
|
<div id="page_<%= uri %>" class='report' style="display:none;">
|
152
153
|
<p>Report for <%= "http://#{host}#{uri}" %></p>
|
153
154
|
<% graphs[uri].each do |graph| %>
|
154
|
-
|
155
|
+
<%= graph.to_html %>
|
155
156
|
<% end %>
|
156
157
|
<pre>
|
157
158
|
<%= report.to_s %>
|
data/lib/autograph.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 1
|
8
7
|
- 2
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Stielau
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-25 00:00:00 -07:00
|
18
18
|
default_executable: autograph
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -55,8 +55,8 @@ dependencies:
|
|
55
55
|
segments:
|
56
56
|
- 0
|
57
57
|
- 2
|
58
|
-
-
|
59
|
-
version: 0.2.
|
58
|
+
- 5
|
59
|
+
version: 0.2.5
|
60
60
|
type: :runtime
|
61
61
|
version_requirements: *id003
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- lib/autograph/autoperf.rb
|
95
95
|
- lib/autograph/configuration.rb
|
96
96
|
- lib/autograph/graph_renderers/base_renderer.rb
|
97
|
+
- lib/autograph/graph_renderers/flot_renderer.rb
|
97
98
|
- lib/autograph/graph_renderers/gchart_renderer.rb
|
98
99
|
- lib/autograph/graph_renderers/rasterized_scruffy_renderer.rb
|
99
100
|
- lib/autograph/graph_renderers/scruffy_renderer.rb
|