raindrops 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.document +2 -1
  2. data/.gitignore +4 -0
  3. data/.wrongdoc.yml +4 -0
  4. data/GIT-VERSION-GEN +1 -1
  5. data/GNUmakefile +2 -196
  6. data/Gemfile +7 -0
  7. data/LICENSE +1 -1
  8. data/README +17 -47
  9. data/Rakefile +0 -104
  10. data/examples/linux-listener-stats.rb +123 -0
  11. data/examples/{config.ru → middleware.ru} +1 -1
  12. data/examples/watcher.ru +4 -0
  13. data/examples/watcher_demo.ru +13 -0
  14. data/examples/zbatery.conf.rb +13 -0
  15. data/ext/raindrops/extconf.rb +5 -0
  16. data/ext/raindrops/linux_inet_diag.c +449 -151
  17. data/ext/raindrops/linux_tcp_info.c +170 -0
  18. data/ext/raindrops/my_fileno.h +36 -0
  19. data/ext/raindrops/raindrops.c +232 -20
  20. data/lib/raindrops.rb +20 -7
  21. data/lib/raindrops/aggregate.rb +8 -0
  22. data/lib/raindrops/aggregate/last_data_recv.rb +86 -0
  23. data/lib/raindrops/aggregate/pmq.rb +239 -0
  24. data/lib/raindrops/last_data_recv.rb +100 -0
  25. data/lib/raindrops/linux.rb +26 -16
  26. data/lib/raindrops/middleware.rb +112 -41
  27. data/lib/raindrops/middleware/proxy.rb +34 -0
  28. data/lib/raindrops/struct.rb +15 -0
  29. data/lib/raindrops/watcher.rb +362 -0
  30. data/pkg.mk +171 -0
  31. data/raindrops.gemspec +10 -20
  32. data/test/ipv6_enabled.rb +10 -0
  33. data/test/rack_unicorn.rb +12 -0
  34. data/test/test_aggregate_pmq.rb +65 -0
  35. data/test/test_inet_diag_socket.rb +13 -0
  36. data/test/test_last_data_recv_unicorn.rb +69 -0
  37. data/test/test_linux.rb +55 -57
  38. data/test/test_linux_all_tcp_listen_stats.rb +66 -0
  39. data/test/test_linux_all_tcp_listen_stats_leak.rb +43 -0
  40. data/test/test_linux_ipv6.rb +158 -0
  41. data/test/test_linux_tcp_info.rb +61 -0
  42. data/test/test_middleware.rb +15 -2
  43. data/test/test_middleware_unicorn.rb +37 -0
  44. data/test/test_middleware_unicorn_ipv6.rb +37 -0
  45. data/test/test_raindrops.rb +65 -1
  46. data/test/test_raindrops_gc.rb +23 -1
  47. data/test/test_watcher.rb +85 -0
  48. metadata +69 -22
  49. data/examples/linux-tcp-listener-stats.rb +0 -44
@@ -13,4 +13,26 @@ class TestRaindropsGc < Test::Unit::TestCase
13
13
  end
14
14
  end
15
15
 
