diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-27 15:10:12 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-27 15:10:12 +0300 |
commit | 154523302b10ab5aeb67bde861880a98e3f8117a (patch) | |
tree | 3b399e7da80ccc47877c5b6e1491abdcf1019c1b /lib/gitlab/middleware | |
parent | 018e39a9507cc12bee5c6a168641d9843c5a6419 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/middleware')
-rw-r--r-- | lib/gitlab/middleware/speedscope.rb | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/gitlab/middleware/speedscope.rb b/lib/gitlab/middleware/speedscope.rb new file mode 100644 index 00000000000..7eade40c47a --- /dev/null +++ b/lib/gitlab/middleware/speedscope.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Gitlab + module Middleware + class Speedscope + def initialize(app) + @app = app + end + + def call(env) + request = Rack::Request.new(env) + + if request.params['performance_bar'] == 'flamegraph' && Gitlab::PerformanceBar.allowed_for_user?(request.env['warden'].user) + body = nil + + Gitlab::SafeRequestStore[:capturing_flamegraph] = true + + require 'stackprof' + + flamegraph = ::StackProf.run( + mode: :wall, + raw: true, + aggregate: false, + interval: (0.5 * 1000).to_i + ) do + _, _, body = @app.call(env) + end + + path = env['PATH_INFO'].sub('//', '/') + body.close if body.respond_to?(:close) + + return flamegraph(flamegraph, path) + end + + @app.call(env) + end + + def flamegraph(graph, path) + headers = { 'Content-Type' => 'text/html' } + + html = <<~HTML + <!DOCTYPE html> + <html> + <head> + <style> + body { margin: 0; height: 100vh; } + #speedscope-iframe { width: 100%; height: 100%; border: none; } + </style> + </head> + <body> + <script type="text/javascript"> + var graph = #{Gitlab::Json.generate(graph)}; + var json = JSON.stringify(graph); + var blob = new Blob([json], { type: 'text/plain' }); + var objUrl = encodeURIComponent(URL.createObjectURL(blob)); + var iframe = document.createElement('IFRAME'); + iframe.setAttribute('id', 'speedscope-iframe'); + document.body.appendChild(iframe); + var iframeUrl = '#{Gitlab.config.gitlab.relative_url_root}/assets/speedscope/index.html#profileURL=' + objUrl + '&title=' + 'Flamegraph for #{CGI.escape(path)}'; + iframe.setAttribute('src', iframeUrl); + </script> + </body> + </html> + HTML + + [200, headers, [html]] + end + end + end +end |