Class: Rack::PerftoolsProfiler::Profiler

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/perftools_profiler/profiler.rb

Constant Summary collapse

PROFILING_DATA_FILE =
::File.join(self.tmpdir, 'rack_perftools_profiler.prof')
PROFILING_SETTINGS_FILE =
::File.join(self.tmpdir, 'rack_perftools_profiler.config')
DEFAULT_PRINTER =
:text
MODES =
[:cputime, :methods, :objects, :walltime]
DEFAULT_MODE =
:cputime
CHANGEABLE_MODES =
[:methods, :objects]
UNSET_FREQUENCY =
"-1"
DEFAULT_GEMFILE_DIR =
'.'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options) ⇒ Profiler

Returns a new instance of Profiler.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/rack/perftools_profiler/profiler.rb', line 31

def initialize(app, options)
  @printer     = (options.delete(:default_printer) { DEFAULT_PRINTER }).to_sym
  @frequency   = (options.delete(:frequency) { UNSET_FREQUENCY }).to_s
  @mode        = (options.delete(:mode) { DEFAULT_MODE }).to_sym
  @bundler     = (options.delete(:bundler) { false })
  @gemfile_dir = (options.delete(:gemfile_dir) { DEFAULT_GEMFILE_DIR })
  @mode_for_request = nil
  ProfileDataAction.check_printer(@printer)
  ensure_mode_is_valid(@mode)
  # We need to set the enviroment variables before loading perftools
  set_env_vars
  require 'perftools'
  raise ProfilerArgumentError, "Invalid option(s): #{options.keys.join(' ')}" unless options.empty?
end

Class Method Details

.clear_dataObject



53
54
55
# File 'lib/rack/perftools_profiler/profiler.rb', line 53

def self.clear_data
  ::File.delete(PROFILING_DATA_FILE) if ::File.exists?(PROFILING_DATA_FILE)
end

.tmpdirObject



16
17
18
19
20
# File 'lib/rack/perftools_profiler/profiler.rb', line 16

def self.tmpdir
  dir = nil
  Dir.chdir Dir.tmpdir do dir = Dir.pwd end # HACK FOR OSX
  dir
end

Instance Method Details

#data(options = {}) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/rack/perftools_profiler/profiler.rb', line 83

def data(options = {})
  printer = (options.fetch('printer') {@printer}).to_sym
  ignore = options.fetch('ignore') { nil }
  focus = options.fetch('focus') { nil }
  if ::File.exists?(PROFILING_DATA_FILE)
    args = "--#{printer}"
    args += " --ignore=#{ignore}" if ignore
    args += " --focus=#{focus}" if focus
    cmd = "pprof.rb #{args} #{PROFILING_DATA_FILE}"
    cmd = "bundle exec " + cmd if @bundler
    stdout, stderr, status = Dir.chdir(@gemfile_dir) { run(cmd) }
    if status!=0
      raise ProfilingError.new("Running the command '#{cmd}' exited with status #{status}", stderr)
    elsif stdout.length == 0 && stderr.length > 0
      raise ProfilingError.new("Running the command '#{cmd}' failed to generate a file", stderr)
    else
      [printer, stdout]
    end
  else
    [:none, nil]
  end
end

#profile(mode = nil) ⇒ Object



46
47
48
49
50
51
# File 'lib/rack/perftools_profiler/profiler.rb', line 46

def profile(mode = nil)
  start(mode)
  yield
ensure
  stop
end

#profiling?Boolean

Returns:

  • (Boolean)


77
78
79
80
81
# File 'lib/rack/perftools_profiler/profiler.rb', line 77

def profiling?
  pstore_transaction(true) do |store|
    store[:profiling?]
  end
end

#start(mode = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rack/perftools_profiler/profiler.rb', line 57

def start(mode = nil)
  ensure_mode_is_changeable(mode) if mode
  PerfTools::CpuProfiler.stop
  if (mode)
    @mode_for_request = mode
  end  
  unset_env_vars
  set_env_vars
  PerfTools::CpuProfiler.start(PROFILING_DATA_FILE)
  self.profiling = true
ensure
  @mode_for_request = nil
end

#stopObject



71
72
73
74
75
# File 'lib/rack/perftools_profiler/profiler.rb', line 71

def stop
  PerfTools::CpuProfiler.stop
  self.profiling = false
  unset_env_vars
end