3
module ActionController #:nodoc:
4
# The benchmarking module times the performance of actions and reports to the logger. If the Active Record
5
# package has been included, a separate timing section for database calls will be added as well.
6
module Benchmarking #:nodoc:
7
def self.included(base)
8
base.extend(ClassMethods)
11
alias_method_chain :perform_action, :benchmark
12
alias_method_chain :render, :benchmark
17
# Log and benchmark the workings of a single block and silence whatever logging that may have happened inside it
18
# (unless <tt>use_silence</tt> is set to false).
20
# The benchmark is only recorded if the current level of the logger matches the <tt>log_level</tt>, which makes it
21
# easy to include benchmarking statements in production software that will remain inexpensive because the benchmark
22
# will only be conducted if the log level is low enough.
23
def benchmark(title, log_level = Logger::DEBUG, use_silence = true)
24
if logger && logger.level == log_level
26
ms = Benchmark.ms { result = use_silence ? silence { yield } : yield }
27
logger.add(log_level, "#{title} (#{('%.1f' % ms)}ms)")
34
# Silences the logger for the duration of the block.
36
old_logger_level, logger.level = logger.level, Logger::ERROR if logger
39
logger.level = old_logger_level if logger
44
def render_with_benchmark(options = nil, extra_options = {}, &block)
46
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
47
db_runtime = ActiveRecord::Base.connection.reset_runtime
51
@view_runtime = Benchmark.ms { render_output = render_without_benchmark(options, extra_options, &block) }
53
if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
54
@db_rt_before_render = db_runtime
55
@db_rt_after_render = ActiveRecord::Base.connection.reset_runtime
56
@view_runtime -= @db_rt_after_render
61
render_without_benchmark(options, extra_options, &block)
66
def perform_action_with_benchmark
68
ms = [Benchmark.ms { perform_action_without_benchmark }, 0.01].max
69
logging_view = defined?(@view_runtime)
70
logging_active_record = Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
72
log_message = 'Completed in %.0fms' % ms
74
if logging_view || logging_active_record
76
log_message << view_runtime if logging_view
78
if logging_active_record
79
log_message << ", " if logging_view
80
log_message << active_record_runtime + ")"
86
log_message << " | #{response.status}"
87
log_message << " [#{complete_request_uri rescue "unknown"}]"
89
logger.info(log_message)
90
response.headers["X-Runtime"] = "%.0f" % ms
92
perform_action_without_benchmark
97
"View: %.0f" % @view_runtime
100
def active_record_runtime
101
db_runtime = ActiveRecord::Base.connection.reset_runtime
102
db_runtime += @db_rt_before_render if @db_rt_before_render
103
db_runtime += @db_rt_after_render if @db_rt_after_render
104
"DB: %.0f" % db_runtime