Skip to content

Commit

Permalink
Log threads as JSON in control app
Browse files Browse the repository at this point in the history
With this commit the status app sends the thread backtraces as an array
of objects with `name` and `backtrace` keys, rather than as a string
matching the SIGINFO output.

While working on this I noticed that we logged the thread TID twice.
This commit simplifies that so we only log the thread TID once, with
both the label (I don't know when the label would get set) and name if
they are available.
  • Loading branch information
composerinteralia committed Nov 11, 2019
1 parent cd91405 commit a344d75
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 20 deletions.
9 changes: 6 additions & 3 deletions lib/puma/app/status.rb
Expand Up @@ -57,9 +57,12 @@ def call(env)
rack_response(200, @cli.stats)

when /\/thread-backtraces$/
strings = Puma::Events.strings
@cli.log_thread_status(strings)
rack_response(200, strings.stdout.string)
backtraces = []
@cli.thread_status do |name, backtrace|
backtraces << { name: name, backtrace: backtrace }
end

rack_response(200, backtraces.to_json)
else
rack_response 404, "Unsupported action", 'text/plain'
end
Expand Down
21 changes: 10 additions & 11 deletions lib/puma/launcher.rb
Expand Up @@ -205,18 +205,14 @@ def close_binder_listeners
@binder.close_listeners
end

def log_thread_status(events)
def thread_status
Thread.list.each do |thread|
events.log "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
logstr = "Thread: TID-#{thread.object_id.to_s(36)}"
logstr += " #{thread.name}" if thread.respond_to?(:name)
events.log logstr
name = "Thread: TID-#{thread.object_id.to_s(36)}"
name += " #{thread['label']}" if thread['label']
name += " #{thread.name}" if thread.respond_to?(:name) && thread.name
backtrace = thread.backtrace || ["<no backtrace available>"]

if thread.backtrace
events.log thread.backtrace.join("\n")
else
events.log "<no backtrace available>"
end
yield name, backtrace
end
end

Expand Down Expand Up @@ -457,7 +453,10 @@ def setup_signals

begin
Signal.trap "SIGINFO" do
log_thread_status(@events)
thread_status do |name, backtrace|
@events.log name
@events.log backtrace
end
end
rescue Exception
# Not going to log this one, as SIGINFO is *BSD only and would be pretty annoying
Expand Down
2 changes: 1 addition & 1 deletion test/test_integration_cluster.rb
Expand Up @@ -44,7 +44,7 @@ def test_siginfo_thread_print
Process.kill :INT , @pid
t.join

assert_match "Thread TID", output.join
assert_match "Thread: TID", output.join
end

def test_usr2_restart
Expand Down
2 changes: 1 addition & 1 deletion test/test_integration_single.rb
Expand Up @@ -99,6 +99,6 @@ def test_siginfo_thread_print
Process.kill :INT , @pid
t.join

assert_match "Thread TID", output.join
assert_match "Thread: TID", output.join
end
end
7 changes: 3 additions & 4 deletions test/test_launcher.rb
Expand Up @@ -57,10 +57,9 @@ def test_puma_wild_location_is_an_absolute_path
end

def test_prints_thread_traces
launcher.log_thread_status(events)
events.stdout.rewind

assert_match "Thread TID", events.stdout.read
launcher.thread_status do |name, _backtrace|
assert_match "Thread: TID", name
end
end

def test_pid_file
Expand Down

0 comments on commit a344d75

Please sign in to comment.