preliminary Rack app to track last_data_recv
[raindrops.git] / examples / linux-listener-stats.rb
blobd675ee1028d21978defda17e2b30986805d95e18
1 #!/usr/bin/ruby
2 $stdout.sync = $stderr.sync = true
3 # this is used to show or watch the number of active and queued
4 # connections on any listener socket from the command line
6 require 'raindrops'
7 require 'optparse'
8 require 'ipaddr'
9 require 'time'
10 usage = "Usage: #$0 [-d DELAY] [-t QUEUED_THRESHOLD] ADDR..."
11 ARGV.size > 0 or abort usage
12 delay = false
13 queued_thresh = -1
15 # "normal" exits when driven on the command-line
16 trap(:INT) { exit 130 }
17 trap(:PIPE) { exit 0 }
19 opts = OptionParser.new('', 24, '  ') do |opts|
20   opts.banner = usage
21   opts.on('-d', '--delay=DELAY', Float) { |n| delay = n }
22   opts.on('-t', '--queued-threshold=INT', Integer) { |n| queued_thresh = n }
23   opts.parse! ARGV
24 end
26 ARGV.each do |addr|
27   addr =~ %r{\A(127\..+):(\d+)\z} or next
28   host, port = $1, $2
29   hex_port = '%X' % port.to_i
30   ip_addr = IPAddr.new(host)
31   hex_host = ip_addr.hton.each_byte.inject('') { |s,o| s << '%02X' % o }
32   socks = File.readlines('/proc/net/tcp')
33   hex_addr = "#{hex_host}:#{hex_port}"
34   if socks.grep(/^\s+\d+:\s+#{hex_addr}\s+/).empty? &&
35      ! socks.grep(/^\s+\d+:\s+00000000:#{hex_port}\s+/).empty?
36     warn "W: #{host}:#{port} (#{hex_addr}) not found in /proc/net/tcp"
37     warn "W: Did you mean 0.0.0.0:#{port}?"
38   end
39 end
41 now = nil
42 fmt = "%20s % 35s % 10u % 10u\n"
43 $stderr.printf fmt.tr('u','s'), *%w(timestamp address active queued)
44 tcp, unix = [], []
45 ARGV.each { |addr| (addr =~ %r{\A/} ? unix : tcp) << addr }
46 combined = {}
47 tcp = nil if tcp.empty?
48 unix = nil if unix.empty?
50 begin
51   if now
52     combined.clear
53     now = nil
54   end
55   tcp and combined.merge! Raindrops::Linux.tcp_listener_stats(tcp)
56   unix and combined.merge! Raindrops::Linux.unix_listener_stats(unix)
57   combined.each do |addr,stats|
58     next if stats.queued < queued_thresh
59     printf fmt, now ||= Time.now.utc.iso8601, addr, stats.active, stats.queued
60   end
61 end while delay && sleep(delay)