Add Server Timing middleware#36289
Conversation
|
FYI, This was originally planned for GSoC but it wasn't completed so I asked to @sebasoga to work on this. https://github.com/railsgsoc/ideas/wiki/2018-Ideas#server-timing-middleware /cc @gsamokovarov |
|
See also #36220 |
|
I think we should be merging efforts on #36220 given it is an older PR and the contributor is still active. |
There was a problem hiding this comment.
Since we really don't care about what we are doing here we can just use true instead
|
@guilleiguaran, @jeremy, @rafaelfranca: happy to merge the efforts. I think we both took a different approach so a little bit of direction of how you think the API should look like might help us know what the best way to merge efforts is. Maybe making the events and opt-in the app config could help reduce potential noise: config.server_timing = ["process_action.action_controller"]Would be great if /cc @itsWill |
There was a problem hiding this comment.
This could be events_collection.sum(&:duration) instead of duration_sum(events_collection).
|
It looks like a cool feature. Maybe try to backport it to the older version of Rails? |
What is server timing? It's an specification that defines how the server can communicate the user agent performance metrics about the request it is responding to. Here's the oficinal specification: https://www.w3.org/TR/server-timing/#dfn-server-timing-header-field How does it work? This introduces a new `ServerTiming` middleware only on `development` by default, this is done using the `config.server_timing` setting. It works by subscribing to all `ActiveSupport::Notifications` and adding their duration to the `Server-Timing` header. Why is this useful? It makes looking at perfomance metrics in development much easier, especially when using Chrime devtools which includes the metrics in the Network Inspector. Here's an example:  Paired on this with @guilleiguaran
We only want to be subscribed for the life span of the middleware execution.
We don't really care about what's going on in the block as long as it gets executed.
c8eb8ac to
45c9631
Compare
|
@igorkasyanchuk I'd be glad to give that a try once we settle on an API for this. |
Got [this message](https://github.com/rails/rails/commit/45c9631614437b32af264c3fea3dad0333222456/checks?check_suite_id=390902272): ``` Offenses: actionpack/test/dispatch/server_timing_test.rb:41:3: C: Layout/EmptyLinesAroundAccessModifier: Remove a blank line after private. private ^^^^^^^ 2826 files inspected, 1 offense detected ```
| end | ||
|
|
||
| status, headers, body = @app.call(env) | ||
| ActiveSupport::Notifications.unsubscribe(subscriber) |
There was a problem hiding this comment.
Should we unsubscribe in an ensure block, to ensure we don't leak subscriptions if the @app crashes? 🤔
There was a problem hiding this comment.
@gsamokovarov that makes sense. Are you thinking about something along these lines?
status, headers, body = begin
@app.call(env)
ensure
ActiveSupport::Notifications.unsubscribe(subscriber)
endThere was a problem hiding this comment.
Yes, something like this should work.
| config.consider_all_requests_local = true | ||
|
|
||
| # Enable server timing | ||
| config.server_timing = true |
There was a problem hiding this comment.
What about to make this default for development (also default for framework defaults "6.1" )? That will make it easier to use (it will kick-in on its own once "6.1" defaults are loaded) for upgraded apps as well.
There was a problem hiding this comment.
@simi I think the most sensible is to make this the default on development only. I agree this would be a nice default for apps upgrading to 6.1+. Let's see what people in the core and committers team think about it.
There was a problem hiding this comment.
My idea is to make it default in development only, but without need of explicit configuration entry.
Avoid instantiating an empty array and inserting items into it by using `map`.
f8c6119 to
f888f68
Compare
We want to make sure that if the application during crashes the Server Timing middleware unsubscribes before continuing.
f888f68 to
6d9ce6e
Compare
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
|
I would like to see this feature in a future version of Rails, what else needs to be done? |
|
Hi there! Any news? |
|
@jeremy, @guilleiguaran is there anything I can do to move forward with this? |
|
@SebastianS Could you resolve the merge conflicts and add a changelog entry? |
|
@p8 will do. |
|
@SebastianS sorry for the super-late reply, I've merged this and added the CHANGELOG entry in 54707cb I think we should explain the new configuration variable added to the Configuring Guide: https://guides.rubyonrails.org/configuring.html |
* main: [ci skip] Add Bootstrap and Bulma to the CSS processors' list (#43254) Add missing configuration to middleware test Add ActionDispatch::ServerTiming to the list of middlewares in test Add CHANGELOG entry for ServerTiming middleware [ci skip] Add Server Timing middleware (#36289) Don't overwrite default opts in rich_text_area_tag (#43156) Only call `wrap_parameters` if it's defined (#43259) Suggest a CSP that's compatible with Turbo + import map (#43227) Fix app generator tests Fix docs spacing Fix typo: integer numbers (not integral) Add `beginning_of_week` option to `weekday_options_for_select` Pluralize the heading on the index page generated with scaffold Move the parameter wrapper code to the ActionController::Railtie class Add explicit rendering to DiskController#update Fix update & destroy queries when default_scope is nillable with all_queries: true
Summary
What is server timing?
It's a specification that defines how the server can communicate the
user agent performance metrics about the request it is responding to.
Here's the official specification: https://www.w3.org/TR/server-timing/
How does it work?
This introduces a new
ServerTimingmiddleware only ondevelopmentbydefault, this is done using the
config.server_timingsetting.It works by subscribing to all
ActiveSupport::Notificationsand addingtheir duration to the
Server-Timingheader.Why is this useful?
It makes looking at performance metrics in development much easier,
especially when using Chrome dev tools which include the metrics in the
Network Inspector. Here's an example:
Paired on this with @guilleiguaran