Module: ActiveProfiling::RubyProfiler

Extended by:
ActiveSupport::Concern
Included in:
ActiveProfiling
Defined in:
lib/active-profiling/ruby_profiler.rb

Instance Method Summary collapse

Instance Method Details

#ruby_profiler(*args) ⇒ Object

Runs a block of Ruby code through ruby-prof and returns the profiler output. Returns an Array containing the the result of the block yielded and the profiler data.

For details on the various options, see the default options located in ActiveProfiling::Railtie::DEFAULT_PROFILER_OPTIONS.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active-profiling/ruby_profiler.rb', line 12

def ruby_profiler(*args)
  options = Rails.application.config.active_profiling.profiler.merge(args.extract_options!)

  printer_class = case options[:printer]
    when :flat_with_line_numbers
      RubyProf::FlatPrinterWithLineNumbers
    else
      RubyProf.const_get("#{options[:printer].to_s.camelize}Printer")
  end

  output = if options[:output]
    options[:output]
  else
    case options[:printer]
      when :call_tree, :call_stack, :graph_html, :dot
        :file
      else
        :log
    end
  end

  return yield if output == :log && !ActiveProfiling::LogSubscriber.logger

  RubyProf.measure_mode = RubyProf.const_get(options[:measure_mode].to_s.upcase)
  GC.disable if options[:disable_gc]

  result = nil
  profiler_result = RubyProf.profile do
    result = yield
  end

  case output
    when :stdout
      printer_class.new(profiler_result).print($stdout, options.printer_options)
    when :log
      str = StringIO.new
      printer_class.new(profiler_result).print(str, options.printer_options)
      str.rewind

      ActiveSupport::Notifications.instrument('profiler_output.active_profiling', {
        :profiler_output => str.read
      })
    when :file
      path, file_name = if args.first
        [ File.dirname(args.first), args.first ]
      elsif options[:file_name]
        [ File.dirname(options[:file_name]), options[:file_name] ]
      else
        time = Time.now.strftime('%Y-%m-%d-%H:%M:%S')
        hash = Digest::MD5.hexdigest(rand.to_s)[0..6]
        path = Rails.root.join('log/profiling', self.class.name.underscore)
        ext = case options[:printer]
          when :graph_html, :call_stack
            'html'
          when :dot
            'dot'
          else
            'log'
        end

        file_name = [
          self.action_name,
          options[:measure_mode],
          options[:printer],
          time,
          hash,
          ext
        ].join('.')

        if options[:printer] == :call_tree && !options[:call_tree_prefix].blank?
          file_name = "#{options[:call_tree_prefix]}#{file_name}"
        end

        [ path.to_s, path.join(file_name) ]
      end

      ActiveSupport::Notifications.instrument('profiler_output_to_file.active_profiling', {
        :file_name => file_name
      })

      FileUtils.mkdir_p(path)
      printer_class.new(profiler_result).print(File.open(file_name, 'w'), options[:printer_options])
  end

  result
ensure
  GC.enable if options[:disable_gc]
end