~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/lib/action_controller/benchmarking.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'benchmark'
2
 
 
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)
9
 
 
10
 
      base.class_eval do
11
 
        alias_method_chain :perform_action, :benchmark
12
 
        alias_method_chain :render, :benchmark
13
 
      end
14
 
    end
15
 
 
16
 
    module ClassMethods
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).
19
 
      #
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
25
 
          result = nil
26
 
          ms = Benchmark.ms { result = use_silence ? silence { yield } : yield }
27
 
          logger.add(log_level, "#{title} (#{('%.1f' % ms)}ms)")
28
 
          result
29
 
        else
30
 
          yield
31
 
        end
32
 
      end
33
 
 
34
 
      # Silences the logger for the duration of the block.
35
 
      def silence
36
 
        old_logger_level, logger.level = logger.level, Logger::ERROR if logger
37
 
        yield
38
 
      ensure
39
 
        logger.level = old_logger_level if logger
40
 
      end
41
 
    end
42
 
 
43
 
    protected
44
 
      def render_with_benchmark(options = nil, extra_options = {}, &block)
45
 
        if logger
46
 
          if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected?
47
 
            db_runtime = ActiveRecord::Base.connection.reset_runtime
48
 
          end
49
 
 
50
 
          render_output = nil
51
 
          @view_runtime = Benchmark.ms { render_output = render_without_benchmark(options, extra_options, &block) }
52
 
 
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
57
 
          end
58
 
 
59
 
          render_output
60
 
        else
61
 
          render_without_benchmark(options, extra_options, &block)
62
 
        end
63
 
      end    
64
 
 
65
 
    private
66
 
      def perform_action_with_benchmark
67
 
        if logger
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?
71
 
 
72
 
          log_message  = 'Completed in %.0fms' % ms
73
 
 
74
 
          if logging_view || logging_active_record
75
 
            log_message << " ("
76
 
            log_message << view_runtime if logging_view
77
 
 
78
 
            if logging_active_record
79
 
              log_message << ", " if logging_view
80
 
              log_message << active_record_runtime + ")"
81
 
            else
82
 
              ")"
83
 
            end
84
 
          end
85
 
 
86
 
          log_message << " | #{response.status}"
87
 
          log_message << " [#{complete_request_uri rescue "unknown"}]"
88
 
 
89
 
          logger.info(log_message)
90
 
          response.headers["X-Runtime"] = "%.0f" % ms
91
 
        else
92
 
          perform_action_without_benchmark
93
 
        end
94
 
      end
95
 
 
96
 
      def view_runtime
97
 
        "View: %.0f" % @view_runtime
98
 
      end
99
 
 
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
105
 
      end
106
 
  end
107
 
end