Search in sources :

Example 6 with StructuredTraceGraph

use of org.hypertrace.core.datamodel.shared.StructuredTraceGraph in project hypertrace-ingester by hypertrace.

the class DefaultServiceEntityEnricher method enrichEvent.

@Override
public void enrichEvent(StructuredTrace trace, Event event) {
    // Nothing to do if the span already has service id on it
    if (EnrichedSpanUtils.getServiceId(event) != null) {
        return;
    }
    // If there is serviceName present in the span, just go ahead and create a service
    // entity with those details. This is to support BareMetal case.
    String serviceName = event.getServiceName();
    if (serviceName != null) {
        // Check if the exit span's jaeger_svcname is different from the parent span's jaeger_svcname
        // If it is then use the parent span's jaeger_svcname as the exit span's jaeger svc name else
        // just use the jaeger svc name as is.
        // This will give us 2 things:
        // 1. No service corresponding to exit span will be registered
        // (Typically this is an example where a facade service is created for a backend.
        // See redis and mysql in HotROD app for an example).
        // The actual service name on the exit span will instead be registered
        // as a backend by the {@link ClientSpanEndpointResolver}
        // 2. Enrich the exit span with the parent span's service entity.
        // This will enable creating an edge between the exit span and the backend
        StructuredTraceGraph graph = buildGraph(trace);
        if (EnrichedSpanUtils.isExitSpan(event) && SpanAttributeUtils.isLeafSpan(graph, event)) {
            String parentSvcName = findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService(event, serviceName, graph).orElse(null);
            if (parentSvcName != null) {
                serviceName = parentSvcName;
            } else {
                // create backend entity at {@link ClientSpanEndpointResolver} if service and peer service
                // are same
                String peerServiceName = SpanSemanticConventionUtils.getPeerServiceName(event);
                if (peerServiceName != null && peerServiceName.equals(serviceName)) {
                    return;
                }
            }
        }
        Map<String, String> attributes = Map.of(SPAN_ID_KEY, HexUtils.getHex(event.getEventId()), TRACE_ID_KEY, HexUtils.getHex(trace.getTraceId()));
        org.hypertrace.entity.data.service.v1.Entity entity = factory.getService(event.getCustomerId(), serviceName, ServiceType.JAEGER_SERVICE.name(), attributes);
        org.hypertrace.core.datamodel.Entity avroEntity = EntityAvroConverter.convertToAvroEntity(entity, false);
        if (avroEntity != null) {
            addEntity(trace, event, avroEntity);
            addEnrichedAttribute(event, SERVICE_ID_ATTR_NAME, AttributeValueCreator.create(avroEntity.getEntityId()));
            addEnrichedAttribute(event, SERVICE_NAME_ATTR_NAME, AttributeValueCreator.create(avroEntity.getEntityName()));
        }
    }
}
Also used : StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph)

Example 7 with StructuredTraceGraph

use of org.hypertrace.core.datamodel.shared.StructuredTraceGraph in project hypertrace-ingester by hypertrace.

the class StructuredTraceGraphBuilderTest method testBuildGraph.

@Test
void testBuildGraph() {
    Entity entity = mock(Entity.class);
    Event parent = mock(Event.class);
    Event child = mock(Event.class);
    Edge eventEdge = mock(Edge.class);
    StructuredTrace underTestTrace = mock(StructuredTrace.class);
    when(underTestTrace.getCustomerId()).thenReturn("__defaultTenant");
    when(underTestTrace.getTraceId()).thenReturn(ByteBuffer.wrap("2ebbc19b6428510f".getBytes()));
    when(underTestTrace.getEntityList()).thenReturn(List.of(entity));
    when(underTestTrace.getEventList()).thenReturn(List.of(parent, child));
    when(underTestTrace.getEntityEdgeList()).thenReturn(List.of());
    when(underTestTrace.getEntityEventEdgeList()).thenReturn(List.of());
    when(underTestTrace.getEventEdgeList()).thenReturn(List.of(eventEdge));
    try (MockedStatic<StructuredTrace> builderMockedStatic = mockStatic(StructuredTrace.class)) {
        StructuredTrace.Builder builder = mock(StructuredTrace.Builder.class);
        when(builder.build()).thenReturn(underTestTrace);
        builderMockedStatic.when(() -> StructuredTrace.newBuilder(underTestTrace)).thenReturn(builder);
        try (MockedConstruction<StructuredTraceGraph> mocked = mockConstruction(StructuredTraceGraph.class)) {
            // calls first time
            StructuredTraceGraph actual = StructuredTraceGraphBuilder.buildGraph(underTestTrace);
            // calls second time, this time it returns from cache
            StructuredTraceGraph cached = StructuredTraceGraphBuilder.buildGraph(underTestTrace);
            Assertions.assertEquals(actual, cached);
        }
    }
}
Also used : Entity(org.hypertrace.core.datamodel.Entity) StructuredTrace(org.hypertrace.core.datamodel.StructuredTrace) Event(org.hypertrace.core.datamodel.Event) StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph) Edge(org.hypertrace.core.datamodel.Edge) Test(org.junit.jupiter.api.Test)

Example 8 with StructuredTraceGraph

use of org.hypertrace.core.datamodel.shared.StructuredTraceGraph in project hypertrace-ingester by hypertrace.

the class TraceUI method build.

