0
+$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
0
+require 'passenger/platform_info'
0
+ attr_accessor :threads
0
+ attr_accessor :vm_size # in KB
0
+ attr_accessor :private_dirty_rss # in KB
0
+ return sprintf("%.1f MB", vm_size / 1024.0)
0
+ def private_dirty_rss_in_mb
0
+ if private_dirty_rss.is_a?(Numeric)
0
+ return sprintf("%.1f MB", private_dirty_rss / 1024.0)
0
+ printf "%-6d %-6d %-6d %-9s %-9s %s\n", pid, ppid, threads,
0
+ vm_size_in_mb, private_dirty_rss_in_mb, name
0
+ apache_processes = list_processes(:exe => PlatformInfo::HTTPD)
0
+ print_process_list_stats(apache_processes)
0
+ passenger_processes = list_processes(:match => /(^Passenger |^Rails:|ApplicationPoolServerExecutable)/)
0
+ print_process_list_stats(passenger_processes)
0
+ if ::Process.uid != 0 && (apache_processes + passenger_processes).any?{ |p| p.private_dirty_rss.nil? }
0
+ puts "*** WARNING: Please run this tool as root. Otherwise the " <<
0
+ "private dirty RSS of processes cannot be determined."
0
+ # Returns a list of Process objects that match the given search criteria.
0
+ # # Search by executable path.
0
+ # list_processes(:exe => '/usr/sbin/apache2')
0
+ # # Search by executable name.
0
+ # list_processes(:name => 'ruby1.8')
0
+ # # Search by process name.
0
+ # list_processes(:match => 'Passenger FrameworkSpawner')
0
+ def list_processes(options)
0
+ name = options[:exe].sub(/.*\/(.*)/, '\1')
0
+ ps = "ps -C '#{name}'"
0
+ ps = "ps -C '#{options[:name]}'"
0
+ raise ArgumentError, "Invalid options."
0
+ list = `#{ps} -o pid,ppid,nlwp,vsz,command`.split("\n")
0
+ p.pid, p.ppid, p.threads, p.vm_size, p.name = line.split(/ +/, 5)
0
+ if p.name !~ /^ps/ && (!options[:match] || p.name.match(options[:match]))
0
+ [:pid, :ppid, :threads, :vm_size].each do |attr|
0
+ p.send("#{attr}=", p.send(attr).to_i)
0
+ p.private_dirty_rss = determine_private_dirty_rss(p.pid)
0
+ # Returns the private dirty RSS for the given process, in KB.
0
+ def determine_private_dirty_rss(pid)
0
+ File.read("/proc/#{pid}/smaps").split("\n").each do |line|
0
+ line =~ /^(Private)_Dirty: +(\d+)/
0
+ rescue Errno::EACCES, Errno::ENOENT
0
+ puts "PID PPID Thrds VM Size Private Name"
0
+ def print_process_list_stats(processes)
0
+ total_private_dirty_rss = 0
0
+ some_private_dirty_rss_cannot_be_determined = false
0
+ if p.private_dirty_rss.is_a?(Numeric)
0
+ total_private_dirty_rss += p.private_dirty_rss
0
+ some_private_dirty_rss_cannot_be_determined = true
0
+ puts "### Processes: #{processes.size}"
0
+ printf "### Total private dirty RSS: %.2f MB", total_private_dirty_rss / 1024.0
0
+ if some_private_dirty_rss_cannot_be_determined
Comments
No one has commented yet.