Module: Tcptop

Defined in:
lib/tcptop.rb,
lib/tcptop/version.rb,
lib/tcptop/collectd.rb

Defined Under Namespace

Classes: Collectd

Constant Summary collapse

VERSION =
"0.1.2"

Class Method Summary collapse

Class Method Details

.parse_options!Object



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
# File 'lib/tcptop.rb', line 10

def self.parse_options!
  options = {:tcp => [], :unix => [], :interval => 2, :sort => :active}
  OptionParser.new do |opts|
    opts.banner = "Usage: tcptop [options]"

    opts.on("-t", "--tcp SOCKET", "tcp socket to filter, can be used multiple times") do |sock|
      options[:tcp] << sock
    end
    opts.on("-u", "--unix PATH", "domain socket to filter, can be used multiple times, will not show by default") do |path|
      options[:unix] << path
    end
    opts.on("-1", "--once", "print once and exit") do
      options[:once] = true
    end
    opts.on("-n", "--interval SECONDS", Float, "seconds between stat collection, DEFAULT: 2") do |interval|
      options[:interval] = interval
    end
    opts.on("--queued", "sort on queued requests, defaults to active") do
      options[:sort] = :queued
    end
    opts.on("--collectd LABEL", "print output suitable for collectd, must also provide socket or path") do |label|
      options[:collectd] = label
    end
    opts.on("-v", "--version", "prints the version and exits") do
      options[:version] = true
    end
  end.parse!
  options
end


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/tcptop.rb', line 82

def self.print_info(sockets, paths, sort)
  puts LAYOUT % [
    "Socket",
    "Active" + (sort == :active ? "*" : ""),
    "Queued" + (sort == :queued ? "*" : "")
  ]
  responses = if paths.any?
                Raindrops::Linux.unix_listener_stats(paths)
              elsif sockets.empty?
                Raindrops::Linux.tcp_listener_stats
              else
                Raindrops::Linux.tcp_listener_stats(sockets)
              end

  responses.sort_by { |(a, s)| -1 * s.send(sort) }.each do |(address, stats)|
    puts LAYOUT % [address, stats.active, stats.queued]
  end
end

.run!Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/tcptop.rb', line 40

def self.run!
  options = parse_options!
  if options[:version]
    puts "tcptop: version #{Tcptop::VERSION}"
    exit 0
  elsif options[:once]
    print_info(options[:tcp], options[:unix], options[:sort])
    exit 0
  elsif options[:collectd]
    unless options[:tcp].size == 1 || options[:unix].size == 1
      puts "the --tcp or --unix option must be used once to identify the socket"
      exit 1
    end

    Signal.trap("INT") { exit 0 }
    hostname = ENV["COLLECTD_HOSTNAME"] || 'localhost'
    interval = (ENV["COLLECTD_INTERVAL"] || '60').to_i
    label = options[:collectd]

    loop do
      stats = nil
      if options[:tcp].size > 0
        _, stats = Raindrops::Linux.tcp_listener_stats(options[:tcp]).first
      else
        _, stats = Raindrops::Linux.unix_listener_stats(options[:unix]).first
      end
      Collectd.reading(stats.active, stats.queued, hostname, label)
      sleep interval
    end
  else
    Signal.trap("INT") { exit 0 }

    loop do
      system "clear"
      puts "Updated: #{Time.now}, checking every #{options[:interval]} seconds"
      puts
      print_info(options[:tcp], options[:unix], options[:sort])
      sleep options[:interval]
    end
  end
end