-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
log link to speedscope during gcs upload #47
Conversation
5711b5c
to
87bd1ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this functionality already will basically depend on the url formatter being set to provide useful output, as the default case generates (and apparently, always has) a nonsense URL. For this reason, I'm suggesting simplifying the PR a bit and just checking if the formatter is defined, and if so, call it, leaving the current profile_url
method where it is.
Overall this does look like it will achieve what it sets out to, and make it easier to get the profile URL by relying on the custom formatter being set by the app.
I'd like to defer to @gmcgibbon though as he's a better rubyist than myself and is familiar with this gem. Before rewriting anything, let's hear what he has to say.
lib/app_profiler.rb
Outdated
|
||
def profile_url(upload) | ||
if AppProfiler.profile_url_formatter.nil? | ||
"#{AppProfiler.speedscope_host}#profileURL=#{upload.url}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned on slack, I think this branch path can be misleading, it is likely it will generate URLs that do not work (but this code was already here since the initial import and I guess that was just missed). We more or less require that the profile formatter be given to generate the correct URL, as I am pretty sure this default one will fail in almost every situation.
I think I'd opt for leaving this code where it is, tucked in the middleware module, and then just directly call the formatter if it is defined, since I'd argue the default case here has essentially no value, perhaps even negative value as it will generate wrong URLs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the default case of using a local speedscope instance and filesystem storage. I would prefer if we just made this the default profile_url_formatter
proc eg. mattr_accessor :profile_url_formatter, default: proc { |upload| "#{AppProfiler.speedscope_host}#profileURL=#{upload.url}" }
. This way there are no conditionals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcgibbon ah! that makes sense, i hadn't considered that it would work with a local file and speedscope instance! Thanks for clarifying 👍
lib/app_profiler/profile.rb
Outdated
@@ -41,6 +41,7 @@ def upload | |||
AppProfiler.storage.upload(self).tap do |upload| | |||
if upload && defined?(upload.url) | |||
AppProfiler.logger.info("[Profiler] uploaded profile profile_url=#{upload.url}") | |||
AppProfiler.logger.info("[Profiler] Profile available at profile_url=#{AppProfiler.profile_url(upload)}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if a better approach would be to do the following:
unless AppProfiler.profile_url_formatter.nil?
AppProfiler.logger.info("[Profiler] Profile available at profile_url=#{AppProfiler.profile_url_formatter.call(upload)}")
end
Then add a new test like assert_custom_url_printed_on_upload
that sets the url formatter and checks the output as you have in your existing test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're talking about 2 different things in this log message. The profile_url (the location of the profile on the storage service) and the speedscope_url (the address to actually view the profile). I think this would make more sense:
AppProfiler.logger.info("[Profiler] uploaded profile profile_url=#{upload.url} speedscope_url=#{AppProfiler.profile_url_formatter.call(upload)}")
It would be nice if we could define #speedscope_url
on the upload object, but this would require a larger refactor of the storage services.
lib/app_profiler/profile.rb
Outdated
AppProfiler.logger.info( | ||
"[Profiler] data uploaded: " \ | ||
"profile_url=#{upload.url} " \ | ||
"profile_viewer_url=#{AppProfiler.profile_url_formatter.call(upload)}" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the wording of the log here. Please review and I'll need to update the docs as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AppProfiler.logger.info( | |
"[Profiler] data uploaded: " \ | |
"profile_url=#{upload.url} " \ | |
"profile_viewer_url=#{AppProfiler.profile_url_formatter.call(upload)}" | |
) | |
AppProfiler.logger.info( | |
<<~INFO.squish | |
[Profiler] data uploaded: | |
profile_url=#{upload.url} | |
profile_viewer_url=#{AppProfiler.profile_viewer_url(upload)} | |
INFO | |
) |
Nit: We could use a heredoc for this multiline string instead
@@ -72,5 +75,9 @@ def profile_data_header | |||
def profile_url_formatter=(block) | |||
@@profile_url_formatter = block # rubocop:disable Style/ClassVars | |||
end | |||
|
|||
def profile_url(upload) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def profile_url(upload) | |
def profile_viewer_url(upload) |
If we're going to keep this method, we should name it to distinguish the difference between a profile url and a profile viewer url and use it in lib/app_profiler/profile.rb
too. profile_url_formatter
should also be renamed to profile_viewer_url_formatter
, but we would need to do a deprecation cycle for that (so maybe we could consider doing this in another change).
lib/app_profiler/profile.rb
Outdated
AppProfiler.logger.info( | ||
"[Profiler] data uploaded: " \ | ||
"profile_url=#{upload.url} " \ | ||
"profile_viewer_url=#{AppProfiler.profile_url_formatter.call(upload)}" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AppProfiler.logger.info( | |
"[Profiler] data uploaded: " \ | |
"profile_url=#{upload.url} " \ | |
"profile_viewer_url=#{AppProfiler.profile_url_formatter.call(upload)}" | |
) | |
AppProfiler.logger.info( | |
<<~INFO.squish | |
[Profiler] data uploaded: | |
profile_url=#{upload.url} | |
profile_viewer_url=#{AppProfiler.profile_viewer_url(upload)} | |
INFO | |
) |
Nit: We could use a heredoc for this multiline string instead
@@ -35,7 +35,10 @@ module Viewer | |||
mattr_accessor :autoredirect, default: false | |||
mattr_reader :profile_header, default: "X-Profile" | |||
mattr_accessor :context, default: nil | |||
mattr_reader :profile_url_formatter, default: nil | |||
mattr_reader :profile_url_formatter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mattr_reader :profile_url_formatter, | |
mattr_reader :profile_url_formatter, default: proc do |upload| | |
"#{AppProfiler.speedscope_host}#profileURL=#{upload.url}" | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcgibbon when I use do
instead of braces I'm getting an error
`proc': tried to create Proc object without a block (ArgumentError)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yeah sorry. Let's assign the proc to a constant and then assign the constant to the default.
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
## [Unreleased] | |||
|
|||
[Unreleased]: https://github.com/Shopify/app_profiler | |||
- Log info with link to speedscope during file upload (#47) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Log info with link to speedscope during file upload (#47) | |
- Log info with link to speedscope during file upload (#47) |
08b3ade
to
7ca3f59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after the proc fix. Please squash your commits before merging. Thanks!
PR review pr review make proc a const
a21dc9e
to
9dbfd8a
Compare
Why?
Make it easier to link to the flamegraph in speedscope. When trying to get to the profile I needed to read through the docs and then eventually disturb @dalehamel to get the right link.
How?
middleware/upload_action
into theapp_profiler
and accessed the method fromprofile
Next: can remove the logging from the background queue in core
For reviewers: