Support profiling server startup and build via a --profile flag

This commit is contained in:
Ben Hollis 2012-07-18 22:10:02 -07:00
parent 3f21f7bc62
commit 00b590eedb
7 changed files with 81 additions and 6 deletions

View file

@ -7,6 +7,12 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
moredir = File.expand_path(File.join(File.dirname(File.dirname(libdir)), "middleman-more", "lib", "middleman-more")) moredir = File.expand_path(File.join(File.dirname(File.dirname(libdir)), "middleman-more", "lib", "middleman-more"))
$LOAD_PATH.unshift(moredir) unless $LOAD_PATH.include?(moredir) $LOAD_PATH.unshift(moredir) unless $LOAD_PATH.include?(moredir)
require 'middleman-core/profiling'
if ARGV.include? '--profile'
Middleman::Profiling.profiler = Middleman::Profiling::RubyProfProfiler.new
end
Middleman::Profiling.start
require "middleman-core/load_paths" require "middleman-core/load_paths"
Middleman.setup_load_paths Middleman.setup_load_paths
@ -16,4 +22,4 @@ require "middleman-core/cli"
Dir.chdir(ENV["MM_ROOT"]) if ENV["MM_ROOT"] Dir.chdir(ENV["MM_ROOT"]) if ENV["MM_ROOT"]
# Start the CLI # Start the CLI
Middleman::Cli::Base.start Middleman::Cli::Base.start

View file

@ -9,7 +9,6 @@ module Middleman
# The base task from which everything else etends # The base task from which everything else etends
class Base < Thor class Base < Thor
class << self class << self
def start(*args) def start(*args)
# Change flag to a module # Change flag to a module
@ -23,7 +22,7 @@ module Middleman
super super
end end
end end
desc "version", "Show version" desc "version", "Show version"
def version def version
require 'middleman-core/version' require 'middleman-core/version'
@ -87,4 +86,4 @@ require "middleman-core/cli/init"
require "middleman-core/cli/bundler" require "middleman-core/cli/bundler"
require "middleman-core/cli/extension" require "middleman-core/cli/extension"
require "middleman-core/cli/server" require "middleman-core/cli/server"
require "middleman-core/cli/build" require "middleman-core/cli/build"

View file

@ -32,6 +32,10 @@ module Middleman::Cli
:type => :string, :type => :string,
:default => false, :default => false,
:desc => 'Print instrument messages' :desc => 'Print instrument messages'
method_option :profile,
:type => :boolean,
:default => false,
:desc => 'Generate profiling report for the build'
# Core build Thor command # Core build Thor command
# @return [void] # @return [void]
@ -257,6 +261,8 @@ module Middleman::Cli
@cleaning_queue.delete(Pathname.new(output_path).realpath) if cleaning? @cleaning_queue.delete(Pathname.new(output_path).realpath) if cleaning?
end end
::Middleman::Profiling.report("build")
end end
end end

View file

@ -33,7 +33,11 @@ module Middleman::Cli
:type => :boolean, :type => :boolean,
:default => false, :default => false,
:desc => 'Disable the file change and delete watcher process' :desc => 'Disable the file change and delete watcher process'
method_option :profile,
:type => :boolean,
:default => false,
:desc => 'Generate profiling report for server startup'
# Start the server # Start the server
def server def server
require "middleman-core" require "middleman-core"

View file

@ -204,6 +204,7 @@ module Middleman
process_request(env, req, res) process_request(env, req, res)
res.status = 404 res.status = 404
res.finish res.finish
end end
end end

View file

@ -46,7 +46,8 @@ module Middleman
# Save the last-used options so it may be re-used when # Save the last-used options so it may be re-used when
# reloading later on. # reloading later on.
@last_options = options @last_options = options
::Middleman::Profiling.report("server_start")
@webrick.start @webrick.start
end end
end end

View file

@ -0,0 +1,58 @@
module Middleman
module Profiling
# The profiler instance. There can only be one!
def self.profiler=(prof)
@profiler = prof
end
def self.profiler
@profiler ||= NullProfiler.new
end
# Start the profiler
def self.start
profiler.start
end
# Stop the profiler and generate a report. Make sure to call start first
def self.report(report_name)
profiler.report(report_name)
end
# A profiler that does nothing. The default.
class NullProfiler
def start
end
def report
end
end
# A profiler that uses ruby-prof
class RubyProfProfiler
def initialize
begin
require 'ruby-prof'
rescue LoadError
raise "To use the --profile option, you must 'gem install ruby-prof' (and include it in your Gemfile if running under bundle exec)"
end
end
def start
RubyProf.start
end
def report(report_name)
result = RubyProf.stop
printer = RubyProf::GraphHtmlPrinter.new(result)
outfile = File.join("profile", report_name)
outfile = (outfile + '.html') unless outfile.end_with? '.html'
FileUtils.mkdir_p(File.dirname(outfile))
File.open(outfile, 'w') do |f|
printer.print(f, :min_percent=> 1)
end
end
end
end
end