Search in sources :

Example 1 with LogEvents

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

the class JaegerSpanToLogRecordsTransformerTest method testDropLogEventRecords.

@Test
void testDropLogEventRecords() {
    Map<String, Object> configs = new HashMap<>();
    configs.putAll(Map.of("processor", Map.of("tenantIdTagKey", "tenant-key", "excludeLogsTenantIds", List.of("tenant-1"))));
    ProcessorContext processorContext = Mockito.mock(ProcessorContext.class);
    Mockito.when(processorContext.appConfigs()).thenReturn(Map.of("span-normalizer-job-config", ConfigFactory.parseMap(configs)));
    JaegerSpanToLogRecordsTransformer jaegerSpanToLogRecordsTransformer = new JaegerSpanToLogRecordsTransformer();
    jaegerSpanToLogRecordsTransformer.init(processorContext);
    KeyValue<String, LogEvents> keyValue = jaegerSpanToLogRecordsTransformer.transform(null, new PreProcessedSpan("tenant-1", getTestSpan(), buildEvent("tenant-1", getTestSpan(), Optional.of("tenant-key"))));
    Assertions.assertNull(keyValue);
}
Also used : HashMap(java.util.HashMap) ByteString(com.google.protobuf.ByteString) ProcessorContext(org.apache.kafka.streams.processor.ProcessorContext) LogEvents(org.hypertrace.core.datamodel.LogEvents) Test(org.junit.jupiter.api.Test)

Example 2 with LogEvents

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

the class SpanNormalizerTest method whenByPassedExpectStructuredTraceToBeOutput.

