Skip to content

Commit 792f8b2

Browse files
authored
fix for performance observed during enrichment process (#100)
* fix for performance * functional validation * changes logs * cleaning PR by removing measuing logging codes * Removes un-used logger * Adds comments for redability
1 parent c529c39 commit 792f8b2

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

hypertrace-trace-enricher/hypertrace-trace-enricher-api/src/main/java/org/hypertrace/traceenricher/trace/util/ApiTraceGraph.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private Pair<List<Event>, List<Event>> getEventsInApiBoundary(
178178
}
179179

180180
public ApiTraceGraph build() {
181-
StructuredTraceGraph graph = StructuredTraceGraph.createGraph(trace);
181+
StructuredTraceGraph graph = StructuredTraceGraphBuilder.buildGraph(trace);
182182

183183
List<ApiNode<Event>> apiNodes = buildApiNodes(graph);
184184
this.setNodeList(apiNodes);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.hypertrace.traceenricher.trace.util;
2+
3+
import org.hypertrace.core.datamodel.StructuredTrace;
4+
import org.hypertrace.core.datamodel.shared.StructuredTraceGraph;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
public class StructuredTraceGraphBuilder {
9+
private static final Logger LOG = LoggerFactory.getLogger(StructuredTraceGraphBuilder.class);
10+
11+
private static ThreadLocal<StructuredTraceGraph> cachedGraph = new ThreadLocal<>();
12+
private static ThreadLocal<StructuredTrace> cachedTrace = new ThreadLocal<>();
13+
14+
public static StructuredTraceGraph buildGraph(StructuredTrace trace) {
15+
// trace doesn't exist
16+
if (cachedTrace.get() == null) {
17+
LOG.info("Building structured trace graph. Reason: no cached trace");
18+
StructuredTraceGraph graph = StructuredTraceGraph.createGraph(trace);
19+
cachedTrace.set(StructuredTrace.newBuilder(trace).build());
20+
cachedGraph.set(graph);
21+
return graph;
22+
}
23+
24+
// is processed and cached are same trace?
25+
if (!cachedTrace.get().getCustomerId().equals(trace.getCustomerId()) ||
26+
!cachedTrace.get().getTraceId().equals(trace.getTraceId())) {
27+
LOG.info("Building structured trace graph. Reason: cached trace and current trace doesn't not match");
28+
StructuredTraceGraph graph = StructuredTraceGraph.createGraph(trace);
29+
cachedTrace.set(StructuredTrace.newBuilder(trace).build());
30+
cachedGraph.set(graph);
31+
return graph;
32+
}
33+
34+
// trace internally changed
35+
if(cachedTrace.get().getEntityList().size() != trace.getEntityList().size() ||
36+
cachedTrace.get().getEventList().size() != trace.getEventList().size() ||
37+
cachedTrace.get().getEntityEdgeList().size() != trace.getEntityEdgeList().size() ||
38+
cachedTrace.get().getEntityEventEdgeList().size() != trace.getEntityEventEdgeList().size() ||
39+
cachedTrace.get().getEventEdgeList().size() != trace.getEventEdgeList().size()) {
40+
LOG.info("Building structured trace graph. Reason: cached trace and current trace have different size");
41+
StructuredTraceGraph graph = StructuredTraceGraph.createGraph(trace);
42+
cachedTrace.set(StructuredTrace.newBuilder(trace).build());
43+
cachedGraph.set(graph);
44+
return graph;
45+
}
46+
47+
return cachedGraph.get();
48+
}
49+
}

hypertrace-trace-enricher/hypertrace-trace-enricher-impl/src/main/java/org/hypertrace/traceenricher/enrichment/AbstractTraceEnricher.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.hypertrace.core.datamodel.StructuredTrace;
1717
import org.hypertrace.core.datamodel.shared.StructuredTraceGraph;
1818
import org.hypertrace.entity.data.service.client.EntityDataServiceClientProvider;
19+
import org.hypertrace.traceenricher.trace.util.StructuredTraceGraphBuilder;
1920

2021
public abstract class AbstractTraceEnricher implements Enricher {
2122

@@ -52,7 +53,7 @@ public void enrichTrace(StructuredTrace trace) {
5253
* Wrapper to the structure graph factory for testing
5354
*/
5455
public StructuredTraceGraph buildGraph(StructuredTrace trace) {
55-
return StructuredTraceGraph.createGraph(trace);
56+
return StructuredTraceGraphBuilder.buildGraph(trace);
5657
}
5758

5859
@Nullable

hypertrace-trace-enricher/hypertrace-trace-enricher-impl/src/main/java/org/hypertrace/traceenricher/enrichment/enrichers/DefaultServiceEntityEnricher.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import org.hypertrace.core.datamodel.shared.SpanAttributeUtils;
1111
import org.hypertrace.core.datamodel.shared.StructuredTraceGraph;
1212
import org.hypertrace.core.datamodel.shared.trace.AttributeValueCreator;
13-
import org.hypertrace.core.span.constants.RawSpanConstants;
14-
import org.hypertrace.core.span.constants.v1.JaegerAttribute;
1513
import org.hypertrace.entity.constants.v1.ServiceAttribute;
1614
import org.hypertrace.entity.data.service.client.EdsClient;
1715
import org.hypertrace.entity.data.service.client.EntityDataServiceClientProvider;
@@ -69,7 +67,7 @@ public void enrichEvent(StructuredTrace trace, Event event) {
6967
// 2. Enrich the exit span with the parent span's service entity.
7068
// This will enable creating an edge between the exit span and the backend
7169

72-
StructuredTraceGraph graph = StructuredTraceGraph.createGraph(trace);
70+
StructuredTraceGraph graph = buildGraph(trace);
7371
if (EnrichedSpanUtils.isExitSpan(event) &&
7472
SpanAttributeUtils.isLeafSpan(graph, event)) {
7573
String parentSvcName = findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService(event,

hypertrace-trace-enricher/hypertrace-trace-enricher/src/main/java/org/hypertrace/traceenricher/trace/enricher/StructuredTraceEnrichProcessor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import static org.hypertrace.traceenricher.trace.enricher.StructuredTraceEnricherConstants.STRUCTURED_TRACES_ENRICHMENT_JOB_CONFIG_KEY;
66

77
import com.typesafe.config.Config;
8+
import java.time.Duration;
9+
import java.time.Instant;
810
import java.util.LinkedHashMap;
911
import java.util.List;
1012
import java.util.Map;
@@ -15,10 +17,13 @@
1517
import org.hypertrace.entity.data.service.client.DefaultEdsClientProvider;
1618
import org.hypertrace.traceenricher.enrichment.EnrichmentProcessor;
1719
import org.hypertrace.traceenricher.enrichment.EnrichmentRegistry;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
1822

1923
public class StructuredTraceEnrichProcessor implements
2024
Transformer<String, StructuredTrace, KeyValue<String, StructuredTrace>> {
2125

26+
private static final Logger logger = LoggerFactory.getLogger(StructuredTraceEnrichProcessor.class);
2227
private static EnrichmentProcessor processor = null;
2328

2429
@Override
@@ -38,7 +43,11 @@ public void init(ProcessorContext context) {
3843

3944
@Override
4045
public KeyValue<String, StructuredTrace> transform(String key, StructuredTrace value) {
46+
Instant start = Instant.now();
4147
processor.process(value);
48+
Instant finish = Instant.now();
49+
long timeElapsed = Duration.between(start, finish).toMillis();
50+
logger.debug("Time taken by enrichment process for key:{} is :{}", key, timeElapsed);
4251
return new KeyValue<>(null, value);
4352
}
4453

0 commit comments

Comments
 (0)