public static TraceUI build(StructuredTrace trace) {
    StructuredTraceGraph graph = new StructuredTraceGraph(trace);
    Set<Event> roots = findRootEvents(trace);
    Set<JSONObject> rootJsons = new HashSet<>();
    for (Event root : roots) {
        JSONObject jsonObject = new JSONObject();
        rootJsons.add(jsonObject);
        Queue<Pair<Event, List<Integer>>> q = new LinkedList<>();
        q.add(Pair.of(root, new ArrayList<>()));
        jsonObject.put("id", HexUtils.getHex(root.getEventId()));
        jsonObject.put("name", root.getEventName());
        jsonObject.put("parent", "null");
        jsonObject.put("attributes", flattenAttributes(root));
        jsonObject.put("children", new JSONArray());
        while (!q.isEmpty()) {
            Pair<Event, List<Integer>> p = q.remove();
            Event e = p.getLeft();
            List<Integer> list = p.getRight();
            List<Event> children = graph.getChildrenEvents(e);
            if (children != null) {
                for (int i = 0; i < children.size(); i++) {
                    Event child = children.get(i);
                    JSONArray jsonArray = jsonObject.getJSONArray("children");
                    for (Integer index : list) {
                        JSONObject childJsonObject = jsonArray.getJSONObject(index);
                        jsonArray = childJsonObject.getJSONArray("children");
                    }
                    JSONObject childJsonObject = new JSONObject();
                    childJsonObject.put("id", HexUtils.getHex(child.getEventId()));
                    childJsonObject.put("name", child.getEventName());
                    childJsonObject.put("parent", HexUtils.getHex(e.getEventId()));
                    childJsonObject.put("attributes", flattenAttributes(child));
                    childJsonObject.put("children", new JSONArray());
                    jsonArray.put(childJsonObject);
                    ArrayList<Integer> indexesList = new ArrayList<>(list);
                    indexesList.add(i);
                    Pair<Event, List<Integer>> pairForChild = Pair.of(child, indexesList);
                    q.add(pairForChild);
                }
            }
        }
    }
    return new TraceUI(trace, rootJsons);
}
Also used : ArrayList(java.util.ArrayList) JSONArray(org.json.JSONArray) LinkedList(java.util.LinkedList) JSONObject(org.json.JSONObject) Event(org.hypertrace.core.datamodel.Event) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph) HashSet(java.util.HashSet) Pair(org.apache.commons.lang3.tuple.Pair)

Example 9 with StructuredTraceGraph

use of org.hypertrace.core.datamodel.shared.StructuredTraceGraph in project hypertrace-ingester by hypertrace.

the class DefaultServiceEntityEnricherTest method test_case6_findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService.

@Test
public void test_case6_findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService() {
    // Case 6:  sampleapp (entry) -> sampleapp (entry) -> sampleapp (exit)
    Event parent1 = createEvent(TENANT_ID, "parent1", Map.of("span.kind", "server"), Map.of(API_BOUNDARY_TYPE_ATTR, "ENTRY", "SERVICE_NAME", "sampleapp"), null, "sampleapp");
    Event parent2 = createEvent(TENANT_ID, "parent2", Map.of("span.kind", "client"), Map.of(API_BOUNDARY_TYPE_ATTR, "ENTRY", "SERVICE_NAME", "sampleapp"), ByteBuffer.wrap("parent1".getBytes()), "sampleapp");
    Event current = createEvent(TENANT_ID, "current", Map.of("span.kind", "client"), Map.of(API_BOUNDARY_TYPE_ATTR, "EXIT"), ByteBuffer.wrap("parent2".getBytes()), "sampleapp");
    StructuredTraceGraph graph = mock(StructuredTraceGraph.class);
    when(graph.getParentEvent(current)).thenReturn(parent2);
    String actual = enricher.findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService(current, "sampleapp", graph).orElse(null);
    String expected = null;
    assertEquals(expected, actual);
}
Also used : Event(org.hypertrace.core.datamodel.Event) StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph) Test(org.junit.jupiter.api.Test)

Example 10 with StructuredTraceGraph

use of org.hypertrace.core.datamodel.shared.StructuredTraceGraph in project hypertrace-ingester by hypertrace.

the class DefaultServiceEntityEnricherTest method test_case5_findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService.

@Test
public void test_case5_findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService() {
    // Case 4:  sampleapp (exit)
    Event current = createEvent(TENANT_ID, "current", Map.of("span.kind", "client"), Map.of(API_BOUNDARY_TYPE_ATTR, "EXIT"), null, "sampleapp");
    StructuredTraceGraph graph = mock(StructuredTraceGraph.class);
    when(graph.getParentEvent(current)).thenReturn(null);
    String actual = enricher.findServiceNameOfFirstAncestorThatIsNotAnExitSpanAndBelongsToADifferentService(current, "sampleapp", graph).orElse(null);
    String expected = null;
    assertEquals(expected, actual);
}
Also used : Event(org.hypertrace.core.datamodel.Event) StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph) Test(org.junit.jupiter.api.Test)

Aggregations

StructuredTraceGraph (org.hypertrace.core.datamodel.shared.StructuredTraceGraph)15 Event (org.hypertrace.core.datamodel.Event)11 Test (org.junit.jupiter.api.Test)7 List (java.util.List)4 StructuredTrace (org.hypertrace.core.datamodel.StructuredTrace)4 ArrayList (java.util.ArrayList)2 Collections (java.util.Collections)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 Map (java.util.Map)2 Optional (java.util.Optional)2 StringUtils (org.apache.commons.lang3.StringUtils)2 Pair (org.apache.commons.lang3.tuple.Pair)2 Edge (org.hypertrace.core.datamodel.Edge)2 HexUtils (org.hypertrace.core.datamodel.shared.HexUtils)2 EnrichedSpanConstants (org.hypertrace.traceenricher.enrichedspan.constants.EnrichedSpanConstants)2 EnrichedSpanUtils (org.hypertrace.traceenricher.enrichedspan.constants.utils.EnrichedSpanUtils)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1