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

Adds Bandit HTTP server support #442

Closed
wants to merge 5 commits into from

Conversation

rodrigocaldeira
Copy link
Contributor

Description

This PR aims to add Bandit HTTP server support to New Relic's Elixir agent.

Suggested changes

  • Inclusion of @bandit_start, @bandit_stop, and @bandit_exception Plug events in plug.ex, each of them corresponding to Bandit's telemetry spans emitted by Bandit.

Motivation

Currently New Relic's Elixir agent supports plug_cowboy adapter only, and by applying the suggested changes to this lib I was able to collect and send web transactions to New Relic normally.

Related issues

Questions

I didn't find any test directly related to NewRelic.Telemetry.Plug module, so I couldn't find a way to check if the suggested changes would break any feature. Also I didn't find any indicator on the debug logs that could tell me if something was wrong during my tests, so any advise on how to create a test to check this is more than welcome!

tpitale
tpitale previously approved these changes Oct 3, 2024
status: status_code(meta),
memory_kb: info[:memory] / @kb,
reductions: info[:reductions],
"bandit.monotonic_time": meas[:monotonic_time] |> to_ms,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Monotonic time only makes sense when used to calculate a duration. It shouldn't be reported as an attribute itself...

Comment on lines +269 to +270
defp get_system_time(%{system_time: system_time}), do: system_time
defp get_system_time(%{monotonic_time: monotonic_time}), do: monotonic_time
Copy link
Collaborator

Choose a reason for hiding this comment

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

We might be conflating these two time types, which are fundamentally different measures. We need to look into the source of both values and make sure we aren't doing that.

I can look closer at this later today...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right @binaryseed .

cowboy uses :erlang.system_time(), on the other hand Bandit uses System.monotonic_time().

Any ideas on how to solve this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looking back on things, I think system_time was probably not necessary to add as an attribute in the first place. The agent already ensures that a start_time is tracked.

It's unlikely that system_time is used, but in the spirit of backward compatibility, I'd suggest that we simply don't include it for Bandit.

You could probably just pass meas to add_start_attrs and only include system_time for cowboy

@tpitale
Copy link
Contributor

tpitale commented Oct 3, 2024

@rodrigocaldeira Would you also be able to take a look at why tests are failing?

@rodrigocaldeira
Copy link
Contributor Author

@rodrigocaldeira Would you also be able to take a look at why tests are failing?

Missing mix format caused that.

@rodrigocaldeira
Copy link
Contributor Author

@rodrigocaldeira Would you also be able to take a look at why tests are failing?

Missing mix format caused that.

Also, I've found the integration tests failed on the command docker-compose up -d defined here:

    - name: Start integration test dependencies
      run: |
        docker-compose up -d
        until pg_isready -h localhost; do sleep 1; done;
        until mysqladmin --protocol tcp ping; do sleep 1; done;

I did change it to docker compose up -d and the integration tests passed.

if NewRelic.Config.enabled?(),
do: DistributedTrace.start(:http, meta.req.headers)
do: DistributedTrace.start(:http, get_headers(meta, server))
Copy link
Collaborator

Choose a reason for hiding this comment

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

We could avoid converting headers to a map twice by gathering the headers into a variable before this line and passing them along to this function and maybe_report_queueing

@binaryseed
Copy link
Collaborator

Ideally we test this along with the other examples...

The simplest way would probably be to add an additional Endpoint to the phx_example application, start it on a different port and configure it to use the Bandit adapter. Then duplicate the phx_example_test.exs and point it at the second endpoint by changing it's request function

@binaryseed
Copy link
Collaborator

I rebased, added tests, and fixed a few issues to this in: #445

@binaryseed
Copy link
Collaborator

Closing in favor of #445 (which includes all of the commits from this PR)

@binaryseed binaryseed closed this Oct 9, 2024
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.

3 participants