[ruby script]ping hosts and sort latency


脚本的目的是ping多个主机地址,排序ping的平均延时,用来看看现在的网络环境连接哪台服务器比较快。

使用方法是

$ ruby ping-servers.rb foo.com bar.com baz.com

$ cat server-list.txt | xargs ruby ping-servers.rb

第一行是直接输入所有主机地址,后面一个是从一个文件中输入所有主机地址。假如输入alipay,taobao和etao。结果如下

$ ruby ping-servers.rb taobao.com alipay.com etao.com
1/3 ping taobao.com
2/3 ping alipay.com
3/3 ping etao.com

host	average latency
taobao.com	12.186
etao.com	12.342
alipay.com	12.767

平均延迟的单位是ms。

脚本的原理是执行ping命令,得到输出,使用正则表达式匹配最后一行,抽取平均延迟,然后按照平均延迟排序多个结果。

正则表达式匹配最后一行的主要原理是如下的ping的输出,注意上面的是normal,即正常情况的,下面是ping不同的情况。抽取的是正常时的avg的值。

# normal
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 98.136/106.188/117.813/7.498 ms

# no response
4 packets transmitted, 0 packets received, 100.0% packet loss

以下是具体脚本

PING_CNT=2
LATENCY_STATUS=/^round-trip min\/avg\/max\/stddev = [\d.]+\/([\d.]+)\/[\d.]+\/[\d.]+ ms/

def ping(host)
 cmd = "ping -c #{PING_CNT} #{host}"
 # puts "execute command: #{cmd}"
 `#{cmd}`
end


def parse(ping_result)
  # >> passed
  # 4 packets transmitted, 4 packets received, 0.0% packet loss
  # round-trip min/avg/max/stddev = 98.136/106.188/117.813/7.498 ms
  # ---
  # >> failed
  # 4 packets transmitted, 0 packets received, 100.0% packet loss
  lines = ping_result.split('\n')
  # try match latency status
  md = lines[-1].match(LATENCY_STATUS)
  if md
    md[1].to_f
  else
    Float::INFINITY
  end
end

metrics = {}
argc = ARGV.size
ARGV.each_with_index do |host, i|
  puts "#{i + 1}/#{argc} ping #{host}"
  metrics[host] = parse(ping(host))
end

puts "\nhost\taverage latency"
metrics.sort_by { |k, v| v }.each do |k, v|
  puts "#{k}\t#{v == Float::INFINITY ? '-' : v}"
end

脚本还是比较简单的。注意默认PING的次数我设置为2,理论上可以通过参数输入修改。