[Feature] Pass matched route into request environment

Hello :wave:t2:

I’m one of the maintainers of the Prometheus Client Rubygem.

Recently, I’ve been working on some improvements to how we label HTTP metrics (e.g. request counters) with the path of the request being handled. One of the improvements (currently in a PR, but expected to be merged soon) is to use framework-specific route information to build the path label in frameworks where it’s made available.

For example, if you have a Sinatra application with a route like:

get "/examples/:example_id" do
  # some endpoint code
end

we can access "sinatra.route" in the request environment, which will contain "GET /examples/:example_id". We do something similar with Grape’s "grape.routing_args".

The nice part about this, which we can’t replicate without support from the web framework, is that we don’t have to guess which parts of the URL’s path contain dynamic data in order to normalise requests against a particular endpoint into a single path label.

We do have fallback code that attempts to use "PATH_INFO" to do so, by turning any purely numeric path segment into the string ":id" and anything that matches the pattern for a UUID into ":uuid". Naturally, this doesn’t catch all dynamic URL data (someone might use alphanumeric IDs and we wouldn’t match those) and results in placeholders whose names might not match those used in the actual route definition.

I was wondering if the Rails team would be open to adding something similar - an additional key in the environment (I think under the "action_dispatch.*" namespace, but I may be wrong there). It would definitely help us make the out-the-box experience of Prometheus better, and I think it would be useful to anyone writing HTTP request instrumentation for Rails apps.

I’m happy to submit a PR if you think it’s a good idea. My apologies if I’ve missed a Rails feature that already exists. The discovery work I did for this is documented here, in the original feature request we received on the Prometheus Ruby client.

2 Likes

I think it’s a good idea, and any logging/monitoring tool can benefit from having the route

Agreed, this would be a nice change!

I’m maintaining Rails Mini Profiler which currently makes use of PATH_INFO (albeit, much less sophisticated than Prometheus Client) to display request paths, and this proposal would certainly be helpful if implemented.