use of zipkin2.storage.QueryRequest in project zipkin by openzipkin.
the class ITZipkinSelfTracing method assertQueryReturnsResults.
void assertQueryReturnsResults(QueryRequest.Builder builder, List<List<Span>> traces) throws IOException {
QueryRequest query = builder.endTs(System.currentTimeMillis()).lookback(DAY).limit(2).build();
assertThat(inMemoryStorage().getTraces(query).execute()).withFailMessage("Expected results from %s. Current traces: %s", query, traces).isNotEmpty();
}
use of zipkin2.storage.QueryRequest in project zipkin by openzipkin.
the class SelectSpansAndAnnotations method toTraceIdQuery.
SelectOffsetStep<? extends Record> toTraceIdQuery(DSLContext context, QueryRequest request) {
long endTs = request.endTs() * 1000;
TableOnConditionStep<?> table = ZIPKIN_SPANS.join(ZIPKIN_ANNOTATIONS).on(schema.joinCondition(ZIPKIN_ANNOTATIONS));
int i = 0;
for (Map.Entry<String, String> kv : request.annotationQuery().entrySet()) {
ZipkinAnnotations aTable = ZIPKIN_ANNOTATIONS.as("a" + i++);
if (kv.getValue().isEmpty()) {
table = maybeOnService(table.join(aTable).on(schema.joinCondition(aTable)).and(aTable.A_KEY.eq(kv.getKey())), aTable, request.serviceName());
} else {
table = maybeOnService(table.join(aTable).on(schema.joinCondition(aTable)).and(aTable.A_TYPE.eq(V1BinaryAnnotation.TYPE_STRING)).and(aTable.A_KEY.eq(kv.getKey())).and(aTable.A_VALUE.eq(kv.getValue().getBytes(UTF_8))), aTable, request.serviceName());
}
}
List<SelectField<?>> distinctFields = new ArrayList<>(schema.spanIdFields);
distinctFields.add(max(ZIPKIN_SPANS.START_TS));
SelectConditionStep<Record> dsl = context.selectDistinct(distinctFields).from(table).where(ZIPKIN_SPANS.START_TS.between(endTs - request.lookback() * 1000, endTs));
if (request.serviceName() != null) {
dsl.and(localServiceNameCondition().and(ZIPKIN_ANNOTATIONS.ENDPOINT_SERVICE_NAME.eq(request.serviceName())));
}
if (request.remoteServiceName() != null) {
dsl.and(ZIPKIN_SPANS.REMOTE_SERVICE_NAME.eq(request.remoteServiceName()));
}
if (request.spanName() != null) {
dsl.and(ZIPKIN_SPANS.NAME.eq(request.spanName()));
}
if (request.minDuration() != null && request.maxDuration() != null) {
dsl.and(ZIPKIN_SPANS.DURATION.between(request.minDuration(), request.maxDuration()));
} else if (request.minDuration() != null) {
dsl.and(ZIPKIN_SPANS.DURATION.greaterOrEqual(request.minDuration()));
}
return dsl.groupBy(schema.spanIdFields).orderBy(max(ZIPKIN_SPANS.START_TS).desc()).limit(request.limit());
}
use of zipkin2.storage.QueryRequest in project zipkin by openzipkin.
the class ElasticsearchSpanStore method getTraces.
@Override
public Call<List<List<Span>>> getTraces(QueryRequest request) {
if (!searchEnabled)
return Call.emptyList();
long endMillis = request.endTs();
long beginMillis = Math.max(endMillis - request.lookback(), EARLIEST_MS);
SearchRequest.Filters filters = new SearchRequest.Filters();
filters.addRange("timestamp_millis", beginMillis, endMillis);
if (request.serviceName() != null) {
filters.addTerm("localEndpoint.serviceName", request.serviceName());
}
if (request.remoteServiceName() != null) {
filters.addTerm("remoteEndpoint.serviceName", request.remoteServiceName());
}
if (request.spanName() != null) {
filters.addTerm("name", request.spanName());
}
for (Map.Entry<String, String> kv : request.annotationQuery().entrySet()) {
if (kv.getValue().isEmpty()) {
filters.addTerm("_q", kv.getKey());
} else {
filters.addTerm("_q", kv.getKey() + "=" + kv.getValue());
}
}
if (request.minDuration() != null) {
filters.addRange("duration", request.minDuration(), request.maxDuration());
}
// We need to filter to traces that contain at least one span that matches the request,
// but the zipkin API is supposed to order traces by first span, regardless of if it was
// filtered or not. This is not possible without either multiple, heavyweight queries
// or complex multiple indexing, defeating much of the elegance of using elasticsearch for this.
// So we fudge and order on the first span among the filtered spans - in practice, there should
// be no significant difference in user experience since span start times are usually very
// close to each other in human time.
Aggregation traceIdTimestamp = Aggregation.terms("traceId", request.limit()).addSubAggregation(Aggregation.min("timestamp_millis")).orderBy("timestamp_millis", "desc");
List<String> indices = indexNameFormatter.formatTypeAndRange(TYPE_SPAN, beginMillis, endMillis);
if (indices.isEmpty())
return Call.emptyList();
SearchRequest esRequest = SearchRequest.create(indices).filters(filters).addAggregation(traceIdTimestamp);
HttpCall<List<String>> traceIdsCall = search.newCall(esRequest, BodyConverters.KEYS);
Call<List<List<Span>>> result = traceIdsCall.flatMap(new GetSpansByTraceId(search, indices)).map(groupByTraceId);
// clash on lower-64 bit. When strict trace ID is enabled, we only filter client-side on clash.
return strictTraceId ? result.map(StrictTraceId.filterTraces(request)) : result;
}
use of zipkin2.storage.QueryRequest in project zipkin by openzipkin.
the class CassandraUtilTest method annotationKeys_dedupes.
@Test
public void annotationKeys_dedupes() {
QueryRequest request = QueryRequest.newBuilder().endTs(System.currentTimeMillis()).limit(10).lookback(86400000L).serviceName("service").parseAnnotationQuery("error and error").build();
assertThat(CassandraUtil.annotationKeys(request)).containsExactly("error");
}
use of zipkin2.storage.QueryRequest in project zipkin by openzipkin.
the class ZipkinQueryApiV2 method getTraces.
@Get("/api/v2/traces")
@Blocking
public AggregatedHttpResponse getTraces(@Param("serviceName") Optional<String> serviceName, @Param("remoteServiceName") Optional<String> remoteServiceName, @Param("spanName") Optional<String> spanName, @Param("annotationQuery") Optional<String> annotationQuery, @Param("minDuration") Optional<Long> minDuration, @Param("maxDuration") Optional<Long> maxDuration, @Param("endTs") Optional<Long> endTs, @Param("lookback") Optional<Long> lookback, @Default("10") @Param("limit") int limit) throws IOException {
QueryRequest queryRequest = QueryRequest.newBuilder().serviceName(serviceName.orElse(null)).remoteServiceName(remoteServiceName.orElse(null)).spanName(spanName.orElse(null)).parseAnnotationQuery(annotationQuery.orElse(null)).minDuration(minDuration.orElse(null)).maxDuration(maxDuration.orElse(null)).endTs(endTs.orElse(System.currentTimeMillis())).lookback(lookback.orElse(defaultLookback)).limit(limit).build();
List<List<Span>> traces = storage.spanStore().getTraces(queryRequest).execute();
return jsonResponse(writeTraces(SpanBytesEncoder.JSON_V2, traces));
}
Aggregations