initial
[raindrops.git] / lib / raindrops / linux.rb
blob6dff73f59d19163f5ab5e5b98901491b412dd979
1 # -*- encoding: binary -*-
2 class Raindrops
3 module Linux
5   # The standard proc path for active UNIX domain sockets, feel free to call
6   # String#replace on this if your /proc is mounted in a non-standard location
7   # for whatever reason
8   PROC_NET_UNIX = "/proc/net/unix"
10   # Get ListenStats from an array of +paths+
11   #
12   # Socket state mapping from integer => symbol, based on socket_state
13   # enum from include/linux/net.h in the Linux kernel:
14   #     typedef enum {
15   #             SS_FREE = 0,              /* not allocated                */
16   #             SS_UNCONNECTED,           /* unconnected to any socket    */
17   #             SS_CONNECTING,            /* in process of connecting     */
18   #             SS_CONNECTED,             /* connected to socket          */
19   #             SS_DISCONNECTING          /* in process of disconnecting  */
20   #     } socket_state;
21   # * SS_CONNECTING maps to ListenStats#active
22   # * SS_CONNECTED maps to ListenStats#queued
23   #
24   # This method may be significantly slower than its tcp_listener_stats
25   # counterpart due to the latter being able to use inet_diag via netlink.
26   # This parses /proc/net/unix as there is no other (known) way
27   # to expose Unix domain socket statistics over netlink.
28   def unix_listener_stats(paths)
29     rv = Hash.new { |h,k| h[k.freeze] = ListenStats.new(0, 0) }
30     paths = paths.map do |path|
31       path = path.dup
32       path.force_encoding(Encoding::BINARY) if defined?(Encoding)
33       rv[path]
34       Regexp.escape(path)
35     end
36     paths = / 00000000 \d+ (\d+)\s+\d+ (#{paths.join('|')})$/n
38     # no point in pread since we can't stat for size on this file
39     File.open(PROC_NET_UNIX, "rb") do |fp|
40       fp.read.scan(paths).each do |s|
41         path = s.last
42         case s.first.to_i
43         when 2 then rv[path].queued += 1
44         when 3 then rv[path].active += 1
45         end
46       end
47     end
49     rv
50   end
52   module_function :unix_listener_stats
54 end # Linux
55 end # Raindrops