1 revert https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5281
2 hack due https://github.com/ruby-prof/ruby-prof/pull/191
8 gem 'email_reply_parser', '~> 0.5.8'
10 -gem 'ruby-prof', '~> 0.15.9'
13 gem 'activerecord-session_store', '~> 1.0.0'
14 gem 'nested_form', '~> 0.3.2'
22 ruby-progressbar (1.8.1)
27 rubocop-rspec (~> 1.5.0)
28 ruby-fogbugz (~> 0.2.1)
29 - ruby-prof (~> 0.15.9)
33 --- b/app/controllers/admin/requests_profiles_controller.rb
36 -class Admin::RequestsProfilesController < Admin::ApplicationController
38 - @profile_token = Gitlab::RequestProfiler.profile_token
39 - @profiles = Gitlab::RequestProfiler::Profile.all.group_by(&:request_path)
43 - clean_name = Rack::Utils.clean_path_info(params[:name])
44 - profile = Gitlab::RequestProfiler::Profile.find(clean_name)
47 - render text: profile.content
49 - redirect_to admin_requests_profiles_path, alert: 'Profile not found'
53 --- b/app/views/admin/background_jobs/_head.html.haml
54 +++ a/app/views/admin/background_jobs/_head.html.haml
56 = link_to admin_health_check_path, title: 'Health Check' do
59 - = nav_link(controller: :requests_profiles) do
60 - = link_to admin_requests_profiles_path, title: 'Requests Profiles' do
63 --- b/app/views/admin/requests_profiles/index.html.haml
66 -- @no_container = true
67 -- page_title 'Requests Profiles'
68 -= render 'admin/background_jobs/head'
70 -%div{ class: container_class }
74 - .bs-callout.clearfix
76 - %code X-Profile-Token: #{@profile_token}
77 - to profile the request
79 - - if @profiles.present?
80 - .prepend-top-default
81 - - @profiles.each do |path, profiles|
82 - .panel.panel-default.panel-small
86 - - profiles.each do |profile|
88 - = link_to profile.time.to_s(:long), admin_requests_profile_path(profile), data: {no_turbolink: true}
92 --- b/app/views/layouts/nav/_admin.html.haml
93 +++ a/app/views/layouts/nav/_admin.html.haml
95 = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
98 + = nav_link(controller: %w(system_info background_jobs logs health_check)) do
99 - = nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles)) do
100 = link_to admin_system_info_path, title: 'Monitoring' do
103 --- b/app/workers/requests_profiles_worker.rb
106 -class RequestsProfilesWorker
107 - include Sidekiq::Worker
109 - sidekiq_options queue: :default
112 - Gitlab::RequestProfiler.remove_all_profiles
115 --- gitlabhq-8.11.0/config/initializers/request_profiler.rb 2016-08-22 15:27:22.000000000 +0300
116 +++ /dev/null 2007-02-13 18:29:53.000000000 +0200
118 -require 'gitlab/request_profiler/middleware'
120 -Rails.application.configure do |config|
121 - config.middleware.use(Gitlab::RequestProfiler::Middleware)
123 --- b/lib/gitlab/request_profiler.rb
129 - module RequestProfiler
130 - PROFILES_DIR = "#{Gitlab.config.shared.path}/tmp/requests_profiles"
133 - Rails.cache.fetch('profile-token') do
134 - Devise.friendly_token
137 - module_function :profile_token
139 - def remove_all_profiles
140 - FileUtils.rm_rf(PROFILES_DIR)
142 - module_function :remove_all_profiles
145 --- gitlabhq-8.11.0/lib/gitlab/request_profiler/middleware.rb 2016-08-22 15:27:22.000000000 +0300
146 +++ /dev/null 2007-02-13 18:29:53.000000000 +0200
149 -require_dependency 'gitlab/request_profiler'
152 - module RequestProfiler
154 - def initialize(app)
160 - call_with_profiling(env)
167 - header_token = env['HTTP_X_PROFILE_TOKEN']
168 - return unless header_token.present?
170 - profile_token = RequestProfiler.profile_token
171 - return unless profile_token.present?
173 - header_token == profile_token
176 - def call_with_profiling(env)
178 - result = RubyProf::Profile.profile do
179 - ret = catch(:warden) do
184 - printer = RubyProf::CallStackPrinter.new(result)
185 - file_name = "#{env['PATH_INFO'].tr('/', '|')}_#{Time.current.to_i}.html"
186 - file_path = "#{PROFILES_DIR}/#{file_name}"
188 - FileUtils.mkdir_p(PROFILES_DIR)
189 - File.open(file_path, 'wb') do |file|
190 - printer.print(file)
193 - if ret.is_a?(Array)
196 - throw(:warden, ret)
202 --- b/lib/gitlab/request_profiler/profile.rb
206 - module RequestProfiler
208 - attr_reader :name, :time, :request_path
210 - alias_method :to_param, :name
213 - Dir["#{PROFILES_DIR}/*.html"].map do |path|
214 - new(File.basename(path))
218 - def self.find(name)
219 - name_dup = name.dup
220 - name_dup << '.html' unless name.end_with?('.html')
222 - file_path = "#{PROFILES_DIR}/#{name_dup}"
223 - return unless File.exist?(file_path)
228 - def initialize(name)
235 - File.read("#{PROFILES_DIR}/#{name}")
241 - _, path, timestamp = name.split(/(.*)_(\d+)\.html$/)
242 - @request_path = path.tr('|', '/')
243 - @time = Time.at(timestamp.to_i).utc