16
- end
16
+ def test_gc_postfork
17
+ tmp = Raindrops.new 2
18
+ pid = fork do
19
+ 1000000.times do
20
+ tmp = Raindrops.new 2
21
+ tmp.to_ary
22
+ end
23
+ end
24
+ _, status = Process.waitpid2(pid)
25
+ assert status.success?
26
+ assert_equal [ 0, 0 ], tmp.to_ary
27
+ tmp.incr 1
28
+ assert_equal [ 0, 1 ], tmp.to_ary
29
+ pid = fork do
30
+ tmp.incr 1
31
+ exit([ 0, 2 ] == tmp.to_ary)
32
+ end
33
+ _, status = Process.waitpid2(pid)
34
+ assert status.success?
35
+ assert_equal [ 0, 2 ], tmp.to_ary
36
+ end
37
+ end if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" &&
38
+ ENV["STRESS"].to_i != 0
@@ -0,0 +1,85 @@
1
+ # -*- encoding: binary -*-
2
+ require "test/unit"
3
+ require "rack"
4
+ require "raindrops"
5
+
6
+ class TestWatcher < Test::Unit::TestCase
7
+ TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
8
+ def check_headers(headers)
9
+ %w(X-Count X-Std-Dev X-Min X-Max X-Mean
10
+ X-Outliers-Low X-Outliers-Low X-Last-Reset).each { |x|
11
+ assert_kind_of String, headers[x], "#{x} missing"
12
+ }
13
+ end
14
+
15
+ def teardown
16
+ @app.shutdown
17
+ @ios.each { |io| io.close unless io.closed? }
18
+ end
19
+
20
+ def setup
21
+ @ios = []
22
+ @srv = TCPServer.new TEST_ADDR, 0
23
+ @ios << @srv
24
+ @port = @srv.addr[1]
25
+ @client = TCPSocket.new TEST_ADDR, @port
26
+ @addr = "#{TEST_ADDR}:#{@port}"
27
+ @ios << @client
28
+ @app = Raindrops::Watcher.new :delay => 0.001
29
+ @req = Rack::MockRequest.new @app
30
+ end
31
+
32
+ def test_index
33
+ resp = @req.get "/"
34
+ assert_equal 200, resp.status.to_i
35
+ t = Time.parse resp.headers["Last-Modified"]
36
+ assert_in_delta Time.now.to_f, t.to_f, 2.0
37
+ end
38
+
39
+ def test_active_txt
40
+ resp = @req.get "/active/#@addr.txt"
41
+ assert_equal 200, resp.status.to_i
42
+ assert_equal "text/plain", resp.headers["Content-Type"]
43
+ check_headers(resp.headers)
44
+ end
45
+
46
+ def test_active_html
47
+ resp = @req.get "/active/#@addr.html"
48
+ assert_equal 200, resp.status.to_i
49
+ assert_equal "text/html", resp.headers["Content-Type"]
50
+ check_headers(resp.headers)
51
+ end
52
+
53
+ def test_reset
54
+ resp = @req.post "/reset/#@addr"
55
+ assert_equal 302, resp.status.to_i
56
+ end
57
+
58
+ def test_tail
59
+ env = @req.class.env_for "/tail/#@addr.txt"
60
+ status, headers, body = @app.call env
61
+ assert_equal "text/plain", headers["Content-Type"]
62
+ assert_equal 200, status.to_i
63
+ tmp = []
64
+ body.each do |x|
65
+ assert_kind_of String, x
66
+ tmp << x
67
+ break if tmp.size > 1
68
+ end
69
+ end
70
+
71
+ def test_tail_queued_min
72
+ env = @req.class.env_for "/tail/#@addr.txt?queued_min=1"
73
+ status, headers, body = @app.call env
74
+ assert_equal "text/plain", headers["Content-Type"]
75
+ assert_equal 200, status.to_i
76
+ tmp = []
77
+ body.each do |x|
78
+ tmp = TCPSocket.new TEST_ADDR, @port
79
+ @ios << tmp
80
+ assert_kind_of String, x
81
+ assert_equal 1, x.strip.split(/\s+/).last.to_i
82
+ break
83
+ end
84
+ end
85
+ end if RUBY_PLATFORM =~ /linux/
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raindrops
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 4
9
- - 1
10
- version: 0.4.1
4
+ prerelease:
5
+ version: 0.5.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - raindrops hackers
@@ -15,15 +10,27 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-09-26 00:00:00 +00:00
13
+ date: 2011-03-17 00:00:00 +00:00
19
14
  default_executable:
20
- dependencies: []
21
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 1.0.10
25
+ type: :development
26
+ version_requirements: *id001
22
27
  description: |-
23
- Raindrops is a real time stats package to show statistics for Rack HTTP
28
+ Raindrops is a real-time stats toolkit to show statistics for Rack HTTP
24
29
  servers. It is designed for preforking servers such as Rainbows! and
25
30
  Unicorn, but should support any Rack HTTP server under Ruby 1.9, 1.8 and
