mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 15:48:43 -05:00
Introduce support for dumping Rails process heap at the end of a benchmark run
This commit is contained in:
parent
c273a6d1d4
commit
fb60daa867
4 changed files with 36 additions and 3 deletions
|
@ -18,4 +18,20 @@ class Admin::DiagnosticsController < Admin::AdminController
|
||||||
content_type: Mime::TEXT
|
content_type: Mime::TEXT
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dump_heap
|
||||||
|
begin
|
||||||
|
# ruby 2.1
|
||||||
|
GC.start(full_mark: true)
|
||||||
|
require 'objspace'
|
||||||
|
|
||||||
|
io = File.open("discourse-heap-#{SecureRandom.hex(3)}.json",'w')
|
||||||
|
ObjectSpace.dump_all(:output => io)
|
||||||
|
io.close
|
||||||
|
|
||||||
|
render text: "HEAP DUMP:\n#{io.path}", content_type: Mime::TEXT
|
||||||
|
rescue
|
||||||
|
render text: "HEAP DUMP:\nnot supported", content_type: Mime::TEXT
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
if ENV['DISCOURSE_DUMP_HEAP'] == "1"
|
||||||
|
require 'objspace'
|
||||||
|
ObjectSpace.trace_object_allocations_start
|
||||||
|
end
|
||||||
|
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
||||||
# Set up gems listed in the Gemfile.
|
# Set up gems listed in the Gemfile.
|
||||||
|
|
|
@ -181,6 +181,7 @@ Discourse::Application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
get "memory_stats"=> "diagnostics#memory_stats", constraints: AdminConstraint.new
|
get "memory_stats"=> "diagnostics#memory_stats", constraints: AdminConstraint.new
|
||||||
|
get "dump_heap"=> "diagnostics#dump_heap", constraints: AdminConstraint.new
|
||||||
|
|
||||||
end # admin namespace
|
end # admin namespace
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ require "fileutils"
|
||||||
@best_of = 1
|
@best_of = 1
|
||||||
@mem_stats = false
|
@mem_stats = false
|
||||||
@unicorn = false
|
@unicorn = false
|
||||||
|
@dump_heap = false
|
||||||
|
|
||||||
opts = OptionParser.new do |o|
|
opts = OptionParser.new do |o|
|
||||||
o.banner = "Usage: ruby bench.rb [options]"
|
o.banner = "Usage: ruby bench.rb [options]"
|
||||||
|
@ -26,6 +27,11 @@ opts = OptionParser.new do |o|
|
||||||
o.on("-b", "--best_of [NUM]", "Number of times to run the bench taking best as result") do |i|
|
o.on("-b", "--best_of [NUM]", "Number of times to run the bench taking best as result") do |i|
|
||||||
@best_of = i.to_i
|
@best_of = i.to_i
|
||||||
end
|
end
|
||||||
|
o.on("-d", "--heap_dump") do
|
||||||
|
@dump_heap = true
|
||||||
|
# We need an env var for config/boot.rb to enable allocation tracing prior to framework init
|
||||||
|
ENV['DISCOURSE_DUMP_HEAP'] = "1"
|
||||||
|
end
|
||||||
o.on("-m", "--memory_stats") do
|
o.on("-m", "--memory_stats") do
|
||||||
@mem_stats = true
|
@mem_stats = true
|
||||||
end
|
end
|
||||||
|
@ -103,18 +109,18 @@ end
|
||||||
ENV["RAILS_ENV"] = "profile"
|
ENV["RAILS_ENV"] = "profile"
|
||||||
|
|
||||||
|
|
||||||
gc_env_vars = %w(RUBY_GC_HEAP_INIT_SLOTS RUBY_GC_HEAP_FREE_SLOTS RUBY_GC_HEAP_GROWTH_FACTOR RUBY_GC_HEAP_GROWTH_MAX_SLOTS RUBY_GC_MALLOC_LIMIT RUBY_GC_OLDMALLOC_LIMIT RUBY_GC_MALLOC_LIMIT_MAX RUBY_GC_OLDMALLOC_LIMIT_MAX RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR)
|
discourse_env_vars = %w(DISCOURSE_DUMP_HEAP RUBY_GC_HEAP_INIT_SLOTS RUBY_GC_HEAP_FREE_SLOTS RUBY_GC_HEAP_GROWTH_FACTOR RUBY_GC_HEAP_GROWTH_MAX_SLOTS RUBY_GC_MALLOC_LIMIT RUBY_GC_OLDMALLOC_LIMIT RUBY_GC_MALLOC_LIMIT_MAX RUBY_GC_OLDMALLOC_LIMIT_MAX RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR)
|
||||||
|
|
||||||
if @include_env
|
if @include_env
|
||||||
puts "Running with tuned environment"
|
puts "Running with tuned environment"
|
||||||
ENV["RUBY_GC_MALLOC_LIMIT"] = "50_000_000"
|
ENV["RUBY_GC_MALLOC_LIMIT"] = "50_000_000"
|
||||||
gc_env_vars - %w(RUBY_GC_MALLOC_LIMIT).each do |v|
|
discourse_env_vars - %w(RUBY_GC_MALLOC_LIMIT).each do |v|
|
||||||
ENV.delete v
|
ENV.delete v
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# clean env
|
# clean env
|
||||||
puts "Running with the following custom environment"
|
puts "Running with the following custom environment"
|
||||||
gc_env_vars.each do |w|
|
discourse_env_vars.each do |w|
|
||||||
puts "#{w}: #{ENV[w]}"
|
puts "#{w}: #{ENV[w]}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -256,6 +262,11 @@ begin
|
||||||
puts open("http://127.0.0.1:#{@port}/admin/memory_stats#{append}").read
|
puts open("http://127.0.0.1:#{@port}/admin/memory_stats#{append}").read
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if @dump_heap
|
||||||
|
puts
|
||||||
|
puts open("http://127.0.0.1:#{@port}/admin/dump_heap#{append}").read
|
||||||
|
end
|
||||||
|
|
||||||
if @result_file
|
if @result_file
|
||||||
File.open(@result_file,"wb") do |f|
|
File.open(@result_file,"wb") do |f|
|
||||||
f.write(results)
|
f.write(results)
|
||||||
|
|
Loading…
Reference in a new issue