1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Instrument requests count (#2106)

* Instrument requests count

* Fix existing tests

* Add history

* add new test
This commit is contained in:
Yoann Lecuyer 2020-02-11 16:47:40 +01:00 committed by GitHub
parent 6f59df8dc0
commit a391634a34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 7 deletions

View file

@ -5,6 +5,7 @@
* Configuration: `environment` is read from `RAILS_ENV`, if `RACK_ENV` can't be found (#2022)
* `Puma.stats` now returns a Hash instead of a JSON string (#2086)
* `GC.compact` is called before fork if available (#2093)
* Add `requests_count` to workers stats. (#2106)
* Bugfixes
* Your bugfix goes here (#Github Number)

View file

@ -94,7 +94,7 @@ module Puma
def ping!(status)
@last_checkin = Time.now
captures = status.match(/{ "backlog":(?<backlog>\d*), "running":(?<running>\d*), "pool_capacity":(?<pool_capacity>\d*), "max_threads": (?<max_threads>\d*) }/)
captures = status.match(/{ "backlog":(?<backlog>\d*), "running":(?<running>\d*), "pool_capacity":(?<pool_capacity>\d*), "max_threads": (?<max_threads>\d*), "requests_count": (?<requests_count>\d*) }/)
@last_status = captures.names.inject({}) do |hash, key|
hash[key.to_sym] = captures[key].to_i
hash
@ -296,7 +296,8 @@ module Puma
r = server.running || 0
t = server.pool_capacity || 0
m = server.max_threads || 0
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m} }\n!
rc = server.requests_count || 0
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m}, "requests_count": #{rc} }\n!
io << payload
rescue IOError
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue

View file

@ -36,6 +36,7 @@ module Puma
attr_reader :thread
attr_reader :events
attr_reader :requests_count
attr_accessor :app
attr_accessor :min_threads
@ -85,6 +86,8 @@ module Puma
@mode = :http
@precheck_closing = true
@requests_count = 0
end
attr_accessor :binder, :leak_stack_on_error, :early_hints
@ -626,6 +629,8 @@ module Puma
#
# Finally, it'll return +true+ on keep-alive connections.
def handle_request(req, lines)
@requests_count +=1
env = req.env
client = req.io

View file

@ -20,6 +20,7 @@ module Puma
running: @server.running || 0,
pool_capacity: @server.pool_capacity || 0,
max_threads: @server.max_threads || 0,
requests_count: @server.requests_count || 0,
}
end

View file

@ -57,7 +57,7 @@ class TestCLI < Minitest::Test
body = s.read
s.close
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16}/, body.split(/\r?\n/).last)
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16,"requests_count":0}/, body.split(/\r?\n/).last)
ensure
cli.launcher.stop
@ -91,9 +91,9 @@ class TestCLI < Minitest::Test
body = http.request(req).body
end
expected_stats = /{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16}/
expected_stats = /{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16,"requests_count":0}/
assert_match(expected_stats, body.split(/\r?\n/).last)
assert_equal([:started_at, :backlog, :running, :pool_capacity, :max_threads], Puma.stats.keys)
assert_equal([:started_at, :backlog, :running, :pool_capacity, :max_threads, :requests_count], Puma.stats.keys)
ensure
cli.launcher.stop
@ -136,7 +136,7 @@ class TestCLI < Minitest::Test
body = s.read
s.close
assert_match(/\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","workers":2,"phase":0,"booted_workers":2,"old_workers":0,"worker_status":\[\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","pid":\d+,"index":0,"phase":0,"booted":true,"last_checkin":"[^"]+","last_status":\{"backlog":0,"running":2,"pool_capacity":2,"max_threads":2\}\},\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","pid":\d+,"index":1,"phase":0,"booted":true,"last_checkin":"[^"]+","last_status":\{"backlog":0,"running":2,"pool_capacity":2,"max_threads":2\}\}\]\}/, body.split("\r\n").last)
assert_match(/\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","workers":2,"phase":0,"booted_workers":2,"old_workers":0,"worker_status":\[\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","pid":\d+,"index":0,"phase":0,"booted":true,"last_checkin":"[^"]+","last_status":\{"backlog":0,"running":2,"pool_capacity":2,"max_threads":2,"requests_count":0\}\},\{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","pid":\d+,"index":1,"phase":0,"booted":true,"last_checkin":"[^"]+","last_status":\{"backlog":0,"running":2,"pool_capacity":2,"max_threads":2,"requests_count":0\}\}\]\}/, body.split("\r\n").last)
ensure
if UNIX_SKT_EXIST && HAS_FORK
cli.launcher.stop
@ -171,7 +171,7 @@ class TestCLI < Minitest::Test
body = s.read
s.close
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16}/, body.split("\r\n").last)
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":0,"running":0,"pool_capacity":16,"max_threads":16,"requests_count":0}/, body.split("\r\n").last)
ensure
if UNIX_SKT_EXIST
cli.launcher.stop
@ -202,6 +202,48 @@ class TestCLI < Minitest::Test
t.join if UNIX_SKT_EXIST
end
def test_control_requests_count
tcp = UniquePort.call
cntl = UniquePort.call
url = "tcp://127.0.0.1:#{cntl}/"
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:#{tcp}",
"--control-url", url,
"--control-token", "",
"test/rackup/lobster.ru"], @events
t = Thread.new do
cli.run
end
wait_booted
s = TCPSocket.new "127.0.0.1", cntl
s << "GET /stats HTTP/1.0\r\n\r\n"
body = s.read
s.close
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":\d+,"running":\d+,"pool_capacity":\d+,"max_threads":\d+,"requests_count":0}/, body.split(/\r?\n/).last)
# send real requests to server
3.times do
s = TCPSocket.new "127.0.0.1", tcp
s << "GET / HTTP/1.0\r\n\r\n"
body = s.read
s.close
end
s = TCPSocket.new "127.0.0.1", cntl
s << "GET /stats HTTP/1.0\r\n\r\n"
body = s.read
s.close
assert_match(/{"started_at":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z","backlog":\d+,"running":\d+,"pool_capacity":\d+,"max_threads":\d+,"requests_count":3}/, body.split(/\r?\n/).last)
ensure
cli.launcher.stop
t.join
end
def test_control_thread_backtraces
skip UNIX_SKT_MSG unless UNIX_SKT_EXIST
url = "unix://#{@tmp_path}"

View file

@ -38,6 +38,14 @@ class WebServerTest < Minitest::Test
assert @tester.ran_test, "Handler didn't really run"
end
def test_requests_count
assert_equal @server.requests_count, 0
3.times do
hit(["http://127.0.0.1:#{@server.connected_port}/test"])
end
assert_equal @server.requests_count, 3
end
def test_trickle_attack
socket = do_test(VALID_REQUEST, 3)
assert_match "hello", socket.read