On Thu, 2018-02-22 at 10:11 +0100, Karli Sjöberg via freebsd-ports wrote: > On Thu, 2018-02-22 at 07:50 +0100, Karli Sjöberg via freebsd-ports > wrote: > > On Tue, 2018-02-20 at 21:31 +0000, Marcin Cieslak wrote: > > > On Mon, 19 Feb 2018, Karli Sjöberg wrote: > > > > > > > > What is the tool you are trying to deploy? foreman_maintain? > > > > > > Sorry, I was too quick. This foreman_main is used to > > > download/update > > > foreman > > > from RedHat Satellite servers, which is not what you want. > > > > Well, I want the "foreman_maintain" package, which includes > > "passenger- > > recycler", so I guess I do want it :) > > > > > > > > However, the passenger-recycler script is a standalone script > > > which > > > could possibly used with this little fix: > > > > Ooh, awesome! Yeah, should´ve figured since it´s only at 0.1.3 :) > > > > > > > > https://github.com/theforeman/foreman_maintain/pull/143 > > > > > > To apply this, please add files/patch-bin_passenger-recycler in > > > the > > > port I've sent before: > > > > > > --- bin/passenger-recycler.orig 2018-02-20 21:09:18 UTC > > > +++ bin/passenger-recycler > > > @@ -41,10 +41,10 @@ def process_status?(pid) > > > end > > > > > > require 'phusion_passenger' > > > +PhusionPassenger.locate_directories > > > require 'phusion_passenger/platform_info' > > > require 'phusion_passenger/platform_info/ruby' > > > require 'phusion_passenger/admin_tools/memory_stats' > > > -PhusionPassenger.locate_directories > > > stats = PhusionPassenger::AdminTools::MemoryStats.new > > > unless stats.platform_provides_private_dirty_rss_information? > > > puts 'Please run as root or platform unsupported' > > > > Yes, this works, thanks! > > > > > > > > > > > But the real problem is that Passenger does think it supports > > > getting process private dirty RSS memory information only on > > > Linux: > > > > > > https://github.com/phusion/passenger/blob/219ad24159ae4033a342e6a > > > d7 > > > 53 > > > cfee05d98bae0/src/ruby_supportlib/phusion_passenger/admin_tools/m > > > em > > > or > > > y_stats.rb#L121 > > > > > > In file > > > src/ruby_supportlib/phusion_passenger/admin_tools/memory_stats.rb > > > : > > > > > > 120 def platform_provides_private_dirty_rss_information? > > > 121 return os_name_simple == "linux" > > > 122 end > > > > > > This support probably would need to be written. So, > > > unfortunately, > > > passenger-recycler > > > as written will exit with: > > > > > > Please run as root or platform unsupported > > > > Yes, I have now gotten to this stage at least, thank you very much! > > I > > don´t mind having a look at it, it might be simplest thing to > > write, > > or > > it´s hell, but I´ll have a look! > > > > Thank you for pointing me in the right direction! > > > > /K > > > > > > > > But passenger-recycler does something very simple - if the amount > > > of > > > "private resident RSS > > > memory" is higher than specified amount in the configuration > > > file, > > > it > > > kills the process. > > > > > > You might get a much better monitoring on FreeBSD by monitoring > > > the > > > output of > > > > > > procstat -v <processid> > > > > > > which will give you details about the memory usage of the process > > > and > > > see how it is growing > > > over time. Maybe you can pinpoint the shared library that causes > > > this, if you are lucky. > > How do I interpret the output of 'procstat -v <pid>' though? Can I > sum > up all of the RES or PRES numbers to get the total virtual memory > that > this process is consuming?
I hacked at it a bit and came up with an updated patch that includes the changes you made, plus my own. Since "private dirty RSS" isn´t available, I´ve used "maximum RSS" from 'procstat -r <pid>', which is far from perfect, but it´s better than nothing. It now runs and does what you´d expect :) I have attached it to this email. /K > /K Marcin
--- bin/passenger-recycler 2018-02-22 14:19:40.000000000 +0100 +++ bin/passenger-recycler 2018-02-22 14:11:30.034911000 +0100 @@ -41,41 +41,76 @@ end require 'phusion_passenger' +PhusionPassenger.locate_directories require 'phusion_passenger/platform_info' require 'phusion_passenger/platform_info/ruby' require 'phusion_passenger/admin_tools/memory_stats' -PhusionPassenger.locate_directories stats = PhusionPassenger::AdminTools::MemoryStats.new [47/377] -unless stats.platform_provides_private_dirty_rss_information? - puts 'Please run as root or platform unsupported' - exit 1 -end -killed = 0 -stats.passenger_processes.each do |p| - pid = p.pid.to_i - debug "Checking #{pid} with RSS of #{p.private_dirty_rss}" - next unless p.private_dirty_rss > CONFIG[:MAX_PRIV_RSS_MEMORY] - started = begin + +case PhusionPassenger::PlatformInfo.os_name_simple +when "linux" + unless stats.platform_provides_private_dirty_rss_information? + puts 'Please run as root or platform unsupported' + exit 1 + end + killed = 0 + stats.passenger_processes.each do |p| + pid = p.pid.to_i + debug "Checking #{pid} with RSS of #{p.private_dirty_rss}" + next unless p.private_dirty_rss > CONFIG[:MAX_PRIV_RSS_MEMORY] + started = begin `ps -p#{pid} -o start=`.strip rescue StandardError => e verbose "Error: #{e.message} \nReturning '?'" '?' end - status_ps = `ps -p#{pid} -u` - status_all = `passenger-status 2> /dev/null` - status_backtraces = `passenger-status --show=backtraces 2>/dev/null` - verbose "Terminating #{pid} (started #{started}) with private dirty RSS" \ + status_ps = `ps -p#{pid} -u` + status_all = `passenger-status 2> /dev/null` + status_backtraces = `passenger-status --show=backtraces 2>/dev/null` + verbose "Terminating #{pid} (started #{started}) with private dirty RSS" \ " size of #{p.private_dirty_rss} MB" - Process.kill 'SIGUSR1', pid - sleep CONFIG[:GRACEFUL_SHUTDOWN_SLEEP] - kill(pid) - process_status?(pid) - if CONFIG[:SEND_STATUS] - verbose status_ps - verbose status_all - verbose status_backtraces + Process.kill 'SIGUSR1', pid + sleep CONFIG[:GRACEFUL_SHUTDOWN_SLEEP] + kill(pid) + process_status?(pid) + if CONFIG[:SEND_STATUS] + verbose status_ps + verbose status_all + verbose status_backtraces + end + killed += 1 + exit(1) if killed >= CONFIG[:MAX_TERMINATION] + end +when "freebsd" + killed = 0 + stats.passenger_processes.each do |p| + pid = p.pid.to_i + pid_rss = `procstat -r #{pid} | awk '/maximum RSS/{print$5}'`.strip.to_i + pid_rss_mb = sprintf("%.1f", pid_rss / 1024.0) + debug "Checking #{pid} with RSS of #{pid_rss}" + next unless pid_rss > CONFIG[:MAX_PRIV_RSS_MEMORY] + started = begin + `ps -p#{pid} -o start=`.strip + rescue StandardError => e + verbose "Error: #{e.message} \nReturning '?'" + '?' + end + status_ps = `ps -p#{pid} -u` + status_all = `passenger-status 2> /dev/null` + status_backtraces = `passenger-status --show=backtraces 2>/dev/null` + verbose "Terminating #{pid} (started #{started}) with RSS size of" \ + " #{pid_rss_mb} MB" + Process.kill 'SIGUSR1', pid + sleep CONFIG[:GRACEFUL_SHUTDOWN_SLEEP] + kill(pid) + process_status?(pid) + if CONFIG[:SEND_STATUS] + verbose status_ps + verbose status_all + verbose status_backtraces + end + killed += 1 + exit(1) if killed >= CONFIG[:MAX_TERMINATION] end - killed += 1 - exit(1) if killed >= CONFIG[:MAX_TERMINATION] end exit 0
signature.asc
Description: This is a digitally signed message part