Permalink
Browse files

Remove steps (took too much explanation, anyhow), add trending sparkl…

…ine (pure Ruby, inline img data implementation)
  • Loading branch information...
1 parent ded4b3d commit 7aa130b7c3921fb8beb7132413b8d5c3bfe0ec00 Bruce Williams committed May 24, 2008
@@ -44,7 +44,7 @@ version: 2.5.1
/* Styling */
#tuneup { height: 50px; color: #ddd; background: #000 url(/images/tuneup/head.gif) 0 100% repeat-x; padding: 0 0 0 10px; font-family: "Helvetica Neue", "Lucida Grande", Calibri, Helvetica, Verdana, sans-serif; font-size: 12px; }
-#tuneup #tuneup-content { margin-left: 170px; color: #000; height: 50px; vertical-align: middle; text-align: left; }
+#tuneup #tuneup-content { margin-left: 170px; color: #ddd; height: 50px; vertical-align: middle; text-align: left; }
#tuneup #tuneup-root-bar { float: right; }
#tuneup a, #tuneup a:visited, #tuneup a:active { color: #fff; text-decoration: underline; font-size: 12px; border: 0; }
@@ -176,4 +176,5 @@ version: 2.5.1
#tuneup #tuneup-data:hover #tuneup-schema { display: block; }
#tuneup #tuneup-schema table, #tuneup #tuneup-schema tr { background: transparent; }
#tuneup #tuneup-schema th { background: #111; color: #fff; border: 0 }
-#tuneup #tuneup-schema td { background: #000; font-family: monospace; color: #ddd; padding: 1px; font-size: 11px; }
+#tuneup #tuneup-schema td { background: #000; font-family: monospace; color: #ddd; padding: 1px; font-size: 11px; }
+#tuneup #tuneup-trend { float: right; width: 100px; }
View
@@ -0,0 +1,52 @@
+require 'base64'
+require 'zlib'
+
+# Note: This is a modified copy of _why's `bumpspark' library,
+# discussed and collaborated on at:
+# http://redhanded.hobix.com/inspect/sparklinesForMinimalists.html
+# Many thanks to the various collaborators; _why (concept), MenTaLguY (transparency), and jzp (png)
+module BumpsparkHelper
+
+ def build_png_chunk(type,data)
+ to_check = type + data
+ return [data.length].pack("N") + to_check + [Zlib.crc32(to_check)].pack("N")
+ end
+
+ def build_png(image_rows)
+ header = [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
+ raw_data = image_rows.map { |row| [0] + row }.flatten.pack("C*")
+ ihdr_data = [ image_rows.first.length,image_rows.length,
+ 8,2,0,0,0].pack("NNCCCCC")
+ ihdr = build_png_chunk("IHDR", ihdr_data)
+ trns = build_png_chunk("tRNS", ([ 0 ]*6).pack("C6"))
+ idat = build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
+ iend = build_png_chunk("IEND", "")
+
+ return header + ihdr + trns + idat + iend
+ end
+ def bumpspark(results)
+ black = [0, 0, 0]
+ white, red, grey = [0xFF,0xFF,0xFF], [0xFF,0,0], [0x99,0x99,0x99]
+ rows = normalize(results).inject([]) do |ary, r|
+ ary << [black]*15 << [black]*15
+ ary.last[r/9,4] = [(r > 50 and red or grey)]*4
+ ary
+ end.transpose.reverse
+ return build_png(rows)
+ end
+ def build_data_url(type,data)
+ data = Base64.encode64(data).delete("\n")
+ return "data:#{type};base64,#{CGI.escape(data)}"
+ end
+
+ def normalize(results)
+ min, max = results.min, results.max
+ width = max - min
+ return [1] * results.size if width == 0
+ width += (300 * 1000)
+ results.map do |result|
+ ((result - min) * 100 / width.to_f).to_i
+ end
+ end
+
+end
View
@@ -18,7 +18,7 @@ class << self
attr_writer :collecting
attr_accessor :running
- attr_accessor :current_run_id
+ attr_reader :trend
def run(controller, request)
@running = (!controller.is_a?(TuneupController) && !request.xhr?)
@@ -41,12 +41,12 @@ def collecting
def record(controller, request)
if recording?
@stack = [Fiveruns::Tuneup::RootStep.new]
+ @trend = nil
@environment = environment
- self.current_run_id = generate_run_id(request.url)
yield
log :info, "Persisting for #{request.url} using stub #{stub(request.url)}"
- persist(self.current_run_id, @environment, schemas, @stack.shift)
- self.current_run_id = nil
+ data = @stack.shift
+ persist(generate_run_id(request.url, data.time), @environment, schemas, data)
elsif !@running
# Plugin displaying the data
# TODO: Support targeted selection (for historical run)
@@ -55,6 +55,7 @@ def record(controller, request)
log :info, "Retrieved last run id of #{last_id} for #{request.parameters['uri']} using stub #{stub(request.parameters['uri'])}"
if last_id && (data = retrieve_run(last_id))
@stack = [data]
+ @trend = trend_for(last_id)
else
log :debug, "No stack found"
clear_stack
@@ -79,7 +80,6 @@ def stack
def start
log :info, "Starting..."
- reset! unless ENV['FIVERUNS_TUNEUP_RETAIN']
install_instrumentation
log :debug, "Using collector at #{collector_url}"
log :debug, "Using frontend at #{frontend_url}"
@@ -92,13 +92,6 @@ def log(level, text)
#######
private
#######
-
- # Remove all runs from this session
- def reset!
- FileUtils.rm_rf run_dir
- rescue
- # Nothing to remove, ignore
- end
def clear_stack
@stack = []
@@ -21,10 +21,6 @@ def load_from_file(filename)
YAML.load(decompressed)
end
- def run_files
- Dir[File.join(run_dir, '*.yml.gz')]
- end
-
def last_filename_for_run_uri(uri)
filename_for(last_run_id_for(uri))
end
@@ -33,16 +29,23 @@ def last_filename_for_run_uri(uri)
private
#######
+ def trend_for(run_id)
+ Dir[File.join(run_dir, File.dirname(run_id), "*.gz")].map do |filename|
+ Integer(File.basename(filename, '.yml.gz').split('_').last)
+ end
+ end
+
def last_run_id_for(url)
last_file = Dir[File.join(run_dir, stub(url), '*.gz')].last
if last_file
File.join(File.basename(File.dirname(last_file)), File.basename(last_file, '.yml.gz'))
end
end
- def generate_run_id(url)
+ # Use Run ID, current timestamp, and total time (in microseconds)
+ def generate_run_id(url, time)
timestamp = '%d' % (Time.now.to_f * 1000)
- File.join(stub(url), timestamp.to_s)
+ File.join(stub(url), timestamp.to_s << "_#{(time * 1000).to_i}")
end
def persist(run_id, environment, schemas, data)
View
@@ -1,4 +1,6 @@
module TuneupHelper #:nodoc:
+
+ include BumpsparkHelper
def tuneup_signin_url
"#{Fiveruns::Tuneup.collector_url}/users"
@@ -39,6 +41,18 @@ def tuneup_schemas
Fiveruns::Tuneup.stack.first['schemas']
end
+ def trend
+ numbers= if Fiveruns::Tuneup.trend.size > 50
+ Fiveruns::Tuneup.trend[-50..-1]
+ else
+ Fiveruns::Tuneup.trend
+ end
+ return unless numbers.size > 1
+ tag(:img,
+ :src => build_data_url("image/png",bumpspark(numbers)), :alt => '',
+ :title => "Trend over last #{pluralize(numbers.size, 'run')}")
+ end
+
def tuneup_step_link(step)
name = tuneup_style_step_name(tuneup_truncate_step_name(step))
link = if step.children.any?
View
@@ -2,6 +2,15 @@ namespace :fiveruns do
namespace :tuneup do
+ namespace :tmp do
+
+ desc "Clear tempory data (runs, etc)"
+ task :clear => :environment do
+ rm_rf File.join(RAILS_ROOT, 'tmp', 'tuneup')
+ end
+
+ end
+
namespace :assets do
desc "Install assets"
@@ -2,7 +2,7 @@
<div id='tuneup-top'>
<div id='tuneup-summary'>
<%= tuneup_bar(tuneup_data, :id => 'tuneup-root-bar') %>
- <%= pluralize(tuneup_data.size, 'step') %> / <%= tuneup_data.time.to_i %> ms
+ <%= trend %> <%= tuneup_data.time.to_i %> ms
</div>
<%= link_to_remote "Upload this Run", :url => "/tuneup/upload?uri=#{CGI.escape(params[:uri])}", :html => {:id => 'tuneup-save-link'} %>
</div>

0 comments on commit 7aa130b

Please sign in to comment.