26
- possibly Rubinius (untested) on platforms supporting POSIX shared memory.
31
+ Rubinius on platforms supporting POSIX shared memory. It may also be
32
+ used as a generic scoreboard for sharing atomic counters across multiple
33
+ processes.
27
34
  email: raindrops@librelist.com
28
35
  executables: []
29
36
 
@@ -35,51 +42,87 @@ extra_rdoc_files:
35
42
  - NEWS
36
43
  - ChangeLog
37
44
  - lib/raindrops.rb
45
+ - lib/raindrops/aggregate.rb
46
+ - lib/raindrops/aggregate/last_data_recv.rb
47
+ - lib/raindrops/aggregate/pmq.rb
48
+ - lib/raindrops/last_data_recv.rb
38
49
  - lib/raindrops/linux.rb
39
50
  - lib/raindrops/middleware.rb
51
+ - lib/raindrops/middleware/proxy.rb
40
52
  - lib/raindrops/struct.rb
53
+ - lib/raindrops/watcher.rb
54
+ - ext/raindrops/raindrops.c
41
55
  - ext/raindrops/linux_inet_diag.c
56
+ - ext/raindrops/linux_tcp_info.c
42
57
  files:
43
58
  - .document
44
59
  - .gitignore
45
60
  - .manifest
61
+ - .wrongdoc.yml
46
62
  - COPYING
47
63
  - ChangeLog
48
64
  - GIT-VERSION-FILE
49
65
  - GIT-VERSION-GEN
50
66
  - GNUmakefile
67
+ - Gemfile
68
+ - LATEST
51
69
  - LICENSE
52
70
  - NEWS
53
71
  - README
54
72
  - Rakefile
55
73
  - TODO
56
- - examples/config.ru
57
- - examples/linux-tcp-listener-stats.rb
74
+ - examples/linux-listener-stats.rb
75
+ - examples/middleware.ru
76
+ - examples/watcher.ru
77
+ - examples/watcher_demo.ru
78
+ - examples/zbatery.conf.rb
58
79
  - ext/raindrops/extconf.rb
59
80
  - ext/raindrops/linux_inet_diag.c
81
+ - ext/raindrops/linux_tcp_info.c
82
+ - ext/raindrops/my_fileno.h
60
83
  - ext/raindrops/raindrops.c
61
84
  - ext/raindrops/raindrops_atomic.h
62
85
  - lib/raindrops.rb
86
+ - lib/raindrops/aggregate.rb
87
+ - lib/raindrops/aggregate/last_data_recv.rb
88
+ - lib/raindrops/aggregate/pmq.rb
89
+ - lib/raindrops/last_data_recv.rb
63
90
  - lib/raindrops/linux.rb
64
91
  - lib/raindrops/middleware.rb
92
+ - lib/raindrops/middleware/proxy.rb
65
93
  - lib/raindrops/struct.rb
94
+ - lib/raindrops/watcher.rb
95
+ - pkg.mk
66
96
  - raindrops.gemspec
67
97
  - setup.rb
98
+ - test/ipv6_enabled.rb
99
+ - test/rack_unicorn.rb
100
+ - test/test_aggregate_pmq.rb
101
+ - test/test_inet_diag_socket.rb
102
+ - test/test_last_data_recv_unicorn.rb
68
103
  - test/test_linux.rb
104
+ - test/test_linux_all_tcp_listen_stats.rb
105
+ - test/test_linux_all_tcp_listen_stats_leak.rb
106
+ - test/test_linux_ipv6.rb
69
107
  - test/test_linux_middleware.rb
108
+ - test/test_linux_tcp_info.rb
70
109
  - test/test_middleware.rb
110
+ - test/test_middleware_unicorn.rb
111
+ - test/test_middleware_unicorn_ipv6.rb
71
112
  - test/test_raindrops.rb
72
113
  - test/test_raindrops_gc.rb
73
114
  - test/test_struct.rb
115
+ - test/test_watcher.rb
74
116
  has_rdoc: true
75
117
  homepage: http://raindrops.bogomips.org/
