Module: AppProfiler

Includes:
ActiveSupport::Deprecation::DeprecatedConstantAccessor
Defined in:
lib/app_profiler/server.rb,
lib/app_profiler.rb,
lib/app_profiler/backend.rb,
lib/app_profiler/profile.rb,
lib/app_profiler/railtie.rb,
lib/app_profiler/version.rb,
lib/app_profiler/middleware.rb,
lib/app_profiler/parameters.rb,
lib/app_profiler/yarn/command.rb,
lib/app_profiler/profile/vernier.rb,
lib/app_profiler/profile/stackprof.rb,
lib/app_profiler/request_parameters.rb,
lib/app_profiler/viewer/base_viewer.rb,
lib/app_profiler/backend/base_backend.rb,
lib/app_profiler/storage/base_storage.rb,
lib/app_profiler/storage/file_storage.rb,
lib/app_profiler/yarn/with_speedscope.rb,
lib/app_profiler/middleware/base_action.rb,
lib/app_profiler/middleware/view_action.rb,
lib/app_profiler/backend/vernier_backend.rb,
lib/app_profiler/middleware/upload_action.rb,
lib/app_profiler/viewer/speedscope_viewer.rb,
lib/app_profiler/backend/stackprof_backend.rb,
lib/app_profiler/storage/google_cloud_storage.rb,
lib/app_profiler/viewer/speedscope_remote_viewer.rb,
lib/app_profiler/viewer/speedscope_remote_viewer/middleware.rb,
lib/app_profiler/viewer/speedscope_remote_viewer/base_middleware.rb

Overview

This module provides a means to start a golang-inspired profile server it is implemented using stdlib and Rack to avoid additional dependencies

Defined Under Namespace

Modules: Backend, Server, Storage, Viewer, Yarn Classes: BackendError, BaseProfile, ConfigurationError, Middleware, Parameters, Railtie, RequestParameters, StackprofProfile, VernierProfile

Constant Summary collapse

DefaultProfileFormatter =
proc do |upload|
  "#{AppProfiler.speedscope_host}#profileURL=#{upload.url}"
end
DefaultProfilePrefix =
proc do
  Time.zone.now.strftime("%Y%m%d-%H%M%S")
end
VERSION =
"0.2.0"

Class Method Summary collapse

Class Method Details

.after_process_queue=(handler) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/app_profiler.rb', line 169

def after_process_queue=(handler)
  if handler && (!handler.is_a?(Proc) || (handler.lambda? && handler.arity != 2))
    raise ArgumentError, "after_process_queue must be a proc or a lambda that accepts two arguments"
  end

  @@after_process_queue = handler # rubocop:disable Style/ClassVars
end

.backendObject



126
127
128
129
# File 'lib/app_profiler.rb', line 126

def backend
  @profiler_backend ||= Backend::StackprofBackend
  @profiler_backend.name
end

.backend=(new_backend) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/app_profiler.rb', line 99

def backend=(new_backend)
  return if new_backend == backend

  new_profiler_backend = backend_for(new_backend)

  if running?
    raise BackendError,
      "cannot change backend to #{new_backend} while #{backend} backend is running"
  end

  return if @profiler_backend == new_profiler_backend

  clear
  @profiler_backend = new_profiler_backend
end

.backend_for(backend_name) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/app_profiler.rb', line 115

def backend_for(backend_name)
  if vernier_supported? &&
      backend_name == AppProfiler::Backend::VernierBackend.name
    AppProfiler::Backend::VernierBackend
  elsif backend_name == AppProfiler::Backend::StackprofBackend.name
    AppProfiler::Backend::StackprofBackend
  else
    raise BackendError, "unknown backend #{backend_name}"
  end
end

.profile_data_headerObject



145
146
147
# File 'lib/app_profiler.rb', line 145

def profile_data_header
  @@profile_data_header ||= profile_header.dup << "-Data" # rubocop:disable Style/ClassVars
end

.profile_enqueue_failure=(handler) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/app_profiler.rb', line 161

def profile_enqueue_failure=(handler)
  if handler && (!handler.is_a?(Proc) || (handler.lambda? && handler.arity != 1))
    raise ArgumentError, "profile_enqueue_failure must be a proc or a lambda that accepts one argument"
  end

  @@profile_enqueue_failure = handler # rubocop:disable Style/ClassVars
end

.profile_enqueue_success=(handler) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/app_profiler.rb', line 153

def profile_enqueue_success=(handler)
  if handler && (!handler.is_a?(Proc) || (handler.lambda? && handler.arity != 0))
    raise ArgumentError, "profile_enqueue_success must be proc or a lambda that accepts no argument"
  end

  @@profile_enqueue_success = handler # rubocop:disable Style/ClassVars
end

.profile_header=(profile_header) ⇒ Object



135
136
137
138
139
# File 'lib/app_profiler.rb', line 135

def profile_header=(profile_header)
  @@profile_header = profile_header # rubocop:disable Style/ClassVars
  @@request_profile_header = nil    # rubocop:disable Style/ClassVars
  @@profile_data_header = nil       # rubocop:disable Style/ClassVars
end

.profile_url(upload) ⇒ Object



177
178
179
180
181
# File 'lib/app_profiler.rb', line 177

def profile_url(upload)
  return unless AppProfiler.profile_url_formatter

  AppProfiler.profile_url_formatter.call(upload)
end

.profile_url_formatter=(block) ⇒ Object



149
150
151
# File 'lib/app_profiler.rb', line 149

def profile_url_formatter=(block)
  @@profile_url_formatter = block # rubocop:disable Style/ClassVars
end

.profilerObject



94
95
96
97
# File 'lib/app_profiler.rb', line 94

def profiler
  backend
  @backend ||= @profiler_backend.new
end

.request_profile_headerObject



141
142
143
# File 'lib/app_profiler.rb', line 141

def request_profile_header
  @@request_profile_header ||= profile_header.upcase.tr("-", "_").prepend("HTTP_") # rubocop:disable Style/ClassVars
end

.run(*args, backend: nil, **kwargs, &block) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/app_profiler.rb', line 66

def run(*args, backend: nil, **kwargs, &block)
  orig_backend = self.backend
  begin
    self.backend = backend if backend
    profiler.run(*args, **kwargs, &block)
  rescue BackendError => e
    logger.error(
      "[AppProfiler.run] exception #{e} configuring backend #{backend}: #{e.message}"
    )
    yield
  end
ensure
  AppProfiler.backend = orig_backend
end

.running?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/app_profiler.rb', line 90

def running?
  @backend&.running?
end

.start(*args) ⇒ Object



81
82
83
# File 'lib/app_profiler.rb', line 81

def start(*args)
  profiler.start(*args)
end

.stopObject



85
86
87
88
# File 'lib/app_profiler.rb', line 85

def stop
  profiler.stop
  profiler.results
end

.vernier_supported?Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/app_profiler.rb', line 131

def vernier_supported?
  defined?(AppProfiler::Backend::VernierBackend.name)
end