#!/usr/bin/env ruby # Phusion Passenger - http://www.modrails.com/ # Copyright (c) 2008, 2009 Phusion # # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib")) $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../ext")) require 'phusion_passenger/admin_tools/control_process' require 'optparse' include PhusionPassenger::AdminTools # ANSI color codes RESET = "\e[0m" BOLD = "\e[1m" YELLOW = "\e[33m" BLACK_BG = "\e[40m" BLUE_BG = "\e[44m" def show_status(control_process, options = {}) case options[:show] when 'pool' begin text = control_process.status rescue SystemCallError => e STDERR.puts "*** ERROR: Cannot query status for Passenger instance #{control_process.pid}:" STDERR.puts e.to_s exit 2 end # Colorize output text.gsub!(/^(----)(.*)$/, YELLOW + BLUE_BG + BOLD + '\1\2' + RESET) puts text when 'backtraces' begin text = control_process.backtraces rescue SystemCallError => e STDERR.puts "*** ERROR: Cannot query status for Passenger instance #{control_process.pid}:" STDERR.puts e.to_s exit 2 end # Colorize output text.gsub!(/^(Thread .*:)$/, BLACK_BG + YELLOW + '\1' + RESET) text.gsub!(/^( +in '.*? )(.*?)\(/, '\1' + BOLD + '\2' + RESET + '(') puts text end end def start options = { :show => 'pool' } parser = OptionParser.new do |opts| opts.banner = "Usage: passenger-status [options] [Phusion Passenger's PID]" opts.separator "" opts.separator "Tool for inspecting Phusion Passenger's internal status." opts.separator "" opts.separator "Options:" opts.on("--show=pool|backtraces", String, "Whether to show the pool's contents or\n" << "#{' ' * 37}the backtraces of all threads.") do |what| if what !~ /\A(pool|backtraces)\Z/ STDERR.puts "Invalid argument for --show." exit 1 else options[:show] = what end end end begin parser.parse! rescue OptionParser::ParseError => e puts e puts puts "Please see '--help' for valid options." exit 1 end if ARGV.empty? control_processes = ControlProcess.list if control_processes.empty? STDERR.puts("ERROR: Phusion Passenger doesn't seem to be running.") exit 2 elsif control_processes.size == 1 show_status(control_processes.first, options) else puts "It appears that multiple Passenger instances are running. Please select a" puts "specific one by running:" puts puts " passenger-status " puts puts "The following Passenger instances are running:" control_processes.each do |control| puts " PID: #{control.pid}" end exit 1 end else show_status(ControlProcess.for_pid(ARGV[0].to_i), options) end end start