diff --git a/History.md b/History.md index ad105af4..776e6967 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,7 @@ ## Master * Features + * Instrument started_at in /stats (#1844) * Add log_formatter configuration (#1816) * Bugfixes diff --git a/lib/puma/cluster.rb b/lib/puma/cluster.rb index 492db590..658cd5c6 100644 --- a/lib/puma/cluster.rb +++ b/lib/puma/cluster.rb @@ -95,12 +95,13 @@ module Puma @signal = "TERM" @options = options @first_term_sent = nil + @started_at = Time.now @last_checkin = Time.now @last_status = '{}' @dead = false end - attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status + attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at def booted? @stage == :booted @@ -376,8 +377,8 @@ module Puma def stats old_worker_count = @workers.count { |w| w.phase != @phase } booted_worker_count = @workers.count { |w| w.booted? } - worker_status = '[' + @workers.map { |w| %Q!{ "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']' - %Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }! + worker_status = '[' + @workers.map { |w| %Q!{ "started_at": "#{w.started_at.utc.iso8601}", "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']' + %Q!{ "started_at": "#{@started_at.utc.iso8601}", "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }! end def preload? diff --git a/lib/puma/runner.rb b/lib/puma/runner.rb index 213200fb..0c40dcbb 100644 --- a/lib/puma/runner.rb +++ b/lib/puma/runner.rb @@ -14,6 +14,7 @@ module Puma @options = cli.options @app = nil @control = nil + @started_at = Time.now end def daemon? diff --git a/lib/puma/single.rb b/lib/puma/single.rb index 3cc5e4d8..a1673a8e 100644 --- a/lib/puma/single.rb +++ b/lib/puma/single.rb @@ -18,7 +18,7 @@ module Puma r = @server.running || 0 t = @server.pool_capacity || 0 m = @server.max_threads || 0 - %Q!{ "backlog": #{b}, "running": #{r}, "pool_capacity": #{t}, "max_threads": #{m} }! + %Q!{ "started_at": "#{@started_at.utc.iso8601}", "backlog": #{b}, "running": #{r}, "pool_capacity": #{t}, "max_threads": #{m} }! end def restart diff --git a/test/test_cli.rb b/test/test_cli.rb index 571c7999..ec280388 100644 --- a/test/test_cli.rb +++ b/test/test_cli.rb @@ -62,8 +62,8 @@ class TestCLI < Minitest::Test body = s.read s.close - assert_equal '{ "backlog": 0, "running": 0, "pool_capacity": 16, "max_threads": 16 }', body.split(/\r?\n/).last - assert_equal '{ "backlog": 0, "running": 0, "pool_capacity": 16, "max_threads": 16 }', Puma.stats + 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 }/, Puma.stats ensure cli.launcher.stop @@ -101,7 +101,7 @@ class TestCLI < Minitest::Test s = UNIXSocket.new @tmp_path s << "GET /stats HTTP/1.0\r\n\r\n" body = s.read - assert_match(/\{ "workers": 2, "phase": 0, "booted_workers": 2, "old_workers": 0, "worker_status": \[\{ "pid": \d+, "index": 0, "phase": 0, "booted": true, "last_checkin": "[^"]+", "last_status": \{ "backlog":0, "running":2, "pool_capacity":2, "max_threads": 2 \} \},\{ "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 \} \},\{ "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) cli.launcher.stop t.join @@ -125,7 +125,7 @@ class TestCLI < Minitest::Test s << "GET /stats HTTP/1.0\r\n\r\n" body = s.read - assert_equal '{ "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 }/, body.split("\r\n").last cli.launcher.stop t.join