Search in sources :

Example 16 with Event

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

the class ApiTraceGraph method buildApiNodeEdges.

private void buildApiNodeEdges(StructuredTraceGraph graph) {
    // 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();
        for (Event exitBoundaryEvent : exitBoundaryEvents) {
            List<Event> exitBoundaryEventChildren = graph.getChildrenEvents(exitBoundaryEvent);
            if (exitBoundaryEventChildren != null) {
                for (Event exitBoundaryEventChild : exitBoundaryEventChildren) {
                    // always!
                    if (EnrichedSpanUtils.isEntryApiBoundary(exitBoundaryEventChild)) {
                        // get the api node exit boundary event is connecting to
                        ApiNode<Event> destinationApiNode = entryApiBoundaryEventIdToApiNode.get(exitBoundaryEventChild.getEventId());
                        Optional<ApiNodeEventEdge> edgeBetweenApiNodes = createEdgeBetweenApiNodes(apiNode, destinationApiNode, exitBoundaryEvent, exitBoundaryEventChild);
                        edgeBetweenApiNodes.ifPresent(edge -> {
                            apiNodeEventEdgeList.add(edge);
                            apiExitBoundaryEventIdxWithOutgoingEdge.add(edge.getSrcEventIndex());
                            apiEntryBoundaryEventIdxWithIncomingEdge.add(edge.getTgtEventIndex());
                            apiNodeIdxToEdges.computeIfAbsent(apiNodeHeadEventIdToIndex.get(apiNode.getHeadEvent().getEventId()), v -> Sets.newHashSet()).add(apiNodeEventEdgeList.size() - 1);
                        });
                    } else {
                        if (LOGGER.isDebugEnabled()) {
                            LOGGER.debug("Exit boundary event with eventId: {}, eventName: {}, serviceName: {}," + " can only have entry boundary event as child. Non-entry child:" + " childEventId: {}, childEventName: {}, childServiceName: {}." + " traceId for events: {}", HexUtils.getHex(exitBoundaryEvent.getEventId()), exitBoundaryEvent.getEventName(), exitBoundaryEvent.getServiceName(), HexUtils.getHex(exitBoundaryEventChild.getEventId()), exitBoundaryEventChild.getEventName(), exitBoundaryEventChild.getServiceName(), HexUtils.getHex(trace.getTraceId()));
                        }
                    }
                }
            }
        }
        // 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) {
                    // which can happen if exit span missing and both belongs to different services.
                    if (EnrichedSpanUtils.isEntryApiBoundary(child) && 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);
                    }
                }
            }
        }
    }
}
Also used : EnrichedSpanUtils(org.hypertrace.traceenricher.enrichedspan.constants.utils.EnrichedSpanUtils) AttributeValue(org.hypertrace.traceenricher.enrichedspan.constants.v1.AttributeValue) AvroBuilderCache.fastNewBuilder(org.hypertrace.core.datamodel.shared.AvroBuilderCache.fastNewBuilder) LoggerFactory(org.slf4j.LoggerFactory) HashBasedTable(com.google.common.collect.HashBasedTable) Edge(org.hypertrace.core.datamodel.Edge) StringUtils(org.apache.commons.lang3.StringUtils) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) StructuredTraceGraph(org.hypertrace.core.datamodel.shared.StructuredTraceGraph) ApiNode(org.hypertrace.core.datamodel.shared.ApiNode) Lists(com.google.common.collect.Lists) Map(java.util.Map) EnrichedSpanConstants(org.hypertrace.traceenricher.enrichedspan.constants.EnrichedSpanConstants) HexUtils(org.hypertrace.core.datamodel.shared.HexUtils) LinkedList(java.util.LinkedList) StructuredTrace(org.hypertrace.core.datamodel.StructuredTrace) Logger(org.slf4j.Logger) ApiNodeEventEdge(org.hypertrace.core.datamodel.ApiNodeEventEdge) Event(org.hypertrace.core.datamodel.Event) Set(java.util.Set) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) List(java.util.List) Optional(java.util.Optional) Queue(java.util.Queue) Table(com.google.common.collect.Table) Collections(java.util.Collections) ApiNodeEventEdge(org.hypertrace.core.datamodel.ApiNodeEventEdge) Event(org.hypertrace.core.datamodel.Event)

Example 17 with Event

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

the class EnrichedSpanUtilsTest method testGetParent.

