2017-06-07 07:57:21 +00:00
|
|
|
module Peek
|
|
|
|
module Rblineprof
|
|
|
|
module CustomControllerHelpers
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
2017-06-09 08:31:38 +00:00
|
|
|
# This will become useless once https://github.com/peek/peek-rblineprof/pull/5
|
|
|
|
# is merged
|
2017-06-07 07:57:21 +00:00
|
|
|
def pygmentize(file_name, code, lexer = nil)
|
|
|
|
if lexer.present?
|
|
|
|
Gitlab::Highlight.highlight(file_name, code)
|
|
|
|
else
|
|
|
|
"<pre>#{Rack::Utils.escape_html(code)}</pre>"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-06-09 08:31:38 +00:00
|
|
|
# rubocop:disable all
|
2017-06-07 07:57:21 +00:00
|
|
|
def inject_rblineprof
|
|
|
|
ret = nil
|
|
|
|
profile = lineprof(rblineprof_profiler_regex) do
|
|
|
|
ret = yield
|
|
|
|
end
|
|
|
|
|
|
|
|
if response.content_type =~ %r|text/html|
|
|
|
|
sort = params[:lineprofiler_sort]
|
|
|
|
mode = params[:lineprofiler_mode] || 'cpu'
|
|
|
|
min = (params[:lineprofiler_min] || 5).to_i * 1000
|
|
|
|
summary = params[:lineprofiler_summary]
|
|
|
|
|
|
|
|
# Sort each file by the longest calculated time
|
|
|
|
per_file = profile.map do |file, lines|
|
2017-06-09 08:31:38 +00:00
|
|
|
total, child, excl, total_cpu, child_cpu, excl_cpu = lines[0]
|
2017-06-07 07:57:21 +00:00
|
|
|
|
|
|
|
wall = summary == 'exclusive' ? excl : total
|
|
|
|
cpu = summary == 'exclusive' ? excl_cpu : total_cpu
|
|
|
|
idle = summary == 'exclusive' ? (excl - excl_cpu) : (total - total_cpu)
|
|
|
|
|
|
|
|
[
|
|
|
|
file, lines,
|
|
|
|
wall, cpu, idle,
|
2017-06-09 08:31:38 +00:00
|
|
|
sort == 'idle' ? idle : sort == 'cpu' ? cpu : wall
|
2017-06-07 07:57:21 +00:00
|
|
|
]
|
2017-06-09 08:31:38 +00:00
|
|
|
end.sort_by{ |a,b,c,d,e,f| -f }
|
2017-06-07 07:57:21 +00:00
|
|
|
|
2018-06-14 16:34:58 +00:00
|
|
|
output = "<div class='modal-dialog modal-xl'><div class='modal-content'>"
|
2017-07-06 19:37:31 +00:00
|
|
|
output << "<div class='modal-header'>"
|
|
|
|
output << "<h4>Line profiling: #{human_description(params[:lineprofiler])}</h4>"
|
2018-05-30 15:30:25 +00:00
|
|
|
output << "<button class='close' type='button' data-dismiss='modal' aria-label='close'><span aria-hidden='true'>×</span></button>"
|
2017-07-06 19:37:31 +00:00
|
|
|
output << "</div>"
|
|
|
|
output << "<div class='modal-body'>"
|
2017-06-09 08:31:38 +00:00
|
|
|
|
2017-07-06 19:37:31 +00:00
|
|
|
per_file.each do |file_name, lines, file_wall, file_cpu, file_idle, file_sort|
|
2017-06-07 07:57:21 +00:00
|
|
|
output << "<div class='peek-rblineprof-file'><div class='heading'>"
|
|
|
|
|
|
|
|
show_src = file_sort > min
|
|
|
|
tmpl = show_src ? "<a href='#' class='js-lineprof-file'>%s</a>" : "%s"
|
|
|
|
|
2017-06-09 08:31:38 +00:00
|
|
|
if mode == 'cpu'
|
|
|
|
output << sprintf("<span class='duration'>% 8.1fms + % 8.1fms</span> #{tmpl}", file_cpu / 1000.0, file_idle / 1000.0, file_name.sub(Rails.root.to_s + '/', ''))
|
|
|
|
else
|
|
|
|
output << sprintf("<span class='duration'>% 8.1fms</span> #{tmpl}", file_wall/1000.0, file_name.sub(Rails.root.to_s + '/', ''))
|
|
|
|
end
|
2017-06-07 07:57:21 +00:00
|
|
|
|
|
|
|
output << "</div>" # .heading
|
|
|
|
|
|
|
|
next unless show_src
|
|
|
|
|
|
|
|
output << "<div class='data'>"
|
|
|
|
code = []
|
|
|
|
times = []
|
|
|
|
File.readlines(file_name).each_with_index do |line, i|
|
|
|
|
code << line
|
|
|
|
wall, cpu, calls = lines[i + 1]
|
|
|
|
|
|
|
|
if calls && calls > 0
|
|
|
|
if mode == 'cpu'
|
|
|
|
idle = wall - cpu
|
|
|
|
times << sprintf("% 8.1fms + % 8.1fms (% 5d)", cpu / 1000.0, idle / 1000.0, calls)
|
|
|
|
else
|
|
|
|
times << sprintf("% 8.1fms (% 5d)", wall / 1000.0, calls)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
times << ' '
|
|
|
|
end
|
|
|
|
end
|
|
|
|
output << "<pre class='duration'>#{times.join("\n")}</pre>"
|
|
|
|
# The following line was changed from
|
|
|
|
# https://github.com/peek/peek-rblineprof/blob/8d3b7a283a27de2f40abda45974516693d882258/lib/peek/rblineprof/controller_helpers.rb#L125
|
2017-06-09 08:31:38 +00:00
|
|
|
# This will become useless once https://github.com/peek/peek-rblineprof/pull/16
|
|
|
|
# is merged and is implemented.
|
2017-06-07 14:51:15 +00:00
|
|
|
output << "<pre class='code highlight white'>#{pygmentize(file_name, code.join, 'ruby')}</pre>"
|
2017-06-07 07:57:21 +00:00
|
|
|
output << "</div></div>" # .data then .peek-rblineprof-file
|
|
|
|
end
|
|
|
|
|
2017-07-06 19:37:31 +00:00
|
|
|
output << "</div></div></div>"
|
|
|
|
|
|
|
|
response.body += "<div class='modal' id='modal-peek-line-profile' tabindex=-1>#{output}</div>".html_safe
|
2017-06-07 07:57:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
ret
|
|
|
|
end
|
2017-07-06 19:37:31 +00:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def human_description(lineprofiler_param)
|
|
|
|
case lineprofiler_param
|
|
|
|
when 'app'
|
|
|
|
'app/ & lib/'
|
|
|
|
when 'views'
|
|
|
|
'app/view/'
|
|
|
|
when 'gems'
|
|
|
|
'vendor/gems'
|
|
|
|
when 'all'
|
|
|
|
'everything in Rails.root'
|
|
|
|
when 'stdlib'
|
|
|
|
'everything in the Ruby standard library'
|
|
|
|
else
|
|
|
|
'app/, config/, lib/, vendor/ & plugin/'
|
|
|
|
end
|
|
|
|
end
|
2017-06-07 07:57:21 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|