apm-agent-rum-js
apm-agent-rum-js copied to clipboard
infomations of the request headers
Hi, we try to add infos of a request headers to the 'external' span to through overwrite the 'setRequestHeader' method, but we can't associate the request header information with the corresponding span. What can we do?
Hi @zhaoShijuan,
Thank you for using the RUM agent!!
I would need more info in order to help you properly.
Questions:
-
Are you creating the "external" span manually? or is it being created automatically by the agent?
-
What do you mean with "overwrite the 'setRequestHeader' method"? Are you overwriting the native API of the XHR object or are you using the method to add the headers?
-
Could you share the code you have written to achieve the span-header association?
Let me share two examples that may help you somehow, although they assume scenarios that might not be yours, so please, when you have time share with us the information requested above.
I'm also going to assume that your website performs network requests with XHR rather than with Fetch. (since you mentioned setRequestHeader which belongs to XHR)
Example that assumes that span is created manually:
const transaction = elasticApm.startTransaction('test', 'custom')
const url = 'http://localhost:3000/api_test_2'
const httpSpan = transaction.startSpan('GET ' + url, 'external.http')
const xhr = new XMLHttpRequest()
xhr.open('GET', url);
xhr.onload = function () {
httpSpan.addLabels({ 'x-custom-header': "value", 'x-custom-header-2': "value2"})
httpSpan.end()
transaction.end()
}
xhr.send(null)
On the example above you can see how I added labels that correspond to custom headers.
Kibana provides that information when seeing the details of the span
Labels:
Example that assumes that span is created automatically:
You can leverage the transaction:end event to extract the span you are mentioning:
elasticApm.observe("transaction:end", tr => {
if (tr && tr.type === "the type of your transaction") {
const [mySpan] = tr.spans
.filter(span => span.type === 'external' && span.context.http.url === 'your-endpoint-url')
if (!mySpan.context.tags) {
mySpan.context.tags = {}
}
mySpan.context.tags['x-custom-header'] = 'value'
}
})
To be honest, I wouldn't you to recommend to do that since relies on internal API properties and you might have issues in future versions of the RUM agent. Although, if for you it's crucial to have the headers on the span that's the way.
--
Bear in mind that you can also associate the headers to the transaction, too
Thanks, Alberto
Sorry for taking so long to reply!Below is the answer to your questions:
-
The span is created automatically by the agent
-
We want to get the headers
-
We added the following code to
xhr-patch.js,XHR_REQUEST_HEADERis a constant
const setRequestHeaderNative = XMLHttpRequestPrototype.setRequestHeader
XMLHttpRequestPrototype.setRequestHeader = function() {
const args = arguments
this[XHR_REQUEST_HEADER] = {
...this[XHR_REQUEST_HEADER],
[args[0]]: args[1]
}
setRequestHeaderNative.apply(this, args)
}
Hi @zhaoShijuan,
Thanks for providing those details!
Overwriting setRequestHeader will not add the header you want to the "external" span.
--
Since the span is created automatically by the agent the most recommended way you have to add custom information on the fly is using elasticApm.observe.
I don't know the details of your endpoint, but let me put an example with an arbitrary one:
Example:
- endpoint: http://localhost:3000/api_test_2
- header name: "hello"
- header value: "world"
RUM agent allows you to add custom information via labels.
elasticApm.observe("transaction:end", tr => {
const externalSpans = tr.spans.filter(span => {
return span.type === 'external' && span.context.http.url.includes("api_test_2")
})
externalSpans.map(span => {
span.addLabels({ "hello": "world" })
})
})
As you can see at the code above, I'm observing the end of the transaction and:
- extracting all the external spans of such transaction and filtering by the endpoint
- add the header info via labels
The code is just an example, but it's quite lightweight and malleable, so you can modify to meet your requirements if needed
Doing so, you will be able to see the labels on the span details:
You can search spans with such label via Kibana Discover:
and
Thanks, Alberto
Hi @zhaoShijuan,
Have you managed to get this working?
Thanks, Alberto