<jupyter_start><jupyter_text>Jaeger-query with trace DSLThis notebook loads a trace from Jaeger query service via gRPC and runs analysis on it.  Install library to the local maven repositoryThis step is only needed if trace DSL source code has been modified.Open terminal in Jupyter and run the following command:```cd work && ./mvnw clean install -DskipTests```<jupyter_code>%%loadFromPOM
<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java</artifactId>
  <version>3.11.4</version>
</dependency>
<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java-util</artifactId>
  <version>3.11.4</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-protobuf</artifactId>
  <version>1.28.0</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-netty</artifactId>
  <version>1.28.0</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-stub</artifactId>
  <version>1.28.0</version>
</dependency>

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_httpserver</artifactId>
    <version>0.7.0</version>
</dependency>
<dependency>
    <groupId>org.apache.tinkerpop</groupId>
    <artifactId>tinkergraph-gremlin</artifactId>
    <version>3.4.3</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

%maven io.jaegertracing:jaeger-tracedsl:0.4.0
%maven io.jaegertracing:jaeger-proto:0.4.0

System.out.println(io.jaegertracing.analytics.gremlin.Keys.class);<jupyter_output>class io.jaegertracing.analytics.gremlin.Keys<jupyter_text>Run analysisIt calculates maximum trace height and network latencies. It connects to Jaeger query service via gRPC.<jupyter_code>import com.google.protobuf.ByteString;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.jaegertracing.analytics.*;
import io.jaegertracing.analytics.NetworkLatency.Name;
import io.jaegertracing.analytics.gremlin.GraphCreator;
import io.jaegertracing.analytics.model.Converter;
import io.jaegertracing.analytics.model.Trace;
import io.jaegertracing.api_v2.Model.Span;
import io.jaegertracing.api_v2.Query.GetTraceRequest;
import io.jaegertracing.api_v2.Query.SpansResponseChunk;
import io.jaegertracing.api_v2.QueryServiceGrpc;
import io.jaegertracing.api_v2.Query.FindTracesRequest;
import io.jaegertracing.api_v2.QueryServiceGrpc.QueryServiceBlockingStub;
import io.jaegertracing.api_v2.Query.TraceQueryParameters;
import io.opentracing.tag.Tags;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tinkerpop.gremlin.structure.Graph;

String queryHostPort = "172.17.0.1:16686";

ManagedChannel channel;
channel = ManagedChannelBuilder.forTarget(queryHostPort).usePlaintext().build();
QueryServiceBlockingStub queryService = QueryServiceGrpc.newBlockingStub(channel);

TraceQueryParameters query = TraceQueryParameters.newBuilder().setServiceName("frontend")
    .build();
Iterator<SpansResponseChunk> traceProto = queryService.findTraces(
    FindTracesRequest.newBuilder().setQuery(query).build());

List<Span> protoSpans = new ArrayList<>();
while (traceProto.hasNext()) {
  protoSpans.addAll(traceProto.next().getSpansList());
}
Trace traces = Converter.toModel(protoSpans);
Graph graph = GraphCreator.create(traces);

Set<io.jaegertracing.analytics.model.Span> errorSpans = NumberOfErrors.calculate(graph);
Map<String, Map<String, Integer>> result = new LinkedHashMap<>();
for (io.jaegertracing.analytics.model.Span errorSpan : errorSpans) {
  for (io.jaegertracing.analytics.model.Span.Log log : errorSpan.logs) {
    String err = log.fields.get(Tags.ERROR.getKey());
    if (err != null) {
      Map<String, Integer> traceIdCount = result.get(err);
      if (traceIdCount == null) {
        traceIdCount = new LinkedHashMap<>();
        result.put(err, traceIdCount);
      }

      Integer count = traceIdCount.get(errorSpan.traceId);
      if (count == null) {
        count = 0;
      }
      traceIdCount.put(errorSpan.traceId, ++count);
    }
  }
}
System.out.println("Error type, traceID and error count:");
for (Map.Entry<String, Map<String, Integer>> errorMap : result.entrySet()) {
  System.out.printf("error type: %s\n", errorMap.getKey());
  for (Map.Entry<String, Integer> traceIdCount : errorMap.getValue().entrySet()) {
    System.out
        .printf("\tTraceID: %s, count %d\n", traceIdCount.getKey(), traceIdCount.getValue());
  }
}

int height = TraceHeight.calculate(graph);
Map<Name, Set<Double>> networkLatencies = NetworkLatency.calculate(graph);
System.out.printf("Trace height = %d\n", height);
System.out.printf("Network latencies = %s\n", networkLatencies);<jupyter_output>Error type, traceID and error count:
error type: redis timeout
	TraceID: fc4df2212ebf40, count 3
	TraceID: 4e916ba6d8c18297, count 2
	TraceID: 72e82f15fdd252b1, count 2
	TraceID: 6b163ddc815f46, count 3
	TraceID: 2bc6bec49b121f07, count 3
	TraceID: c61ac8391634353, count 3
	TraceID: 4921177f60655be1, count 3
	TraceID: 1145bf4bdc8f9c21, count 2
	TraceID: 3bb5668d877b6346, count 2
	TraceID: 557044403cb65f4c, count 2
	TraceID: 3db57c32b396fa5, count 2
	TraceID: 39d5cdef7923c0e, count 3
	TraceID: 47baf4cd727ee0e4, count 2
	TraceID: 18c254d03210b078, count 2
	TraceID: 6836738e2b256fb0, count 2
	TraceID: 4c758ababa3f04c0, count 2
	TraceID: 3a20db525f6344db, count 3
	TraceID: 20402485446b76b3, count 2
	TraceID: 241bc51af4d7b288, count 2
	TraceID: 5c4c962b8064ac8f, count 2
	TraceID: 4a0c5a9b8a33727c, count 2
	TraceID: 472b4e7acd0a2a25, count 2
	TraceID: 64b286ddd2a6d5c5, count 3
	TraceID: 7773d4961586ba9b, count 3
	TraceID: 5b43f81de78c004d, count 2
	TraceID: 625e8ecf62bde6b0, count 2
	TraceID[...]<jupyter_text>Write your own data analysis with Trace DSL and Apache Gremlin<jupyter_code>// Are two spans connected?
TraceTraversal<Vertex, Vertex> traversal = graph.traversal(TraceTraversalSource.class)
        .hasName("HTTP GET: /customer")
        .repeat(__.out())
        .until(__.hasName("SQL SELECT"));

traversal.forEachRemaining(v -> Util.printVertex(v));<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12243589743589743, 'fraction_numerical': 0.05576923076923077, 'mean_word_length': 5.583333333333333, 'pattern_counts': {'":': 0, '<': 90, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '79515', 'license': 'Apache-2.0', 'n_tokens_mistral': 2468, 'n_tokens_neox': 2208, 'n_words': 415, 'path': 'jupyter/jaeger-query.ipynb', 'repo_name': 'shreyagupta30/jaeger-analytics-java', 'size': '6240'}