-
-
Save changeme/dc07d160068a3cc94039e65d4d6e6756 to your computer and use it in GitHub Desktop.
Continuously measure 'Time To First Byte'. Easily plot Connection and TTFB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# @Name TTFB Measurer | |
# @Author Rasmus Christiansen | |
# @Description | |
# | |
# Measures the "true" loading time of a website. | |
# Saves data output to an .out-file | |
# Saves additional .conn and .ttfb files for easy plotting | |
# Generates and saves A report with average data. | |
# | |
# | |
# TODO: Very messy, but gets the job done. Could use a proper rewriting | |
# | |
class APP | |
def initialize | |
if ARGV.length < 1 | |
puts "Usage: #{__FILE__} domain.com [delay] [subsystem] [timeout in minutes]" | |
exit | |
end | |
@delay = 10 | |
@domain = ARGV[0] | |
@domain_formatted = @domain.gsub("/", "_") | |
@domain_formatted = @domain_formatted.gsub(".", "_") | |
@logdir = "ttfb_logs" | |
@timeout = 0 | |
@iter =0 | |
@sum_conn =0.0 | |
@sum_ttfb =0.0 | |
@sum_total=0.0 | |
unless File.directory?(@logdir) | |
Dir.mkdir(@logdir) | |
end | |
if ARGV.length >= 2 | |
@delay = ARGV[1] | |
end | |
if ARGV.length >= 3 | |
@subsystem = ARGV[2] | |
@logdir = @logdir + "/" + @subsystem | |
unless File.directory?(@logdir) | |
Dir.mkdir(@logdir) | |
end | |
end | |
if ARGV.length >= 4 | |
@timeout = (ARGV[3]).to_i*60 | |
end | |
@init_time = Time.now | |
@filename = @logdir + "/" + @domain_formatted + "-" + @init_time.to_i.to_s + ".out" | |
@filename_conn = @logdir + "/" + @domain_formatted + "-" + @init_time.to_i.to_s + ".conn" | |
@filename_ttfb = @logdir + "/" + @domain_formatted + "-" + @init_time.to_i.to_s + ".ttfb" | |
@filename_avg = @logdir + "/" + @domain_formatted + "-" + @init_time.to_i.to_s + ".avg" | |
end | |
def logtime | |
t = Time.now | |
return t.strftime("[%m/%d/%Y %H:%M:%S]") | |
end | |
def logit str | |
open(@filename, 'a') do |f| | |
f.puts str | |
end | |
end | |
def plotlog str | |
tmp = str.split(" ") | |
timediff = Time.now.to_i - @init_time.to_i | |
open(@filename_conn, 'a') do |f| | |
f.puts "#{timediff} #{tmp[1]}" | |
end | |
open(@filename_ttfb, 'a') do |f| | |
f.puts "#{timediff} #{tmp[3]}" | |
end | |
end | |
def ttfb | |
measure = `curl -o /dev/null -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n" -s http://#{@domain}` | |
return measure | |
end | |
def genAvg | |
#end_time = Time.now | |
#@running_time = end_time.to_i - @init_time.to_i | |
puts "Generating report.." | |
puts | |
report = {} | |
report["started"] = "Started:\t" + @init_time.to_i.to_s + @init_time.strftime("\t[%m/%d/%Y %H:%M:%S]") | |
report["ended"] = "Ended:\t\t" + @end_time.to_i.to_s + @end_time.strftime("\t[%m/%d/%Y %H:%M:%S]") | |
report["running"] = "Running:\t" + @running_time.to_s + " seconds" | |
report["connavg"] = "Conn Avg:\t#{@sum_conn/@iter} \t\t[#{@sum_conn}/#{@iter}]" | |
report["ttfbavg"] = "TTFB Avg:\t#{@sum_ttfb/@iter} \t\t[#{@sum_ttfb}/#{@iter}]" | |
report["totalavg"] = "Total Avg:\t#{@sum_total/@iter} \t\t[#{@sum_total}/#{@iter}]" | |
open(@filename_avg, 'a') do |f| | |
f.puts report["started"] | |
puts report["started"] | |
f.puts report["ended"] | |
puts report["ended"] | |
f.puts report["running"] | |
puts report["running"] | |
f.puts report["connavg"] | |
puts report["connavg"] | |
f.puts report["ttfbavg"] | |
puts report["ttfbavg"] | |
f.puts report["totalavg"] | |
puts report["totalavg"] | |
puts | |
end | |
puts "Report saved to: #{@filename_avg}" | |
end | |
def reportAvg str | |
tmp = str.split(" ") | |
#puts "#{@iter} - Summing: #{tmp[1]}, #{tmp[3]}, #{tmp[6]}" | |
@sum_conn +=tmp[1].to_f | |
@sum_ttfb +=tmp[3].to_f | |
@sum_total+=tmp[6].to_f | |
end | |
def run | |
trap("INT") do | |
puts " signal caught!" | |
genAvg | |
exit | |
end | |
puts "Measuring Time To First Byte on #{@domain} with a #{@delay} seconds delay." | |
unless @timeout.nil? || @timeout==0 | |
puts "Running for #{@timeout/60} minutes (#{@timeout} seconds) or until manual quit.." | |
end | |
while TRUE | |
@iter += 1 | |
@end_time = Time.now | |
@running_time = @end_time.to_i - @init_time.to_i | |
#puts "Running for : #{@running_time}" | |
unless @timeout.nil? || @timeout==0 | |
if @running_time >= @timeout | |
#if (@iter >= (@runningtime)) | |
puts "Timeout reached! Quitting.." | |
genAvg | |
exit | |
end | |
end | |
ttfb_res = ttfb | |
ttfb_pretty = logtime + " " + ttfb_res | |
puts ttfb_pretty | |
logit ttfb_pretty | |
plotlog ttfb_res | |
reportAvg ttfb_res | |
sleep(@delay.to_i) | |
end | |
end | |
end | |
app = APP.new | |
app.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment