2006-06-30 16:42:12 -04:00
|
|
|
# Copyright (c) 2005 Zed A. Shaw
|
|
|
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
|
|
|
#
|
|
|
|
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
|
|
|
# for more information.
|
2006-05-21 10:46:42 -04:00
|
|
|
|
2006-03-25 16:15:30 -05:00
|
|
|
require 'logger'
|
|
|
|
require 'set'
|
2006-03-26 15:01:50 -05:00
|
|
|
require 'socket'
|
2006-03-25 16:15:30 -05:00
|
|
|
|
2006-08-17 18:05:28 -04:00
|
|
|
|
|
|
|
|
2006-03-25 16:15:30 -05:00
|
|
|
$mongrel_debugging=true
|
|
|
|
|
|
|
|
module MongrelDbg
|
|
|
|
SETTINGS = { :tracing => {}}
|
|
|
|
LOGGING = { }
|
|
|
|
|
2006-08-17 18:05:28 -04:00
|
|
|
def MongrelDbg::configure(log_dir = File.join("log","mongrel_debug"))
|
2006-03-25 16:15:30 -05:00
|
|
|
Dir.mkdir(log_dir) if not File.exist?(log_dir)
|
|
|
|
@log_dir = log_dir
|
2006-08-17 18:05:28 -04:00
|
|
|
$objects_out=open(File.join("log","mongrel_debug","objects.log"),"w")
|
2006-08-25 23:05:05 -04:00
|
|
|
$objects_out.puts "run,classname,last,count,delta,lenmean,lensd,lenmax"
|
2006-08-17 18:05:28 -04:00
|
|
|
$objects_out.sync = true
|
|
|
|
$last_stat = nil
|
|
|
|
$run_count = 0
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def MongrelDbg::trace(target, message)
|
2006-03-26 15:01:50 -05:00
|
|
|
if SETTINGS[:tracing][target] and LOGGING[target]
|
2006-03-25 16:15:30 -05:00
|
|
|
LOGGING[target].log(Logger::DEBUG, message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def MongrelDbg::begin_trace(target)
|
|
|
|
SETTINGS[:tracing][target] = true
|
|
|
|
if not LOGGING[target]
|
|
|
|
LOGGING[target] = Logger.new(File.join(@log_dir, "#{target.to_s}.log"))
|
|
|
|
end
|
|
|
|
MongrelDbg::trace(target, "TRACING ON #{Time.now}")
|
|
|
|
end
|
|
|
|
|
|
|
|
def MongrelDbg::end_trace(target)
|
|
|
|
SETTINGS[:tracing][target] = false
|
|
|
|
MongrelDbg::trace(target, "TRACING OFF #{Time.now}")
|
|
|
|
LOGGING[target].close
|
|
|
|
LOGGING[target] = nil
|
|
|
|
end
|
2006-03-26 15:01:50 -05:00
|
|
|
|
|
|
|
def MongrelDbg::tracing?(target)
|
|
|
|
SETTINGS[:tracing][target]
|
|
|
|
end
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
|
|
|
|
$open_files = {}
|
2006-03-25 16:15:30 -05:00
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
class IO
|
|
|
|
alias_method :orig_open, :open
|
|
|
|
alias_method :orig_close, :close
|
|
|
|
|
|
|
|
def open(*arg, &blk)
|
|
|
|
$open_files[self] = args.inspect
|
|
|
|
orig_open(*arg,&blk)
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
def close(*arg,&blk)
|
|
|
|
$open_files.delete self
|
|
|
|
orig_close(*arg,&blk)
|
|
|
|
end
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
|
|
|
|
module Kernel
|
|
|
|
alias_method :orig_open, :open
|
|
|
|
|
|
|
|
def open(*arg, &blk)
|
|
|
|
$open_files[self] = arg[0]
|
|
|
|
orig_open(*arg,&blk)
|
|
|
|
end
|
|
|
|
|
|
|
|
def log_open_files
|
2006-04-03 22:07:30 -04:00
|
|
|
open_counts = {}
|
|
|
|
$open_files.each do |f,args|
|
|
|
|
open_counts[args] ||= 0
|
|
|
|
open_counts[args] += 1
|
2006-03-26 15:01:50 -05:00
|
|
|
end
|
2006-04-03 22:07:30 -04:00
|
|
|
MongrelDbg::trace(:files, open_counts.to_yaml)
|
2006-03-26 15:01:50 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module RequestLog
|
2006-04-01 03:43:30 -05:00
|
|
|
|
|
|
|
# Just logs whatever requests it gets to STDERR (which ends up in the mongrel
|
|
|
|
# log when daemonized).
|
|
|
|
class Access < GemPlugin::Plugin "/handlers"
|
|
|
|
include Mongrel::HttpHandlerPlugin
|
|
|
|
|
|
|
|
def process(request,response)
|
|
|
|
p = request.params
|
2006-04-08 14:00:35 -04:00
|
|
|
STDERR.puts "#{p['REMOTE_ADDR']} - [#{Time.now.httpdate}] \"#{p['REQUEST_METHOD']} #{p["REQUEST_URI"]} HTTP/1.1\""
|
2006-04-01 03:43:30 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
class Files < GemPlugin::Plugin "/handlers"
|
|
|
|
include Mongrel::HttpHandlerPlugin
|
|
|
|
|
|
|
|
def process(request, response)
|
|
|
|
MongrelDbg::trace(:files, "#{Time.now} FILES OPEN BEFORE REQUEST #{request.params['PATH_INFO']}")
|
|
|
|
log_open_files
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2006-08-17 18:05:28 -04:00
|
|
|
# stolen from Robert Klemme
|
2006-03-26 15:01:50 -05:00
|
|
|
class Objects < GemPlugin::Plugin "/handlers"
|
|
|
|
include Mongrel::HttpHandlerPlugin
|
2006-08-17 18:05:28 -04:00
|
|
|
|
|
|
|
def process(request,response)
|
2006-08-25 23:05:05 -04:00
|
|
|
begin
|
|
|
|
stats = Hash.new(0)
|
|
|
|
lengths = {}
|
|
|
|
ObjectSpace.each_object do |o|
|
|
|
|
begin
|
|
|
|
if o.respond_to? :length
|
|
|
|
len = o.length
|
2006-09-22 04:16:54 -04:00
|
|
|
lengths[o.class] ||= Mongrel::Stats.new(o.class)
|
2006-08-25 23:05:05 -04:00
|
|
|
lengths[o.class].sample(len)
|
|
|
|
end
|
|
|
|
rescue Object
|
|
|
|
end
|
|
|
|
|
|
|
|
stats[o.class] += 1
|
|
|
|
end
|
|
|
|
|
|
|
|
stats.sort {|(k1,v1),(k2,v2)| v2 <=> v1}.each do |k,v|
|
|
|
|
if $last_stat
|
|
|
|
delta = v - $last_stat[k]
|
|
|
|
if v > 10 and delta != 0
|
|
|
|
if lengths[k]
|
|
|
|
$objects_out.printf "%d,%s,%d,%d,%d,%f,%f,%f\n", $run_count, k, $last_stat[k], v, delta,lengths[k].mean,lengths[k].sd,lengths[k].max
|
|
|
|
else
|
|
|
|
$objects_out.printf "%d,%s,%d,%d,%d,,,\n", $run_count, k, $last_stat[k], v, delta
|
|
|
|
end
|
|
|
|
end
|
2006-08-17 18:05:28 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2006-08-25 23:05:05 -04:00
|
|
|
$run_count += 1
|
|
|
|
$last_stat = stats
|
|
|
|
rescue Object
|
|
|
|
STDERR.puts "object.log ERROR: #$!"
|
|
|
|
end
|
2006-03-26 15:01:50 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Params < GemPlugin::Plugin "/handlers"
|
|
|
|
include Mongrel::HttpHandlerPlugin
|
2006-08-17 18:05:28 -04:00
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
def process(request, response)
|
|
|
|
MongrelDbg::trace(:rails, "#{Time.now} REQUEST #{request.params['PATH_INFO']}")
|
|
|
|
MongrelDbg::trace(:rails, request.params.to_yaml)
|
|
|
|
end
|
|
|
|
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
2006-04-05 08:29:23 -04:00
|
|
|
|
|
|
|
class Threads < GemPlugin::Plugin "/handlers"
|
|
|
|
include Mongrel::HttpHandlerPlugin
|
2006-08-17 18:05:28 -04:00
|
|
|
|
2006-04-05 08:29:23 -04:00
|
|
|
def process(request, response)
|
|
|
|
MongrelDbg::trace(:threads, "#{Time.now} REQUEST #{request.params['PATH_INFO']}")
|
|
|
|
ObjectSpace.each_object do |obj|
|
2006-06-09 01:01:26 -04:00
|
|
|
begin
|
|
|
|
if obj.class == Mongrel::HttpServer
|
|
|
|
worker_list = obj.workers.list
|
2006-04-05 08:29:23 -04:00
|
|
|
|
2006-06-09 01:01:26 -04:00
|
|
|
if worker_list.length > 0
|
|
|
|
keys = "-----\n\tKEYS:"
|
|
|
|
worker_list.each {|t| keys << "\n\t\t-- #{t}: #{t.keys.inspect}" }
|
|
|
|
end
|
2006-04-05 08:29:23 -04:00
|
|
|
|
2006-06-09 01:01:26 -04:00
|
|
|
MongrelDbg::trace(:threads, "#{obj.host}:#{obj.port} -- THREADS: #{worker_list.length} #{keys}")
|
|
|
|
end
|
|
|
|
rescue Object
|
|
|
|
# ignore since obj.class can sometimes take parameters
|
2006-04-05 08:29:23 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2006-03-25 16:15:30 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2006-03-26 15:01:50 -05:00
|
|
|
END {
|
2006-04-05 08:29:23 -04:00
|
|
|
MongrelDbg::trace(:files, "FILES OPEN AT EXIT")
|
|
|
|
log_open_files
|
2006-03-26 15:01:50 -05:00
|
|
|
}
|