Skip to content
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

Add telemetry events to handlers #25

Closed
wants to merge 6 commits into from
Closed

Add telemetry events to handlers #25

wants to merge 6 commits into from

Conversation

bryannaegele
Copy link

@josevalim can you verify this handles the stop and failure as we intend?

/cc @GregMefford

@bryannaegele
Copy link
Author

bryannaegele commented Mar 4, 2020 via email

@GregMefford
Copy link

Just following up again on this PR because if we won't have something like my PR to Phoenix.Endpoint, then we should get this one released instead. Remaining issues I see:

  1. failure -> exception
  2. plug_cowboy.handler -> plug_adapter.request (I still don't really understand why this is better, but it's up to the maintainers)
  3. If we go with plug_adapter.request, then the metadata should show which adapter it was, and somehow document this structure so that other plug_adapter implementers could know what the expected metadata is.

@GregMefford
Copy link

Oh! I was re-reading José's comment about item 2, that Phoenix has its own version of this handler and that's why we want to make it generic. I was thinking that plug_cowboy was directly used by Phoenix.

Now that I understand, I feel even more strongly that the right path is to just call it what it is: this one is plug_cowboy.* and that one is phoenix.*, so that it's obvious to people where it's coming from. No one will be confused when they switch from Plug to Phoenix or vice-versa and their metrics/traces don't look the same. That's a completely different tech stack even if they look similar, so if you want things to keep working, you'll need to reconfigure what you're tracing or include a different dependency that makes it work properly OoTB for you.

@bryannaegele
Copy link
Author

Is everyone OK with the event name and metadata structuring?

@GregMefford @binaryseed

else
result ->
measurements = %{duration: System.monotonic_time() - start}
:telemetry.execute([:plug_adapter, :request, :stop], measurements, %{name: :plug_cowboy})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd have the updated conn in this event... This is how I did the :stop event in my PR:

https://github.com/elixir-plug/plug_cowboy/pull/27/files#diff-497f9396e978da4bf4bfa189df9f6f13R19-R29

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you see the discussion at #25 (comment)? I'm happy to add it back.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, w/o the conn I'd say this instrumentation is pretty pointless. There'd be no way to aggregate on anything, so we'd just literally get measurements like average request time for every request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the connection to all events then (and in this case it is result). I also propose to rename name: :plug_cowboy to adapter: :plug_cowboy. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the updated conn part of the result? It looks like only req is extracted & returned

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A problem I ran into in my PR is that there's no way that I could figure out to get ahold of an updated conn in the case of an exception being raised.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s return the conn then from try. There is nothing we can do about catch though, it is a non local return.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the issue I ran into with the Tesla PR where you may want to know something about the conn in an exception. If you reference it from there it is the original argument.

Let’s return the conn then from try.

What is the suggestion here? I'm a little confused.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's to assign the result of maybe_send inside the try block & call :telemetry.execute there...

https://github.com/elixir-plug/plug_cowboy/pull/27/files#diff-497f9396e978da4bf4bfa189df9f6f13R19-R28

@@ -4,6 +4,13 @@ defmodule Plug.Cowboy.Handler do
@already_sent {:plug_conn, :sent}

def init(req, {plug, opts}) do
start = System.monotonic_time()

:telemetry.execute([:plug_adapter, :request, :start], %{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh, I don't really understand the event name. I don't see the concept :request really in this library. Plug has an adapter concept, but nothing is explicitly called plug_adapter. Maybe [:plug, :adapter, :handler, :start]?

If I had my way, I'd go with [:plug_cowboy, :handler, :start] since that's a pretty literal mapping of the code that's being executed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is if a handler is a requirement of plug_adapter or just an implementation naming thing here in this library. It would just need to be consistent across adapters. Does anyone know the details?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 As long as it's a static name, I'll live with it

@binaryseed
Copy link
Contributor

I think a test would make sense, here's how I wired up one:

https://github.com/elixir-plug/plug_cowboy/pull/27/files#diff-217f2ca48d3f3e0b4b33f6dea78aeb10

@GregMefford
Copy link

Is there a matching PR for this in Phoenix? I just want to make sure we don’t have some blocker there that means we can’t have consistency, given that there’s a lot of assumptions or intentions to have this be consistent with the equivalent adapter that Phoenix uses.

start = System.monotonic_time()

:telemetry.execute([:plug_adapter, :request, :start], %{
name: :plug_cowboy,
Copy link
Contributor

@binaryseed binaryseed Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like for this execute, name is in the measurements, but for the other one, name is in the metadata. Shouldn't it always be in the metadata?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the conn that is created just below this has important information in it (like the path). I think we should probably include conn in the metadata for the start event

@binaryseed binaryseed mentioned this pull request Apr 20, 2020
@Gazler
Copy link
Member

Gazler commented Apr 25, 2020

I believe this is closed by #31 - feel free to reopen it if I am mistaken though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants