Skip to content

Instantly share code, notes, and snippets.

Created February 9, 2013 21:16
Show Gist options
  • Save anonymous/4747152 to your computer and use it in GitHub Desktop.
Save anonymous/4747152 to your computer and use it in GitHub Desktop.
Munin plugin written in Ruby to get more detailed information when measuring HTTP connections (DNS lookup time, connection time, time waiting for first byte, time until everything is received).
#!/usr/bin/env ruby
require 'uri'
require 'socket'
if ARGV[0] and ( ARGV[0] == "-h" or ARGV[0] == "--help" )
puts "#{$0} [-h|--help] [config]"
puts "Munin plugin to measure individual HTTP timings"
puts " --help,-h Show this help"
puts " config Prints the configuration for munin"
puts ""
puts "Environment variables:"
puts " URL - URL to connect to"
puts " HTTP_HEADER - Custom HTTP Header(s) to append"
puts " graph_title - Title for the munin graph"
puts ""
puts "All values are reported in ms"
puts ""
puts "Written by Markus Fischer <markus@fischer.name>"
exit 0
end
graph_title = ENV['graph_title'] || "HTTP timings"
if ARGV[0] and ARGV[0] == "config"
puts <<EOT
graph_title #{graph_title}
graph_vlabel Time [ms]
graph_args --base 1000
graph_scale no
graph_category HTTPng
dns.label DNS
dns.draw AREA
connect.label Connect
connect.draw STACK
header_sent.label Header sent
header_sent.draw STACK
waiting.label Waiting
waiting.draw STACK
received.label Received
received.draw STACK
EOT
exit 0
end
def diff_time_ms(a,b)
((a - b) * 1000).to_i
end
HTTP_LE = "\r\n"
uri = URI.parse ENV['URL']
request_a = [
"GET / HTTP/1.0",
"Host: #{uri.host}"
]
if ENV['HTTP_HEADER']
request_a << ENV['HTTP_HEADER']
end
request = request_a.join(HTTP_LE) + HTTP_LE + HTTP_LE
timings = {}
timings[:start] = Time.now
hosts = TCPSocket.gethostbyname uri.host
timings[:dns] = Time.now
socket = TCPSocket.new hosts[3], uri.port
timings[:connected] = Time.now
socket.print request
timings[:sent_request] = Time.now
response = socket.recv 1
# So we know how long it took to receive the first byte
timings[:response_started] = Time.now
while rec = socket.recv(4096)
response += rec
break if rec.length == 0
end
timings[:response_finished] = Time.now
data = {}
data[:dns] = diff_time_ms(timings[:dns], timings[:start])
data[:connect] = diff_time_ms(timings[:connected], timings[:dns])
data[:header_sent] = diff_time_ms(timings[:sent_request], timings[:connected])
data[:waiting] = diff_time_ms(timings[:response_started], timings[:sent_request])
data[:received] = diff_time_ms(timings[:response_finished], timings[:response_started])
data.each do |k,v|
puts "#{k}.value #{v}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment