Skip to content

Commit

Permalink
Add process RSS to the Busy page, fixes #4717
Browse files Browse the repository at this point in the history
  • Loading branch information
mperham committed Oct 14, 2020
1 parent d081a8a commit 3b5ae30
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Changes.md
Expand Up @@ -2,6 +2,11 @@

[Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)

HEAD
---------

- Add process RSS on the Busy page [#4717]

6.1.2
---------

Expand Down
9 changes: 6 additions & 3 deletions lib/sidekiq/api.rb
Expand Up @@ -791,19 +791,22 @@ def each
# you'll be happier this way
conn.pipelined do
procs.each do |key|
conn.hmget(key, "info", "busy", "beat", "quiet")
conn.hmget(key, "info", "busy", "beat", "quiet", "rss")
end
end
}

result.each do |info, busy, at_s, quiet|
result.each do |info, busy, at_s, quiet, rss|
# If a process is stopped between when we query Redis for `procs` and
# when we query for `result`, we will have an item in `result` that is
# composed of `nil` values.
next if info.nil?

hash = Sidekiq.load_json(info)
yield Process.new(hash.merge("busy" => busy.to_i, "beat" => at_s.to_f, "quiet" => quiet))
yield Process.new(hash.merge("busy" => busy.to_i,
"beat" => at_s.to_f,
"quiet" => quiet,
"rss" => rss))
end
end

Expand Down
27 changes: 26 additions & 1 deletion lib/sidekiq/launcher.rb
Expand Up @@ -154,12 +154,17 @@ def ❤
end

fails = procd = 0
kb = memory_usage(::Process.pid)

_, exists, _, _, msg = Sidekiq.redis { |conn|
conn.multi {
conn.sadd("processes", key)
conn.exists?(key)
conn.hmset(key, "info", to_json, "busy", curstate.size, "beat", Time.now.to_f, "quiet", @done)
conn.hmset(key, "info", to_json,
"busy", curstate.size,
"beat", Time.now.to_f,
"quiet", @done,
"rss", kb)
conn.expire(key, 60)
conn.rpop("#{key}-signals")
}
Expand All @@ -180,6 +185,26 @@ def ❤
end
end

MEMORY_GRABBER = case RUBY_PLATFORM
when /linux/
->(pid) {
IO.readlines("/proc/#{$$}/status").each do |line|
next unless line.start_with?("VmRSS:")
break line.split[1].to_i
end
}
when /darwin|bsd/
->(pid) {
`ps -o pid,rss -p #{pid}`.lines.last.split.last.to_i
}
else
->(pid) { 0 }
end

def memory_usage(pid)
MEMORY_GRABBER.call(pid)
end

def to_data
@data ||= begin
{
Expand Down
12 changes: 12 additions & 0 deletions lib/sidekiq/web/helpers.rb
Expand Up @@ -258,7 +258,19 @@ def retry_extra_items(retry_job)
end
end

def format_memory(rss_kb)
return "" if rss_kb.nil? || rss_kb == 0

if rss_kb < 100_000
"#{number_with_delimiter(rss_kb)} KB"
else
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
end
end

def number_with_delimiter(number)
return "" if number.nil?

begin
Float(number)
rescue ArgumentError, TypeError
Expand Down
8 changes: 8 additions & 0 deletions test/test_launcher.rb
Expand Up @@ -13,6 +13,14 @@ def new_manager(opts)
Sidekiq::Manager.new(opts)
end

describe 'memory collection' do
it 'works in any test environment' do
kb = Sidekiq::Launcher::MEMORY_GRABBER.call($$)
refute_nil kb
assert kb > 0
end
end

describe 'heartbeat' do
before do
@mgr = new_manager(options)
Expand Down
12 changes: 12 additions & 0 deletions web/assets/stylesheets/application.css
Expand Up @@ -1152,3 +1152,15 @@ div.interval-slider input {
.delete-confirm {
width: 20%;
}

.circled {
border-color: #333;
color: #eee;
background-color: #b1003e;
border-radius: 50%;
text-align: center;
vertical-align: middle;
padding: 3px 7px;
font-size: 0.7em;
margin-left: 5px;
}
2 changes: 2 additions & 0 deletions web/views/busy.erb
Expand Up @@ -18,6 +18,7 @@
<thead>
<th><%= t('Name') %></th>
<th><%= t('Started') %></th>
<th><%= t('RSS') %><a href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="circled" title="Click to learn more about RSS">?</span></a></th>
<th><%= t('Threads') %></th>
<th><%= t('Busy') %></th>
<th>&nbsp;</th>
Expand All @@ -42,6 +43,7 @@
<%= process['queues'] * ", " %>
</td>
<td><%= relative_time(Time.at(process['started_at'])) %></td>
<td><%= format_memory(process['rss'].to_i) %></td>
<td><%= process['concurrency'] %></td>
<td><%= process['busy'] %></td>
<td>
Expand Down

0 comments on commit 3b5ae30

Please sign in to comment.