-
Notifications
You must be signed in to change notification settings - Fork 16
Mark span as APIBoundary if service name differs from parent service … #221
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
625a7e7
57016e7
c0eed4a
8d949f5
ebcb730
060f5eb
034ffff
28b5880
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 |
|---|---|---|
|
|
@@ -272,12 +272,11 @@ private ApiNode<Event> buildApiNode(StructuredTraceGraph graph, Event rootEvent) | |
|
|
||
| private void buildApiNodeEdges(StructuredTraceGraph graph) { | ||
| // 1. get all the exit boundary events from an api node | ||
| // 2. exit boundary events are the only ones which can call a different api node | ||
| // 3. find all the children of exit boundary events, which will be entry boundary nodes of | ||
| // 2. find all the children of exit boundary events, which will be entry boundary nodes of | ||
| // different api nodes | ||
| // 4. find all the api nodes based on children of exit boundary events from | ||
| // 3. find all the api nodes based on children of exit boundary events from | ||
| // `entryBoundaryToApiNode` | ||
| // 5. connect the exit boundary and entry boundary of different api node with an edge | ||
| // 4. connect the exit boundary and entry boundary of different api node with an edge | ||
| for (ApiNode<Event> apiNode : apiNodeList) { | ||
| // exit boundary events of api node | ||
| List<Event> exitBoundaryEvents = apiNode.getExitApiBoundaryEvents(); | ||
|
|
@@ -325,6 +324,42 @@ private void buildApiNodeEdges(StructuredTraceGraph graph) { | |
| } | ||
| } | ||
| } | ||
| // Sometimes an exit span might be missing for services like Istio, Kong. | ||
| // Only Entry spans will be populated for these services, | ||
| // an edge must be created between these services as well. | ||
| // 1. get entry boundary event from an api node. | ||
| // 2. find all the children of entry boundary event, which will be entry boundary nodes of | ||
| // different api nodes | ||
| // 3. Check both parent span and child belong to different service as well. | ||
| // 4. connect the entry boundary of different api nodes with an edge. | ||
| Optional<Event> entryBoundaryEvent = apiNode.getEntryApiBoundaryEvent(); | ||
| if (entryBoundaryEvent.isPresent()) { | ||
| List<Event> children = graph.getChildrenEvents(entryBoundaryEvent.get()); | ||
| if (children != null) { | ||
| for (Event child : children) { | ||
| // if the child of an entry boundary event is an entry api boundary type, | ||
| // which can happen if exit span missing and both belongs to different services. | ||
| if (EnrichedSpanUtils.isEntryApiBoundary(child) | ||
|
Contributor
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. if the exit span is missing how will these two span have parent and child relationship?
Contributor
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. Ignore this, I was assuming that an actual span is missing here which is not the case |
||
| && EnrichedSpanUtils.areBothSpansFromDifferentService( | ||
| child, entryBoundaryEvent.get())) { | ||
| ApiNode<Event> destinationApiNode = entryApiBoundaryEventIdToApiNode.get(child); | ||
| if (LOGGER.isDebugEnabled()) { | ||
| LOGGER.debug( | ||
| "Edge between entry boundaries servicename: {} span: {} to servicename: {} span: {} of trace {}", | ||
| entryBoundaryEvent.get().getServiceName(), | ||
| HexUtils.getHex(entryBoundaryEvent.get().getEventId()), | ||
| child.getServiceName(), | ||
| HexUtils.getHex(child.getEventId()), | ||
| HexUtils.getHex(trace.getTraceId())); | ||
| } | ||
| Optional<ApiNodeEventEdge> edgeBetweenApiNodes = | ||
| createEdgeBetweenApiNodes( | ||
| apiNode, destinationApiNode, entryBoundaryEvent.get(), child); | ||
| edgeBetweenApiNodes.ifPresent(apiNodeEventEdgeList::add); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,11 +83,12 @@ public void enrichEvent(StructuredTrace trace, Event event) { | |
| /* | ||
| Determines if this is entry span is an entry to api | ||
| 1. If the event is an ENTRY span, and | ||
| 2. If the direct parent span is either an EXIT Span or Null, then this is the entry point. | ||
| 2. If the direct parent span is either an EXIT Span or Null, or direct parent span service name differs from current span service name. | ||
| */ | ||
|
|
||
| Event parentEvent = graph.getParentEvent(event); | ||
| if (!EnrichedSpanUtils.isEntrySpan(parentEvent)) { | ||
| if (!EnrichedSpanUtils.isEntrySpan(parentEvent) | ||
|
Contributor
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. Here's a hypothetical: in scenarios where an envoy proxy is injected, usually there will be 2 entry spans back to back and for exits, 2 exit spans back to back. What happens then when the proxy labels the service as "test-service" and the in-app agent labels it with "test-service-foo". Technically, all these spans are in one service, given that a pod is considered as the service but now there will be 2 API boundaries instead of just one.
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. Thanks @tim-mwangi. Is it not possible to fix this ? This change mainly because of multiple gateway spans like Kong, Istio etc which we don't have any control. @davexroth what should we do ?
Contributor
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. Do we have any attributes from Kong, Istio that indicate that span is proxySpan - e.g
Contributor
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. As the boundary between two services (which will have different service labels respectively) are based on (entry, exit) pair, is it safe to assume that two consecutive (entry, entry) or (exit, exit) pairs showing different service labels can possible due to proxy? If, yes, we can consider the below logic for determining entry/exit proxySpan if Should we decorate at proxySpan level or inner service span level for entry API boundary?
we will need merging of spans (proxy + service span) as dependent enrichers eventually if we go with the above logic.
Contributor
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. Discussed offline. I withdraw my concerns. I'm ok with multiple API boundaries if the service name changes.
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. @kotharironak Had offline discussion with Dave and Tim, they have agreed with this change. |
||
| || EnrichedSpanUtils.areBothSpansFromDifferentService(event, parentEvent)) { | ||
| addEnrichedAttribute( | ||
| event, API_BOUNDARY_TYPE_ATTR_NAME, AttributeValueCreator.create(ENTRY_BOUNDARY_TYPE)); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
find all the children of exit boundary eventsis not accurate since we check the children of entry boundary events too nowThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other case updated later in the method, this is the first case.