@Test
public void testGetParent() {
    Event e1 = mock(Event.class);
    when(e1.getEventId()).thenReturn(ByteBuffer.wrap("span-1".getBytes()));
    Event e2 = mock(Event.class);
    when(e2.getEventId()).thenReturn(ByteBuffer.wrap("span-2".getBytes()));
    Event e3 = mock(Event.class);
    when(e3.getEventId()).thenReturn(ByteBuffer.wrap("span-3".getBytes()));
    Event e4 = mock(Event.class);
    when(e4.getEventId()).thenReturn(ByteBuffer.wrap("span-4".getBytes()));
    Map<ByteBuffer, Event> idToEvent = Map.of(ByteBuffer.wrap("span-1".getBytes()), e1, ByteBuffer.wrap("span-2".getBytes()), e2, ByteBuffer.wrap("span-3".getBytes()), e3, ByteBuffer.wrap("span-4".getBytes()), e4);
    Map<ByteBuffer, ByteBuffer> childToParentEventIds = Map.of(ByteBuffer.wrap("span-3".getBytes()), ByteBuffer.wrap("span-2".getBytes()), ByteBuffer.wrap("span-2".getBytes()), ByteBuffer.wrap("span-1".getBytes()), ByteBuffer.wrap("span-4".getBytes()), ByteBuffer.wrap("unknown".getBytes()));
    Event parent = SpanAttributeUtils.getParentSpan(e3, childToParentEventIds, idToEvent);
    assertEquals(e2, parent);
    parent = SpanAttributeUtils.getParentSpan(e2, childToParentEventIds, idToEvent);
    assertEquals(e1, parent);
    parent = SpanAttributeUtils.getParentSpan(e1, childToParentEventIds, idToEvent);
    assertEquals(null, parent);
    parent = SpanAttributeUtils.getParentSpan(e4, childToParentEventIds, idToEvent);
    assertEquals(null, parent);
}
Also used : Event(org.hypertrace.core.datamodel.Event) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.jupiter.api.Test)

Example 18 with Event

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

the class EnrichedSpanUtilsTest method should_getHttpMethod.

@Test
public void should_getHttpMethod() {
    Event e = createMockEventWithAttribute(RawSpanConstants.getValue(HTTP_METHOD), "GET");
    Optional<String> method = EnrichedSpanUtils.getHttpMethod(e);
    assertFalse(method.isEmpty());
    assertEquals("GET", method.get());
}
Also used : Event(org.hypertrace.core.datamodel.Event) Test(org.junit.jupiter.api.Test)

Example 19 with Event

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

the class GraphBuilderUtilTest method testIsStructuredTraceChangedForSizeCondition.

@Test
public void testIsStructuredTraceChangedForSizeCondition() {
    Entity entity = mock(Entity.class);
    Event parent = mock(Event.class);
    Event child = mock(Event.class);
    Edge eventEdge = mock(Edge.class);
    // same size
    StructuredTrace cachedTrace = mock(StructuredTrace.class);
    when(cachedTrace.getCustomerId()).thenReturn("__defaultTenant");
    when(cachedTrace.getTraceId()).thenReturn(ByteBuffer.wrap("2ebbc19b6428510f".getBytes()));
    when(cachedTrace.getEntityList()).thenReturn(List.of(entity));
    when(cachedTrace.getEventList()).thenReturn(List.of(parent, child));
    when(cachedTrace.getEntityEdgeList()).thenReturn(List.of());
    when(cachedTrace.getEntityEventEdgeList()).thenReturn(List.of());
    when(cachedTrace.getEventEdgeList()).thenReturn(List.of(eventEdge));
    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));
    boolean result = GraphBuilderUtil.isStructuredTraceChanged(cachedTrace, underTestTrace);
    Assertions.assertFalse(result);
}
Also used : Entity(org.hypertrace.core.datamodel.Entity) StructuredTrace(org.hypertrace.core.datamodel.StructuredTrace) Event(org.hypertrace.core.datamodel.Event) Edge(org.hypertrace.core.datamodel.Edge) Test(org.junit.jupiter.api.Test)

Example 20 with Event

use of org.hypertrace.core.datamodel.Event 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)

Aggregations

Event (org.hypertrace.core.datamodel.Event)304 Test (org.junit.jupiter.api.Test)257 AttributeValue (org.hypertrace.core.datamodel.AttributeValue)54 StructuredTrace (org.hypertrace.core.datamodel.StructuredTrace)54 Attributes (org.hypertrace.core.datamodel.Attributes)41 Entity (org.hypertrace.entity.data.service.v1.Entity)27 HashMap (java.util.HashMap)25 AbstractAttributeEnricherTest (org.hypertrace.traceenricher.enrichment.enrichers.AbstractAttributeEnricherTest)17 ByteBuffer (java.nio.ByteBuffer)13 BackendInfo (org.hypertrace.traceenricher.enrichment.enrichers.resolver.backend.BackendInfo)13 StructuredTraceGraph (org.hypertrace.core.datamodel.shared.StructuredTraceGraph)12 TestUtil.buildAttributeValue (org.hypertrace.traceenricher.TestUtil.buildAttributeValue)11 AttributeMetadata (org.hypertrace.core.attribute.service.v1.AttributeMetadata)10 SemanticConventionTestUtil.buildAttributes (org.hypertrace.semantic.convention.utils.SemanticConventionTestUtil.buildAttributes)8 Edge (org.hypertrace.core.datamodel.Edge)7 Entity (org.hypertrace.core.datamodel.Entity)7 HashSet (java.util.HashSet)6 List (java.util.List)6 Map (java.util.Map)6 ArrayList (java.util.ArrayList)5