-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathtraceviz.rb
62 lines (51 loc) · 1.33 KB
/
traceviz.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/env ruby
# See http://www.hokstad.com/traceviz-visualizing-traceroute-output-with-graphivz.html
require 'timeout'
require 'set'
require 'socket'
TRACEROUTE=`which traceroute`.chomp
TIMES=3
TIMEOUT=60
def traceroute host
`#{TRACEROUTE} -n #{host}`
end
class TraceViz
def initialize(times,timeout)
@times,@timeout = times,timeout
@edges = Set.new
@nodes = Set.new
@targets = Set.new
@this_host = Socket.gethostname
@targets << @this_host
end
def trace host
@times.times do |i|
STDERR.puts "Trace ##{i+1} for #{host}"
Timeout::timeout(@timeout) do
process_trace(host,traceroute(host))
end rescue nil
end
end
def process_trace host,trace
@targets << host
trace = [@this_host] + trace.collect do |line|
line=line.split
line[0].to_i > 0 && line[1] != "*" ? line[1] : nil
end.compact
trace << host
trace.each {|h| @nodes << h }
trace.each_cons(2) {|h1,h2| @edges << [h1,h2] }
end
def to_dot
res = "digraph G {"
@edges.each { |h1,h2| res << " \"#{h1}\"->\"#{h2}\"\n" }
@nodes.each do |n|
color = @targets.member?(n) ? "lightblue" : "lightgrey"
res << " \"#{n}\" [style=filled fillcolor=#{color}]\n"
end
res << "}"
end
end
tv = TraceViz.new(TIMES,TIMEOUT)
ARGV.each {|host| tv.trace(host) }
puts tv.to_dot