Skip to content

fix: optimize the usage of ApiTraceGraph in the ingestion pipeline#195

Merged
kotharironak merged 6 commits intomainfrom
optimize-api-trace-graph
May 24, 2021
Merged

fix: optimize the usage of ApiTraceGraph in the ingestion pipeline#195
kotharironak merged 6 commits intomainfrom
optimize-api-trace-graph

Conversation

@kotharironak
Copy link
Copy Markdown
Contributor

Description

As part of looking into handling large traces, we have observed a couple of optimization in our ingestion pipeline as described here - hypertrace/hypertrace#244

This PR addresses

  • addresses the issue of building ApiTraceGraph across enricher for once if the trace has not modified. (Case 2 of the above ticket)
  • it also modifies ApiTraceGraph internal Map data structure to use Id based index instead of using the entire object

Testing

  • local testing by ingesting traces to docker-compose setup

@codecov
Copy link
Copy Markdown

codecov bot commented May 21, 2021

Codecov Report

Merging #195 (3d9b21d) into main (2123371) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##               main     #195   +/-   ##
=========================================
  Coverage     78.92%   78.92%           
  Complexity     1128     1128           
=========================================
  Files           101      101           
  Lines          4370     4370           
  Branches        406      406           
=========================================
  Hits           3449     3449           
  Misses          732      732           
  Partials        189      189           
Flag Coverage Δ Complexity Δ
unit 78.92% <100.00%> (ø) 1128.00 <14.00> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ Complexity Δ
...ichment/enrichers/ErrorsAndExceptionsEnricher.java 86.66% <100.00%> (ø) 19.00 <8.00> (ø)
...richer/enrichment/enrichers/ExitCallsEnricher.java 100.00% <100.00%> (ø) 8.00 <2.00> (ø)
...nrichment/enrichers/endpoint/EndpointEnricher.java 78.16% <100.00%> (ø) 15.00 <4.00> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2123371...3d9b21d. Read the comment docs.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@kotharironak
Copy link
Copy Markdown
Contributor Author

I have checked the application flow graph, services, endpoints, waterfall view of traces by running docker-compose
Screenshot 2021-05-21 at 2 15 00 PM
Screenshot 2021-05-21 at 2 14 53 PM
Screenshot 2021-05-21 at 2 13 12 PM
Screenshot 2021-05-21 at 2 12 53 PM

findingrish
findingrish previously approved these changes May 21, 2021
Copy link
Copy Markdown
Contributor

@findingrish findingrish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@tim-mwangi tim-mwangi requested a review from d-trace May 21, 2021 17:04
@tim-mwangi
Copy link
Copy Markdown
Contributor

@d-trace does this affect what you are working on?

@d-trace
Copy link
Copy Markdown
Contributor

d-trace commented May 21, 2021

@d-trace does this affect what you are working on?

No @tim-mwangi. My logic at the moment does calculations based on StructuredTrace directly.

Copy link
Copy Markdown
Contributor

@d-trace d-trace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GraphBuilderUtil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add unit tests for this util?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApiTraceGraphBuilder {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit tests?

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.


// calls second time, this time it returns from cache
StructuredTraceGraphBuilder.buildGraph(underTestTrace);
structuredTraceGraphMockedStatic.verify(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this assertion should be placed before the second call?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sure that after the second call, it was not incremented. Let me put at both the places. Done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it should be at both places

// first call
ApiTraceGraph actual = ApiTraceGraphBuilder.buildGraph(underTestTrace);
Assertions.assertNotNull(actual);
Assertions.assertEquals(1, mockedConstruction.constructed().size());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this mockedConstruction.constructed().size() size representing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The number of times new ApiTraceGraph(trace) is called.

/**
* optimistic method of comparing two trace for considering rebuilding of entire graph structure.
*/
static boolean isSameStructuredTrace(StructuredTrace cachedTrace, StructuredTrace trace) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the method name could be misleading, we are trying to check if the components in the Trace are same as previous or not. Trace might have changed due to event enrichment or trace enrichment.

when(underTestTrace.getEventEdgeList()).thenReturn(List.of(eventEdge));

boolean result = GraphBuilderUtil.isSameStructuredTrace(cachedTrace, underTestTrace);
Assertions.assertTrue(result);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test the negative case as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remains are covered with the other two tests, and this I have created as an end to cover up all. But, if you want, I can add one to the list item.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be taken up subsequently

// calls second time, this time it returns from cache
StructuredTraceGraphBuilder.buildGraph(underTestTrace);
structuredTraceGraphMockedStatic.verify(
() -> StructuredTraceGraph.createGraph(underTestTrace), times(1));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, its also important to test that the cached structure is not returned when a different trace is passed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the fist call doing the same StructuredTraceGraphBuilder.buildGraph as it has to test GraphBuilderUtil.isSameStructuredTrace and the first call cover that part and the method is independently covered in GraphBuilderUtilTest.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah the correctness is tested, this was more of a suggestion for completeness sake.

First test with empty cache, second call return from cache, third call with different trace again build structure.

// second call
ApiTraceGraph second = ApiTraceGraphBuilder.buildGraph(underTestTrace);
Assertions.assertEquals(actual, second);
Assertions.assertEquals(1, mockedConstruction.constructed().size());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, its also important to test that the cached graph is not returned when a different trace is passed?

Copy link
Copy Markdown
Contributor Author

@kotharironak kotharironak May 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first call is testing that we are going to if block where the cache is prepared. And GraphBuilderUtil.isSameStructuredTrace is independently tested in GraphBuilderUtilTest.

@kotharironak kotharironak requested a review from findingrish May 24, 2021 10:35
@github-actions

This comment has been minimized.

@kotharironak kotharironak merged commit 94b8c05 into main May 24, 2021
@kotharironak kotharironak deleted the optimize-api-trace-graph branch May 24, 2021 11:49
@github-actions
Copy link
Copy Markdown

Unit Test Results

  64 files  ±0    64 suites  ±0   49s ⏱️ -3s
314 tests ±0  314 ✔️ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 94b8c05. ± Comparison against base commit 2123371.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants