Skip to content

Commit

Permalink
Add flamegraph path to response headers (#601)
Browse files Browse the repository at this point in the history
* Add flamegraph path to response headers

The motivation for this is to enable easy access to the flamegraph
when using the async-flamegraph action. Currently, if have a CURL
request that you are wanting to profile, you have to add the
`pp=async-flamegraph` query parameter to the request, then copy the
first ID from the `X-MiniProfiler-Ids` header, then add that ID to the
`/mini-profiler-resources/flamegraph?id=` path in the browser.
This assumes that you know that the current request profile id is the
first one in the `X-MiniProfiler-Ids` header (personally I was not
confident of this until I read the source code) and that you know the
path to the flamegraph endpoint.

I originally added the protocol, host, and port to the path, but I
didn't know if that was guaranteed to be correct in all cases, so I
removed it.

* Add note of X-MiniProfiler-Flamegraph-Path header to README
  • Loading branch information
soberstadt authored Feb 14, 2024
1 parent 9081657 commit 263f0d8
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-

Then, to view the flamegraph as a direct HTML response from your request, just visit any page in your app with `?pp=flamegraph` appended to the URL, or add the header `X-Rack-Mini-Profiler` to the request with the value `flamegraph`.

Conversely, if you want your regular response instead (which is specially useful for JSON and/or XHR requests), just append the `?pp=async-flamegraph` parameter to your request/fetch URL; the request will then return as normal, and the flamegraph data will be stored for later *async* viewing, both for this request and for all subsequent requests made by this page (based on the `REFERER` header). For viewing these async flamegraphs, use the 'flamegraph' link that will appear inside the MiniProfiler UI for these requests.
Conversely, if you want your regular response instead (which is specially useful for JSON and/or XHR requests), just append the `?pp=async-flamegraph` parameter to your request/fetch URL; the request will then return as normal, and the flamegraph data will be stored for later *async* viewing, both for this request and for all subsequent requests made by this page (based on the `REFERER` header). For viewing these async flamegraphs, use the 'flamegraph' link that will appear inside the MiniProfiler UI for these requests or path returned in the `X-MiniProfiler-Flamegraph-Path` header.

Note: Mini Profiler will not record SQL timings for a request if it asks for a flamegraph. The rationale behind this is to keep
Mini Profiler's methods that are responsible for generating the timings data out of the flamegraph.
Expand Down Expand Up @@ -466,7 +466,7 @@ If you are using Heroku Redis, you may need to add the following to your `config

```ruby
if Rails.env.production?
Rack::MiniProfiler.config.storage_options = {
Rack::MiniProfiler.config.storage_options = {
url: ENV["REDIS_URL"],
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
}
Expand Down
5 changes: 5 additions & 0 deletions lib/mini_profiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ def inject_profiler(env, status, headers, body)
# inject header
if headers.is_a? Hash
headers['X-MiniProfiler-Ids'] = ids_comma_separated(env)
headers['X-MiniProfiler-Flamegraph-Path'] = flamegraph_path(env) if current.page_struct[:has_flamegraph]
end

if current.inject_js && content_type =~ /text\/html/
Expand Down Expand Up @@ -605,6 +606,10 @@ def ids_comma_separated(env)
ids(env).join(",")
end

def flamegraph_path(env)
@config.base_url_path + 'flamegraph?id=' + current.page_struct[:id]
end

# cancels automatic injection of profile script for the current page
def cancel_auto_inject(env)
current.inject_js = false
Expand Down
4 changes: 3 additions & 1 deletion spec/integration/mini_profiler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ def app
get '/html?pp=async-flamegraph'
expect(last_response).to be_ok
id = last_response.headers['X-MiniProfiler-Ids'].split(",")[0]
get "/mini-profiler-resources/flamegraph?id=#{id}"
flamegraph_path = last_response.headers['X-MiniProfiler-Flamegraph-Path']
expect(flamegraph_path).to eq("/mini-profiler-resources/flamegraph?id=#{id}")
get flamegraph_path
expect(last_response).to be_ok
expect(last_response.body).to include("var graph = {")

Expand Down

0 comments on commit 263f0d8

Please sign in to comment.