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

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to