@Test
@SetEnvironmentVariable(key = "SERVICE_NAME", value = "span-normalizer")
public void whenByPassedExpectStructuredTraceToBeOutput() {
    Config config = ConfigFactory.parseURL(getClass().getClassLoader().getResource("configs/span-normalizer/application.conf"));
    Map<String, Object> mergedProps = new HashMap<>();
    underTest.getBaseStreamsConfig().forEach(mergedProps::put);
    underTest.getStreamsConfig(config).forEach(mergedProps::put);
    mergedProps.put(SpanNormalizerConstants.SPAN_NORMALIZER_JOB_CONFIG, config);
    StreamsBuilder streamsBuilder = underTest.buildTopology(mergedProps, new StreamsBuilder(), new HashMap<>());
    Properties props = new Properties();
    mergedProps.forEach(props::put);
    TopologyTestDriver td = new TopologyTestDriver(streamsBuilder.build(), props);
    TestInputTopic<byte[], Span> inputTopic = td.createInputTopic(config.getString(SpanNormalizerConstants.INPUT_TOPIC_CONFIG_KEY), Serdes.ByteArray().serializer(), new JaegerSpanSerde().serializer());
    Serde<RawSpan> rawSpanSerde = new AvroSerde<>();
    rawSpanSerde.configure(Map.of(), false);
    Serde<StructuredTrace> structuredTraceSerde = new AvroSerde<>();
    structuredTraceSerde.configure(Map.of(), false);
    Serde<TraceIdentity> spanIdentitySerde = new AvroSerde<>();
    spanIdentitySerde.configure(Map.of(), true);
    TestOutputTopic outputTopic = td.createOutputTopic(config.getString(SpanNormalizerConstants.OUTPUT_TOPIC_CONFIG_KEY), spanIdentitySerde.deserializer(), rawSpanSerde.deserializer());
    TestOutputTopic bypassOutputTopic = td.createOutputTopic(config.getString(SpanNormalizerConstants.BYPASS_OUTPUT_TOPIC_CONFIG_KEY), Serdes.String().deserializer(), structuredTraceSerde.deserializer());
    TestOutputTopic rawLogOutputTopic = td.createOutputTopic(config.getString(SpanNormalizerConstants.OUTPUT_TOPIC_RAW_LOGS_CONFIG_KEY), spanIdentitySerde.deserializer(), new AvroSerde<>().deserializer());
    // with logs event, with bypass key
    // expects no output to raw-span-grouper
    // expects output to trace-enricher
    // expects log output
    Span span1 = Span.newBuilder().setSpanId(ByteString.copyFrom("1".getBytes())).setTraceId(ByteString.copyFrom("trace-1".getBytes())).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("jaeger.servicename").setVStr(SERVICE_NAME).build()).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("test.bypass").setVStr("true").build()).addLogs(Log.newBuilder().setTimestamp(Timestamp.newBuilder().setSeconds(10).build()).addFields(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("z2").setVStr("some event detail").build())).build();
    inputTopic.pipeInput(span1);
    // validate output for trace-enricher
    assertFalse(bypassOutputTopic.isEmpty());
    KeyValue<String, StructuredTrace> kv1 = bypassOutputTopic.readKeyValue();
    assertEquals("__default", kv1.value.getCustomerId());
    assertEquals(HexUtils.getHex(ByteString.copyFrom("trace-1".getBytes()).toByteArray()), HexUtils.getHex(kv1.value.getTraceId().array()));
    // validate no output for raw-spans-grouper
    assertTrue(outputTopic.isEmpty());
    // validate that no change in log traffic
    assertFalse(rawLogOutputTopic.isEmpty());
    LogEvents logEvents = (LogEvents) rawLogOutputTopic.readKeyValue().value;
    Assertions.assertEquals(1, logEvents.getLogEvents().size());
    // with logs event, without bypass key
    // expects output to raw-span-grouper
    // expects no output to trace-enricher
    // expects log output
    Span span2 = Span.newBuilder().setSpanId(ByteString.copyFrom("2".getBytes())).setTraceId(ByteString.copyFrom("trace-2".getBytes())).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("jaeger.servicename").setVStr(SERVICE_NAME).build()).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("http.method").setVStr("GET").build()).addLogs(Log.newBuilder().setTimestamp(Timestamp.newBuilder().setSeconds(10).build()).addFields(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("z2").setVStr("some event detail").build())).build();
    inputTopic.pipeInput(span2);
    // validate that no output to trace-enricher
    assertTrue(bypassOutputTopic.isEmpty());
    // validate that output to raw-spans-grouper
    assertFalse(outputTopic.isEmpty());
    KeyValue<TraceIdentity, RawSpan> kv2 = outputTopic.readKeyValue();
    assertEquals("__default", kv2.key.getTenantId());
    assertEquals(HexUtils.getHex(ByteString.copyFrom("trace-2".getBytes()).toByteArray()), HexUtils.getHex(kv2.key.getTraceId().array()));
    // validate that no change in log traffic
    assertFalse(rawLogOutputTopic.isEmpty());
    logEvents = (LogEvents) rawLogOutputTopic.readKeyValue().value;
    Assertions.assertEquals(1, logEvents.getLogEvents().size());
    // with logs event, with bypass key but false value
    // expects output to raw-span-grouper
    // expects no output to trace-enricher
    // expects log output
    Span span3 = Span.newBuilder().setSpanId(ByteString.copyFrom("3".getBytes())).setTraceId(ByteString.copyFrom("trace-3".getBytes())).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("jaeger.servicename").setVStr(SERVICE_NAME).build()).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("http.method").setVStr("GET").build()).addTags(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("test.bypass").setVStr("false").build()).addLogs(Log.newBuilder().setTimestamp(Timestamp.newBuilder().setSeconds(10).build()).addFields(JaegerSpanInternalModel.KeyValue.newBuilder().setKey("z2").setVStr("some event detail").build())).build();
    inputTopic.pipeInput(span3);
    // validate that no output to trace-enricher
    assertTrue(bypassOutputTopic.isEmpty());
    // validate that output to raw-spans-grouper
    assertFalse(outputTopic.isEmpty());
    KeyValue<TraceIdentity, RawSpan> kv3 = outputTopic.readKeyValue();
    assertEquals("__default", kv3.key.getTenantId());
    assertEquals(HexUtils.getHex(ByteString.copyFrom("trace-3".getBytes()).toByteArray()), HexUtils.getHex(kv3.key.getTraceId().array()));
    // validate that no change in log traffic
    assertFalse(rawLogOutputTopic.isEmpty());
    logEvents = (LogEvents) rawLogOutputTopic.readKeyValue().value;
    Assertions.assertEquals(1, logEvents.getLogEvents().size());
}
Also used : HashMap(java.util.HashMap) Config(com.typesafe.config.Config) JaegerSpanSerde(org.hypertrace.core.spannormalizer.jaeger.JaegerSpanSerde) TopologyTestDriver(org.apache.kafka.streams.TopologyTestDriver) ByteString(com.google.protobuf.ByteString) RawSpan(org.hypertrace.core.datamodel.RawSpan) Properties(java.util.Properties) Span(io.jaegertracing.api_v2.JaegerSpanInternalModel.Span) RawSpan(org.hypertrace.core.datamodel.RawSpan) StructuredTrace(org.hypertrace.core.datamodel.StructuredTrace) TestOutputTopic(org.apache.kafka.streams.TestOutputTopic) LogEvents(org.hypertrace.core.datamodel.LogEvents) StreamsBuilder(org.apache.kafka.streams.StreamsBuilder) AvroSerde(org.hypertrace.core.kafkastreams.framework.serdes.AvroSerde) SetEnvironmentVariable(org.junitpioneer.jupiter.SetEnvironmentVariable) Test(org.junit.jupiter.api.Test)

