akoutmos / prom_ex

An Elixir Prometheus metrics collection library built on top of Telemetry with accompanying Grafana dashboards
MIT License
577 stars 96 forks source link

[BUG] Phoenix plugin: path is lost when router forwards to another router #224

Open leolaudouard opened 8 months ago

leolaudouard commented 8 months ago

When using forward function from a router to forward to another router, the resulting metric will have the first router route as path.

Maybe I missed some documentation on how to configure for this use case, sorry if it is the case.

To Reproduce

I slightly modified the example application to reproduce this issue:

https://github.com/leolaudouard/prom_ex/commit/b5b2ac9400a9bb0a9837297fcc506a09a96ae16d

With these routers, the resulting path is always /users, whereas before we had /users/:id

Expected behavior

Same path values as when the router directly forwards to controllers.

I suppose the issue is around here.

aerosol commented 5 months ago

it seems that also the controller is always the router we forward to, and action is "Unknown"

aerosol commented 5 months ago
plausible_prom_ex_phoenix_http_request_duration_milliseconds_bucket{action="Unknown",controller="PlausibleWeb.Plugins.API.Router",host="localhost",method="GET",path="/api/plugins",status="401",le="+Inf"} 1
aerosol commented 5 months ago

@akoutmos I might have a patch for this, any hints on how to test it? I hope we're not expected to craft https://github.com/aerosol/prom_ex/blob/master/test/support/events/phoenix.exs by hand? 🤢

akoutmos commented 5 months ago

Hey there! Sorry I missed this issue. Those fixtures are automatically generated via https://github.com/akoutmos/prom_ex/blob/master/example_applications/web_app/lib/web_app/recorder_supervisor.ex

The way I have been creating them is by adding that to the example app, enabling only the PromEx plugins I want to test, and then interacting with the app in a way that triggers the telemetry events I want to test.

You can then fetch all of the recorded events via https://github.com/akoutmos/prom_ex/blob/master/example_applications/web_app/lib/web_app/recorder.ex

It's not the easiest thing in the world to work with....but does the job. If you make the fix, I can add to the test suite if that makes it easier :)

aerosol commented 5 months ago

Ugh, it's a bit more involved with the current setup. I've spent a lot of time on this and I don't think I can pull it off reasonably well. Some notes in case someone wants to tackle it:

It's a bit of a vendor lock-in situation 😅 - since we can't stop using PromEx easily (due to existing metrics/graphs in a 3rd party storage that are expensive to replicate/replace), the best solution in terms of effort/reward will be to stop using forward and merge the routers. At least, as long as this library stays up to date with all the optional dependencies it aims to target.

private: %{
  :open_api_spex => %{spec_module: PlausibleWeb.Plugins.API.Spec},
  PlausibleWeb.Router => [],
  PlausibleWeb.Plugins.API.Router => ["api", "plugins"], # <-- derp
  :before_send => [#Function<0.54455629/1 in Plug.Telemetry.call/2>,
   #Function<1.492364/1 in Phoenix.LiveReloader.before_send_inject_reloader/3>],
  :phoenix_endpoint => PlausibleWeb.Endpoint,
  :phoenix_router => PlausibleWeb.Plugins.API.Router,
  :plug_session_fetch => #Function<1.76384852/1 in Plug.Session.fetch_session/1>,
  :phoenix_format => "json"
}

Hope this helps someone who is clever enough.