Open brevalessio24 opened 2 years ago
Hi @brevalessio24,
Thanks for reaching out!
The current RUM implementation doesn't provide support for multiple services with a single agent instance. And if you want multiple instances they should be in different pages (iframes for instance) loading each time the RUM agent.
What we suggested in similar scenarios is to use transaction.addLabels from the transaction API. What this api allows you is to add labels
to transactions and filter based on these labels in the UI.
How to use that API will depend on how the transaction has been created. On one hand you have the ones created because of the automatic instrumentation like user interactions, page-load, xhr/fetch requests, errors, etc and on the other hand the ones manually created (custom transactions)
The former gives you the chance of adding a label leveraging the "end" event:
apm.observe('transaction:end', (transaction) => {
// e.g. look for information in the transaction that can help you to distinguish which application triggered this
// and based on that create a label
transaction.addLabels({ 'custom-label': 'custom-value' })
})
The latter gives more control since you create the transactions manually
const transaction = apm.startTransaction('custom transaction', 'custom')
transaction.addLabels({ 'custom-label': 'custom-value' })
// etc
Thanks, Alberto
Hi Alberto, thank you for the response. We guessed that labels can help distinguish transactions from different souces, but our main concern for the moment is to link the, eg. runtime error, to the correct .map.js file.
Since we have app1.js, app2.js, each has its own .map.js file and we didn't find a method to specify which map file to pick each time. Could this also be achievable with labels somehow?
Hi @brevalessio24,
The Create and upload source maps (RUM) guide indicates in the Kibana section that it is possible to upload more than one sourcemap for your application.
Does the guide help you?
Thanks, Alberto
Hi @brevalessio24 ,
Have you find a workable-solution for this?
Thanks, Alberto
Hi @devcorpio , we tried to follow the guide but it didn't work.
We uploaded an app2.js.map
file for App2 with the shared service_name
and bundle_filepath
pointing to /app2.js
.
Do you know how the match between the .js file and the .js.map file happens?
We supposed it is using service_name
, bundle_filepath
and service_version
to create a match but maybe it is not enough in case of multiple map files.
Thanks, Alessio
Hi @brevalessio24,
Are you able to see the sourcemaps
uploaded in Kibana?
One way to see them is openinghttp://localhost:5601/api/apm/sourcemaps
on your browser (or using the domain you have configured)
I have done tests locally, and I can upload several sourcemaps for the same application:
Main details of the first one:
and main details of the second one:
This test uploads a sourcemap, maybe this can help you too.
Could you share the code that you are using for uploading the sourcemaps?
Btw, If you think that having a look at the kibana code might also help you, then you can also check this and this
Hope this helps.
Thanks, Alberto
Hi @devcorpio, the upload is not the problem, on kibana we find the uploads done correctly
{
"artifacts": [
{
"type": "sourcemap",
"identifier": "fe-mf-notifications-0.2.0-unstable.10",
"relative_url": "/api/fleet/artifacts/fe-mf-notifications-0.2.0-unstable.10/7eb4da36b03b96c134ca6d2fad8eeb2b04592733d65f2a66bd9a55e5d0dec55e",
"body": {
"serviceName": "fe-mf-notifications",
"serviceVersion": "0.2.0-unstable.10",
"bundleFilepath": "[https://example.com/mf/fe-mf-notifications/app.js"](https://example.com/mf/fe-mf-notifications/app.js%22),
"sourceMap": {
"version": 3,
"sources": [],
"names": [ "..." ],
"mappings": "...",
"file": "app.js",
"sourcesContent": [ "..." ],
"sourceRoot": ""
}
},
...
},
{
"type": "sourcemap",
"identifier": "fe-mf-notifications-0.2.0-unstable.11",
"relative_url": "/api/fleet/artifacts/fe-mf-notifications-0.2.0-unstable.11/f1ce169c24dd4cebfe58f24e753f725a743c2323ae07af79874fdea0f6094477",
"body": {
"serviceName": "fe-mf-notifications",
"serviceVersion": "0.2.0-unstable.11",
"bundleFilepath": "[https://example.com/mf/fe-mf-notifications/app.js"](https://example.com/mf/fe-mf-notifications/app.js%22),
"sourceMap": {
"version": 3,
"sources": [ "..."],
"names": [ "..." ],
"mappings": "...",
"file": "app.js",
"sourcesContent": [ "..." ],
"sourceRoot": ""
}
},
...
}
]
}
Above we tried to load a service name for each micro frontend.
The problem is highlighted in apm, we do not see the stacktrace on our "octopus-client" service (the only one we can have).
Then we also tried to load all the micro frontend maps with a single service name (the only registered one) "octopus-client"
{
"type": "sourcemap",
"identifier": "octopus-client-0.2.0-unstable.11",
"relative_url": "/api/fleet/artifacts/octopus-client-0.2.0-unstable.11/9852a7ca370767b6d7519aad75b9c1874b6fee77c82fb9bd633871cacfcff3e4",
"body": {
"serviceName": "octopus-client",
"serviceVersion": "0.2.0-unstable.11",
"bundleFilepath": "[https://example.com/mf/fe-mf-notifications/app.js"](https://example.com/mf/fe-mf-notifications/app.js%22),
"sourceMap": {
"version": 3,
"sources": [ "..."],
"names": [ "... "],
"mappings": "...",
"file": "app.js",
"sourcesContent": ["..."],
"sourceRoot": ""
}
},
...
}
but the result does not change.
In APM how do I match the "maps" and the service name?
Thanks
Hi @elastic/apm-ui,
Would it be possible for someone to help @brevalessio24 with this?
Thanks, Alberto
@devcorpio / @brevalessio24 the apm-server
is responsible to enrich the stachtrace when a source map is found. It uses the service name
and the service version
to find an uploaded source map.
@stuartnelson3 would you know what could be happening on apm-server
that it is not finding the source map?
It uses the service name, service version, and also the path:
https://github.com/elastic/apm-server/blob/main/sourcemap/processor.go#L119-L120
I believe "path" is referring to the bundleFilepath in this case (@simitt can you confirm?).
We uploaded an app2.js.map file for App2 with the shared service_name and bundle_filepath pointing to /app2.js.
I believe it needs to be the full URL, not just /app2.js
.
The example listed is:
"serviceName": "fe-mf-notifications",
"serviceVersion": "0.2.0-unstable.11",
"bundleFilepath": "[https://example.com/mf/fe-mf-notifications/app.js]"
Can you confirm that these are the values being sent with your traces?
You can also turn on debug logging for the apm-server, and check for the incoming request to see what it's trying to match on: https://github.com/elastic/apm-server/blob/main/sourcemap/processor.go#L123
Thanks a lot @cauemarcondes and @stuartnelson3 for your answers!
@brevalessio24 let us know if this helps you.
Thanks, Alberto
I can confirm that we are sending those values along with traces, we'll try with the debug enabled.
Thanks for now.
@brevalessio24 I have forgotten to ask before, apologies. What version of the elastic stack are you using?
Thanks!
@devcorpio the version is 8.1.0 and the APM is server binary (legacy).
The shared bundleFilepath
looks quite odd to me (like a URL in markdown format, but with a replaced "
- look at "[https
vs app.js"]
):
"bundleFilepath": "[https://example.com/mf/fe-mf-notifications/app.js"](https://example.com/mf/fe-mf-notifications/app.js%22)
As @stuartnelson3 pointed out the service.name
, service.version
and path
(== bundlePath
) need to be aligned for the APM Server to find the matching sourcemap.
Can you share a sample document that you expect to have the sourcemap mapping applied, but doesn't (please readact any sensitive information).
Hi @brevalessio24,
Have you had time to check my colleague's comment?
Thanks, Alberto
I have an application shell that loads and mounts X different micro frontends application. Each of them is indipendently deployed and has its own .map file.
My desiderata would be do have X instances of the apm, with different serviceName, working together. I would also like to avoid having the code bundled X times in each micro frontend.
I tried to declare the dependency as external in webpack config, loading the dependency at runtime from unpckg (umd), using System.js and import-maps, but it doesn't seem to work.
Is what I am trying to do achievable somehow? Are there projects in a similar situation, how did they solve the problem?