Example 3 with LogEvents

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

the class JaegerSpanToLogRecordsTransformer method transform.

@Override
public KeyValue<String, LogEvents> transform(byte[] key, PreProcessedSpan preProcessedSpan) {
    try {
        Span value = preProcessedSpan.getSpan();
        String tenantId = preProcessedSpan.getTenantId();
        if (value.getLogsCount() == 0 || tenantIdsToExclude.contains(tenantId)) {
            return null;
        }
        tenantToSpanWithLogsReceivedCount.computeIfAbsent(tenantId, tenant -> PlatformMetricsRegistry.registerCounter(VALID_SPAN_WITH_LOGS_RECEIVED_COUNT, Map.of("tenantId", tenantId))).increment();
        return new KeyValue<>(null, buildLogEventRecords(value, tenantId));
    } catch (Exception e) {
        LOG.error("Exception processing log records", e);
        return null;
    }
}
Also used : SPAN_NORMALIZER_JOB_CONFIG(org.hypertrace.core.spannormalizer.constants.SpanNormalizerConstants.SPAN_NORMALIZER_JOB_CONFIG) Span(io.jaegertracing.api_v2.JaegerSpanInternalModel.Span) AvroBuilderCache.fastNewBuilder(org.hypertrace.core.datamodel.shared.AvroBuilderCache.fastNewBuilder) LoggerFactory(org.slf4j.LoggerFactory) ByteBuffer(java.nio.ByteBuffer) ConcurrentMap(java.util.concurrent.ConcurrentMap) JaegerSpanInternalModel(io.jaegertracing.api_v2.JaegerSpanInternalModel) PlatformMetricsRegistry(org.hypertrace.core.serviceframework.metrics.PlatformMetricsRegistry) Map(java.util.Map) Attributes(org.hypertrace.core.datamodel.Attributes) JaegerHTTagsConverter(org.hypertrace.core.spannormalizer.util.JaegerHTTagsConverter) Counter(io.micrometer.core.instrument.Counter) Logger(org.slf4j.Logger) Config(com.typesafe.config.Config) Transformer(org.apache.kafka.streams.kstream.Transformer) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) KeyValue(org.apache.kafka.streams.KeyValue) Timestamps(com.google.protobuf.util.Timestamps) Collectors(java.util.stream.Collectors) ProcessorContext(org.apache.kafka.streams.processor.ProcessorContext) LogEvents(org.hypertrace.core.datamodel.LogEvents) List(java.util.List) VisibleForTesting(com.google.common.annotations.VisibleForTesting) LogEvent(org.hypertrace.core.datamodel.LogEvent) Collections(java.util.Collections) KeyValue(org.apache.kafka.streams.KeyValue) Span(io.jaegertracing.api_v2.JaegerSpanInternalModel.Span)

Example 4 with LogEvents

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

the class LogEventViewGenerator method process.

