Sends performance data to an endpoint in a Brut-powered app that is expected to save it as an Open Telemetry span.
Uses the W3C-recommended headers "traceparent" and "tracestate" to do this.
Supported Metrics
Currently, this will attempt to send "navigation", "largest-contentful-paint", and "first-contentful-paint" back to the server.
Not all browsers support these, so this element will send back as many as it can. It will wait for all supported metrics to be
received before contacting the server. It will attempt to do this exactly once.
Use
To use this element, your page must have a <meta>
element that contains the value for "traceparent". It is expected that your
server will include this in server-generatd HTML. The Brut's Brut::FrontEnd::Components::Traceparent
component will handle this
for you. The value for "traceparent" is key to connecting the browser metrics to the back-end request that generated the page.
The element also requires a url
attribute to know where to send the data. By default, Brut is listening in
/__brut/instrumentation
. See the example.
Durations vs Timestamps
The performance API produces durations since an origin timestamp. Open Telemetry wants timestamps. In theory,
Performance.timeOrigin
is provided by the browser as a reference time when the page started doing anything.
In practice, this value is incorrect on Firefox, so the element records a timestamp when it is created.
When the data is merged back to the server span, the specific timestamps will not exactly match reality, however the durations will
be accurate. Note that even if Performance.timeOrigin
was correct, clock drift between client and server would make
the timestamps inaccurate anyway.
Encoding
The spec for the "tracestate" header leaves open how the data is to be encoded. It supports multiple vendors using a key/value
pair:
tracestate: honeycomb=«encoded data»,newrelic=«encoded data»
This element uses the vendor name "brut". The data is a Base64-encoded JSON blob containing the data.
tracestate: brut=«Base64 encoded JSON»
The values captured and format of the JSON map closely to Open Telemetry's browser instrumentation format.
Of course, this element is many magnitudes smaller in size than Open Telemetry's, which is why it exists at all