76
118
  licenses: []
77
119
 
78
120
  post_install_message:
79
121
  rdoc_options:
80
- - -Na
81
122
  - -t
82
123
  - raindrops - real-time stats for preforking Rack servers
124
+ - -W
125
+ - http://bogomips.org/raindrops.git/tree/%s
83
126
  require_paths:
84
127
  - lib
85
128
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -87,30 +130,34 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
130
  requirements:
88
131
  - - ">="
89
132
  - !ruby/object:Gem::Version
90
- hash: 3
91
- segments:
92
- - 0
93
133
  version: "0"
94
134
  required_rubygems_version: !ruby/object:Gem::Requirement
95
135
  none: false
96
136
  requirements:
97
137
  - - ">="
98
138
  - !ruby/object:Gem::Version
99
- hash: 3
100
- segments:
101
- - 0
102
139
  version: "0"
103
140
  requirements: []
104
141
 
105
142
  rubyforge_project: rainbows
106
- rubygems_version: 1.3.7
143
+ rubygems_version: 1.6.2
107
144
  signing_key:
108
145
  specification_version: 3
109
146
  summary: real-time stats for preforking Rack servers
110
147
  test_files:
148
+ - test/test_aggregate_pmq.rb
149
+ - test/test_inet_diag_socket.rb
150
+ - test/test_last_data_recv_unicorn.rb
111
151
  - test/test_linux.rb
152
+ - test/test_linux_all_tcp_listen_stats.rb
153
+ - test/test_linux_all_tcp_listen_stats_leak.rb
154
+ - test/test_linux_ipv6.rb
112
155
  - test/test_linux_middleware.rb
156
+ - test/test_linux_tcp_info.rb
113
157
  - test/test_middleware.rb
158
+ - test/test_middleware_unicorn.rb
159
+ - test/test_middleware_unicorn_ipv6.rb
114
160
  - test/test_raindrops.rb
115
161
  - test/test_raindrops_gc.rb
116
162
  - test/test_struct.rb
163
+ - test/test_watcher.rb
@@ -1,44 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- # this is used to show or watch the number of active and queued
4
- # connections on any listener socket from the command line
5
-
6
- require 'raindrops'
7
- require 'optparse'
8
- require 'ipaddr'
9
- usage = "Usage: #$0 [-d delay] ADDR..."
10
- ARGV.size > 0 or abort usage
11
- delay = false
12
-
13
- # "normal" exits when driven on the command-line
14
- trap(:INT) { exit 130 }
15
- trap(:PIPE) { exit 0 }
16
-
17
- opts = OptionParser.new('', 24, ' ') do |opts|
18
- opts.banner = usage
19
- opts.on('-d', '--delay=delay') { |nr| delay = nr.to_i }
20
- opts.parse! ARGV
21
- end
22
-
23
- ARGV.each do |addr|
24
- addr =~ %r{\A(127\..+):(\d+)\z} or next
25
- host, port = $1, $2
26
- hex_port = '%X' % port.to_i
27
- ip_addr = IPAddr.new(host)
28
- hex_host = ip_addr.hton.each_byte.inject('') { |s,o| s << '%02X' % o }
29
- socks = File.readlines('/proc/net/tcp')
30
- hex_addr = "#{hex_host}:#{hex_port}"
31
- if socks.grep(/^\s+\d+:\s+#{hex_addr}\s+/).empty? &&
32
- ! socks.grep(/^\s+\d+:\s+00000000:#{hex_port}\s+/).empty?
33
- warn "W: #{host}:#{port} (#{hex_addr}) not found in /proc/net/tcp"
34
- warn "W: Did you mean 0.0.0.0:#{port}?"
35
- end
36
- end
37
-
38
- fmt = "% 19s % 10u % 10u\n"
39
- printf fmt.tr('u','s'), *%w(address active queued)
40
-
41
- begin
42
- stats = Raindrops::Linux.tcp_listener_stats(ARGV)
43
- stats.each { |addr,stats| printf fmt, addr, stats.active, stats.queued }
44
- end while delay && sleep(delay)