-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[APM] Fix service maps when root transaction has a parent.id #212998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
80b56a1
4cd8461
0d94bb6
abd1ef6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -176,90 +176,86 @@ export async function fetchServicePathsFromTraceIds({ | |
| } | ||
|
|
||
| def processAndReturnEvent(def context, def eventId) { | ||
| def stack = new Stack(); | ||
| def reprocessQueue = new LinkedList(); | ||
|
|
||
| // Avoid reprocessing the same event | ||
| def pathStack = new Stack(); | ||
| def visited = new HashSet(); | ||
|
|
||
| stack.push(eventId); | ||
| def event = context.eventsById.get(eventId); | ||
|
|
||
| if (event == null) { | ||
| return null; | ||
| } | ||
|
|
||
| pathStack.push(eventId); | ||
|
|
||
| // build a stack with the path from the current event to the root | ||
| def parentId = event['parent.id']; | ||
| while (parentId != null && !parentId.equals(eventId)) { | ||
| def parent = context.eventsById.get(parentId); | ||
| if (parent == null || visited.contains(parentId)) { | ||
| break; | ||
| } | ||
|
|
||
| pathStack.push(parentId); | ||
| visited.add(parentId); | ||
| parentId = parent['parent.id']; | ||
| } | ||
|
|
||
| while (!stack.isEmpty()) { | ||
| def currentEventId = stack.pop(); | ||
| def event = context.eventsById.get(currentEventId); | ||
| // pop the stack starting from the root to current event to build the path | ||
| while (!pathStack.isEmpty()) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the path from current event to root transaction defined, it iterates over the stack from the root transaction up until the current event. |
||
| def currentEventId = pathStack.pop(); | ||
| def currentEvent = context.eventsById.get(currentEventId); | ||
|
|
||
| def basePath = new ArrayList(); | ||
|
|
||
| if (event == null || context.processedEvents.get(currentEventId) != null) { | ||
| if (currentEvent == null || context.processedEvents.get(currentEventId) != null) { | ||
| continue; | ||
| } | ||
| visited.add(currentEventId); | ||
|
|
||
| def service = new HashMap(); | ||
| service['service.name'] = event['service.name']; | ||
| service['service.environment'] = event['service.environment']; | ||
| service['agent.name'] = event['agent.name']; | ||
|
|
||
| def basePath = new ArrayList(); | ||
| def parentId = event['parent.id']; | ||
|
|
||
| if (parentId != null && !parentId.equals(currentEventId)) { | ||
| def parent = context.processedEvents.get(parentId); | ||
|
|
||
| if (parent == null) { | ||
|
|
||
| // Only adds the parentId to the stack if it hasn't been visited to prevent infinite loop scenarios | ||
| // if the parent is null, it means it hasn't been processed yet or it could also mean that the current event | ||
| // doesn't have a parent, in which case we should skip it | ||
| if (!visited.contains(parentId)) { | ||
| stack.push(parentId); | ||
| // Add currentEventId to be reprocessed once its parent is processed | ||
| reprocessQueue.add(currentEventId); | ||
| } | ||
|
|
||
|
|
||
| continue; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the issue. |
||
| } | ||
| service['service.name'] = currentEvent['service.name']; | ||
| service['service.environment'] = currentEvent['service.environment']; | ||
| service['agent.name'] = currentEvent['agent.name']; | ||
|
|
||
| def currentParentId = currentEvent['parent.id']; | ||
| def parent = currentParentId != null ? context.processedEvents.get(currentParentId) : null; | ||
|
|
||
| if (parent != null) { | ||
| // copy the path from the parent | ||
| basePath.addAll(parent.path); | ||
| // flag parent path for removal, as it has children | ||
| context.locationsToRemove.add(parent.path); | ||
|
|
||
| // if the parent has 'span.destination.service.resource' set, and the service is different, we've discovered a service | ||
| if (parent['span.destination.service.resource'] != null | ||
| && parent['span.destination.service.resource'] != "" | ||
| && (parent['service.name'] != event['service.name'] | ||
| || parent['service.environment'] != event['service.environment']) | ||
| && (parent['service.name'] != currentEvent['service.name'] | ||
| || parent['service.environment'] != currentEvent['service.environment']) | ||
| ) { | ||
| def parentDestination = getDestination(parent); | ||
| context.externalToServiceMap.put(parentDestination, service); | ||
| } | ||
| } | ||
|
|
||
| def lastLocation = basePath.size() > 0 ? basePath[basePath.size() - 1] : null; | ||
| def currentLocation = service; | ||
|
|
||
| // only add the current location to the path if it's different from the last one | ||
| if (lastLocation == null || !lastLocation.equals(currentLocation)) { | ||
| basePath.add(currentLocation); | ||
| } | ||
|
|
||
| // if there is an outgoing span, create a new path | ||
| if (event['span.destination.service.resource'] != null | ||
| && !event['span.destination.service.resource'].equals("")) { | ||
| if (currentEvent['span.destination.service.resource'] != null | ||
| && !currentEvent['span.destination.service.resource'].equals("")) { | ||
|
|
||
| def outgoingLocation = getDestination(event); | ||
| def outgoingLocation = getDestination(currentEvent); | ||
| def outgoingPath = new ArrayList(basePath); | ||
| outgoingPath.add(outgoingLocation); | ||
| context.paths.add(outgoingPath); | ||
| } | ||
|
|
||
| event.path = basePath; | ||
| context.processedEvents[currentEventId] = event; | ||
|
|
||
| // reprocess events which were waiting for their parents to be processed | ||
| while (!reprocessQueue.isEmpty()) { | ||
| stack.push(reprocessQueue.remove()); | ||
| } | ||
| currentEvent.path = basePath; | ||
| context.processedEvents[currentEventId] = currentEvent; | ||
| } | ||
|
|
||
| return null; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.