RUM transaction.mark()

Hi,

The RUM API states that a transaction.mark() can be used to set timing marks within a transaction.
However, it seems it can only be used in the context of a startTransaction() and transaction.end(), implying it can only be used for custom transactions. Since the documentation also states that there can only be one transaction at a time, it seems impossible to have a custom transaction run simultaneous with the init() method.

Is there a way to capture timing marks inside the context of an elasticApm.init()?
We'd like to be able to capture specific points in time while taking advantage of init()'s resource and navigation API's metrics.

Use case:

Our web page is divided into header, hero, headline, body, and footer sections.
We'd like to capture the load times by putting some timing marks after each section to see when they load in relation to the full page and DOM timings.

Thanks!

Ronald

I've done two approaches, but neither seem satisfactory.
One, I used transaction = apm.getCurrentTransaction() and then applied transaction.mark() at a pre-determined breakpoint in the HTML, but got a strange timing result as below:


The timing for mark.custom.Abovefold doesn't seem to make sense.

Two, I used a pair of apm.startSpan()s to envelope the section I want to measure, but got another strange result as below:

SpanAboveFoldStart was placed way ahead of loading the two imgur images, but the agent only started measuring the span much later.

Am I missing something or is this a currently unsupported use case? I can technically just put plain JS timing marks captured on variables and sent after the fact, and find a way to correlate with the RUM agent numbers using ingest and correlation keys, but that seems a bit hackish to me.

Hi Ronald,

Thanks for using Elastic APM.

The Page load transactions are a bit different compared to custom transactions since some of the processing needs to happen after the page load event. However, this seems that it could be a bug on our side.

Which version of the RUM agent are you currently using?
Also, would you please provide parts of your code that interacts with the agent?

Cheers,
Hamid

Hi Hamid,

I'm using RUM Agent 4.0
Elastic Stack 6.6.1 (Docker)

Code using transaction.mark() (Approach #1)

<!-- some head stuff -->
<script type="text/javascript" src="elastic-apm-rum.umd.min.js">
    var apm = elasticApm.init({
        serviceName: 'some_service_name',            
        serverUrl: 'http://localhost:8200'
        })
        apm.setInitialPageLoadName("MainPage8")
</script>
</head>
<body> 
<!-- some HTML -->
<!-- more HTML including loading large images from some remote servers -->
<script>
    transaction = apm.getCurrentTransaction();
    transaction.mark("Abovefold")
</script>
<!-- more HTML -->

Code using startSpan() to mark timing breakpoints (Approach #2)

<!-- some head stuff -->
<script type="text/javascript" src="elastic-apm-rum.umd.min.js">
    var apm = elasticApm.init({
        serviceName: 'some_service_name',            
        serverUrl: 'http://localhost:8200'
        })
        apm.setInitialPageLoadName("MainPage8")
</script>
</head>
<body> 
<!-- some HTML -->
<script>
apm.startSpan("SpanAboveFoldStart","mark")
</script>
<!-- more HTML inclkuding loading large images from some remote servers -->
<script>
apm.startSpan("SpanAboveFoldEnd","mark")
</script>
<!-- more HTML -->

Hi Ronald,

Regarding the second use case on start and end span. The images places using tag and how script is placed wont help you measure the accurate timings since the loading order of images is prioritised by the browser and its up to the browser image loader on when and how it would be loaded. If you really want to measure the image loading time inside the span timings, I would encourage you to use Image constructor and use image.onload event for capturing when it was finished. So the code would look something like this

  <script>
    const span = apm.startSpan('abovethefold')
    function onLoad() {
      span.end()
    }
    const image = new Image()
    image.src = 'a.com/image.jpg'
    image.onload = onLoad
  </script>

The above onload handler wont fire when the image is cached, so you have to come up with someother way to deal with it. You would need to use timers and check if image is loaded every now and then if you want to measure properly.`

Regarding the issue about transaction.mark, It does seem to be a bug as Hamid mentioned. We will get back to you soon.

Thanks,
Vignesh

Thanks Vignesh.

We actually tried a simple script to the one you provided and we did encounter problems with cached resources as we have very aggressive cache timings. Additionally, we deem it a little bit intrusive to code as we have to put a lot of those if we want to capture timing marks. Using timing.mark() is really the optimal way.

I guess we'll just need to wait for the bug fix on the transaction.mark() issue.

One thought, have you considered something like a timing annotation for HTML? Something that can be invoked like

<p apmMark="some_label">some content here</p>

We have checked and can confirm its the bug on our side, Issue - Fix custom marks for page load transaction · Issue #221 · elastic/apm-agent-rum-js · GitHub.

One thought, have you considered something like a timing annotation for HTML? Something that can be invoked like

Not really, this would mean traversing the entire html tags which is quite suboptimal and would ideally cause a performance hit. Since there is no ideal solution AFAIK to do this with minimal code, It's best to let the user of the application decide on a solution than provided by the agent internally.

Thanks,
Vignesh

Hi Ronald,

We have just released version 4.0.1 of the RUM agent which should fix this bug.

Would you please update your agent to this version?

Let me know how it works for you.

Cheers,
Hamid

Hi Hamid,

I've tested the new agent and it is now showing more accurate timings. I've put a few marks around the HTML and they show offsetted times indicating these are firing in sequence. Excellent work and as always, we so highly appreciate your fast response on this.

Many thanks!

Ronald

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.