newrelic / newrelic/elixir_agent

Problems getting metrics on LiveView async actions

Open
#550 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Elixir
Stars
268
Forks
107
Avg merge
9h 5m
Merged PRs (30d)
2

Description

We have some slow running live actions in production that I am trying to get metrics on.

I think what is happening is that some async operations are not being reported within New Relic so I'm looking for some thoughts or suggestions on how this could be improved. I'm happy to try and make some pull requests where suitable.

The situations appear to be:

1. async_assign

We have a LiveView that is implementing an assign_async during mount:

socket
|> assign_async(:queue_status, fn ->
  {:ok, %{queue_status: fetch_queue_status()}}
end)

In this case, the fetch_queue_status is a long running query. It'll take at least 5 seconds to calculate.

This display in New Relic shows the live action responding in ~20ms. It is not representative of the total loading time for 5+ seconds.

It makes sense to me that the live view transaction would be stopped before the async task completes, so these metrics would not be included, however I am not sure how to actually get these metrics in to New Relic so that we can review and optimise these long running asynchronous tasks.

I have tried manually wrapping the function with:

NewRelic.start_transaction("AssignAsync", "#{socket.view}/queue_status")
# calculate queue status here
NewRelic.stop_transaction()

However, I can't find this transaction anywhere in New Relic.

I see there is an implementation for NewRelic.Instrumented.Task but I'm unsure how to shoehorn this in to assign_async without having to reimplement the function from scratch.

2. live_component

We have an action that will sometimes display a live component that can take several seconds to load:

<.live_component
  module={PoplarWeb.Admin.Moderation.ItemLive}
  locale={@locale}
  id={@item.id}
  item={@item}
  user_id={@user_id}
/>

In this case in New Relic the transaction displays the total render time that I would expect, but it does not include any spans from within the live component so it's not possible to diagnose exactly which part is taking a long time to render.

Having looked at the implementation of telemetry/phoenix_live_view.ex I can see that the traces are hooked in to the telemetry events that Live View publishes.

Is the best approach here to try and hook on the live component telemetry events?

The docs list the following events that don't appear to be implemented:

  • [:phoenix, :live_component, :update, :start]
  • [:phoenix, :live_component, :update, :stop]
  • [:phoenix, :live_component, :handle_event, :start]
  • [:phoenix, :live_component, :handle_event, :stop]
  • [:phoenix, :live_component, :destroyed]

Ideally I want to be able to see the full spans of what is going on within the live component as that would be the most effective for debugging the performance.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with lib/new_relic/telemetry/phoenix_live_view.ex and review the existing LiveView telemetry hooks alongside NewRelic.Instrumented.Task. Compare the assign_async behavior with the listed live_component telemetry events. Done means the relevant asynchronous work and live-component operations produce usable New Relic metrics or spans.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir
Domain
observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.