@Override
public List<LogEventView> process(LogEvents logEvents) {
    try {
        List<LogEventView> list = new ArrayList<>();
        for (LogEvent logEventRecord : logEvents.getLogEvents()) {
            String attributes = convertAttributes(logEventRecord.getAttributes());
            LogEventView logEventView = fastNewBuilder(LogEventView.Builder.class).setSpanId(logEventRecord.getSpanId()).setTraceId(logEventRecord.getTraceId()).setTimestampNanos(logEventRecord.getTimestampNanos()).setTenantId(logEventRecord.getTenantId()).setAttributes(attributes).setSummary(getSummary(logEventRecord.getAttributes())).build();
            if (!StringUtils.isEmpty(logEventRecord.getTenantId()) && null != attributes) {
                logEventAttributeSizeGauge.computeIfAbsent(logEventRecord.getTenantId(), v -> PlatformMetricsRegistry.registerGauge(LOG_EVENT_ATTRIBUTE_SIZE_METRIC, Map.of("tenantId", logEventRecord.getTenantId()), new AtomicInteger(0))).set(attributes.length());
            }
            list.add(logEventView);
        }
        return list;
    } catch (Exception e) {
        LOG.error("Exception processing log records", e);
        return null;
    }
}
Also used : Schema(org.apache.avro.Schema) Logger(org.slf4j.Logger) AvroBuilderCache.fastNewBuilder(org.hypertrace.core.datamodel.shared.AvroBuilderCache.fastNewBuilder) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LoggerFactory(org.slf4j.LoggerFactory) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) HashMap(java.util.HashMap) StringUtils(org.apache.commons.lang3.StringUtils) LogEventView(org.hypertrace.viewgenerator.api.LogEventView) ArrayList(java.util.ArrayList) PlatformMetricsRegistry(org.hypertrace.core.serviceframework.metrics.PlatformMetricsRegistry) LogEvents(org.hypertrace.core.datamodel.LogEvents) List(java.util.List) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) AttributeValue(org.hypertrace.core.datamodel.AttributeValue) Attributes(org.hypertrace.core.datamodel.Attributes) Optional(java.util.Optional) LogEvent(org.hypertrace.core.datamodel.LogEvent) JavaCodeBasedViewGenerator(org.hypertrace.core.viewgenerator.JavaCodeBasedViewGenerator) LogEvent(org.hypertrace.core.datamodel.LogEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AvroBuilderCache.fastNewBuilder(org.hypertrace.core.datamodel.shared.AvroBuilderCache.fastNewBuilder) ArrayList(java.util.ArrayList) LogEventView(org.hypertrace.viewgenerator.api.LogEventView) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 5 with LogEvents

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

the class LogEventViewGeneratorTest method testSummaryField.

@Test
void testSummaryField() {
    LogEventViewGenerator logEventViewGenerator = new LogEventViewGenerator();
    Map<String, String> attributes = new HashMap<>();
    List<String> summaryKeys = new ArrayList<>(LogEventViewGenerator.SUMMARY_KEYS);
    AtomicInteger attributeVal = new AtomicInteger();
    summaryKeys.forEach(key -> attributes.put(key, String.valueOf(attributeVal.getAndIncrement())));
    for (String summaryKey : LogEventViewGenerator.SUMMARY_KEYS) {
        LogEvents logEvents = getLogEventsWithAttribute(attributes);
        List<LogEventView> list = logEventViewGenerator.process(logEvents);
        assertEquals(attributes.get(summaryKey), list.get(0).getSummary());
        attributes.remove(summaryKey);
    }
}
Also used : HashMap(java.util.HashMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) LogEventView(org.hypertrace.viewgenerator.api.LogEventView) LogEvents(org.hypertrace.core.datamodel.LogEvents) Test(org.junit.jupiter.api.Test)

Aggregations

LogEvents (org.hypertrace.core.datamodel.LogEvents)12 Test (org.junit.jupiter.api.Test)9 LogEventView (org.hypertrace.viewgenerator.api.LogEventView)6 HashMap (java.util.HashMap)5 Config (com.typesafe.config.Config)4 Span (io.jaegertracing.api_v2.JaegerSpanInternalModel.Span)4 ByteString (com.google.protobuf.ByteString)3 List (java.util.List)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ProcessorContext (org.apache.kafka.streams.processor.ProcessorContext)3 Attributes (org.hypertrace.core.datamodel.Attributes)3 LogEvent (org.hypertrace.core.datamodel.LogEvent)3 AvroBuilderCache.fastNewBuilder (org.hypertrace.core.datamodel.shared.AvroBuilderCache.fastNewBuilder)3 PlatformMetricsRegistry (org.hypertrace.core.serviceframework.metrics.PlatformMetricsRegistry)3 Logger (org.slf4j.Logger)3 LoggerFactory (org.slf4j.LoggerFactory)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Timestamps (com.google.protobuf.util.Timestamps)2 JaegerSpanInternalModel (io.jaegertracing.api_v2.JaegerSpanInternalModel)2