Skip to content

Commit

Permalink
BanyanDB: fix storage and query Tag autocomplete data (apache#12432)
Browse files Browse the repository at this point in the history
  • Loading branch information
wankai123 authored Jul 11, 2024
1 parent 90d5006 commit 641163c
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/en/changes/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* Support tracing topology query for debugging.
* Fix expression of graph `Current QPS` in MySQL dashboard.
* Support tracing logs query for debugging.
* BanyanDB: fix Tag autocomplete data storage and query.

#### UI
* Highlight search log keywords.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,33 @@ public static long getTimeBucket(long timestamp, DownSampling downsampling) {
throw new UnexpectedException("Unknown downsampling value.");
}
}

/**
* Retain the minute time bucket to day time bucket. The format of timeBucket in minute format is "yyyyMMddHHmm", `HHmm` will be set to `0000`.
* minuteTimeBucket `202407112218` will be converted to `202407110000`.
* @param minuteTimeBucket minuteTimeBucket
* @return minute time bucket in day precision
*/
public static long retainToDay4MinuteBucket(long minuteTimeBucket) {
if (isMinuteBucket(minuteTimeBucket)) {
return minuteTimeBucket / 10000 * 10000;
} else {
throw new UnexpectedException("Current time bucket is not a minute time bucket");
}
}

/**
* Retain the minute time bucket to day time bucket. The format of timeBucket in minute format is "yyyyMMddHHmm", `HHmm` will be set to `2359`.
* minuteTimeBucket `202407112218` will be converted to `202407112359`.
* @param minuteTimeBucket minuteTimeBucket
* @return minute time bucket in day precision
*/
public static long retainToDayLastMin4MinuteBucket(long minuteTimeBucket) {
if (isMinuteBucket(minuteTimeBucket)) {
return minuteTimeBucket / 10000 * 10000 + 2359;
} else {
throw new UnexpectedException("Current time bucket is not a minute time bucket");
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.core.analysis.manual.searchtag;

import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
import org.apache.skywalking.oap.server.core.source.TagAutocomplete;

Expand All @@ -30,7 +31,8 @@ public void dispatch(TagAutocomplete source) {
autocomplete.setTagKey(source.getTagKey());
autocomplete.setTagValue(source.getTagValue());
autocomplete.setTagType(source.getTagType().name());
autocomplete.setTimeBucket(source.getTimeBucket());
// change the precision in Day for reduce the storage
autocomplete.setTimeBucket(TimeBucket.retainToDay4MinuteBucket(source.getTimeBucket()));
MetricsStreamProcessor.getInstance().in(autocomplete);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,36 @@ public long endTimeDurationToSecondTimeBucket(Step step, String dateStr) {
throw new UnexpectedException("Unsupported step " + step.name());
}

public long startTimeDurationToMinuteTimeBucket(Step step, String dateStr) {
long minTimeBucket = convertToTimeBucket(step, dateStr);
switch (step) {
case DAY:
return minTimeBucket * 100 * 100;
case HOUR:
return minTimeBucket * 100;
case MINUTE:
return minTimeBucket;
case SECOND:
return minTimeBucket / 100;
}
throw new UnexpectedException("Unsupported step " + step.name());
}

public long endTimeDurationToMinuteTimeBucket(Step step, String dateStr) {
long minTimeBucket = convertToTimeBucket(step, dateStr);
switch (step) {
case DAY:
return (minTimeBucket * 100 + 23) * 100 + 59;
case HOUR:
return minTimeBucket * 100 + 59;
case MINUTE:
return minTimeBucket;
case SECOND:
return minTimeBucket / 100;
}
throw new UnexpectedException("Unsupported step " + step.name());
}

public List<PointOfTime> getDurationPoints(Step step, long startTimeBucket, long endTimeBucket) {
DateTime dateTime = parseToDateTime(step, startTimeBucket);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ public long getEndTimeBucketInSec() {
return DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(step, end);
}

public long getStartTimeBucketInMin() {
return DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(step, start);
}

public long getEndTimeBucketInMin() {
return DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(step, end);
}

/**
* Assemble time point based on {@link #step} and {@link #start} / {@link #end}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.core.analysis;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

Expand Down Expand Up @@ -64,4 +65,14 @@ public void testConversion(DownSampling downSampling) {
}
Assertions.assertEquals(instance.getTimeInMillis(), timestamp);
}

@Test
public void testRetainToDay4MinuteBucket() {
Assertions.assertEquals(202407110000L, TimeBucket.retainToDay4MinuteBucket(202407112218L));
}

@Test
public void testRetainToDayLastMin4MinuteBucket() {
Assertions.assertEquals(202407112359L, TimeBucket.retainToDayLastMin4MinuteBucket(202407112218L));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,40 @@ public void testGetDurationPoints() {
Assertions.assertTrue(Arrays.asList(20220910L, 20220911L, 20220912L)
.equals(pointOfTimes.stream().map(PointOfTime::getPoint).collect(Collectors.toList())));
}

@Test
public void testStartTimeDurationToMinuteTimeBucket() {
Assertions.assertEquals(
202209080000L, DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(Step.DAY, "2022-09-08"));
Assertions.assertEquals(
202209081000L, DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(Step.HOUR, "2022-09-08 10"));
Assertions.assertEquals(
202209081010L, DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(Step.MINUTE, "2022-09-08 1010"));
Assertions.assertEquals(
202209081010L, DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(Step.SECOND, "2022-09-08 101010"));
try {
DurationUtils.INSTANCE.startTimeDurationToMinuteTimeBucket(Step.HOUR, "2022-09-08 30");
Assertions.fail("Should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
Assertions.assertTrue(true);
}
}

@Test
public void testEndTimeDurationToMinuteTimeBucket() {
Assertions.assertEquals(
202209082359L, DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(Step.DAY, "2022-09-08"));
Assertions.assertEquals(
202209081059L, DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(Step.HOUR, "2022-09-08 10"));
Assertions.assertEquals(
202209081010L, DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(Step.MINUTE, "2022-09-08 1010"));
Assertions.assertEquals(
202209081010L, DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(Step.SECOND, "2022-09-08 101010"));
try {
DurationUtils.INSTANCE.endTimeDurationToMinuteTimeBucket(Step.HOUR, "2022-09-08 30");
Assertions.fail("Should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
Assertions.assertTrue(true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,16 @@ public BanyanDBTagAutocompleteQueryDAO(BanyanDBStorageClient client) {
@Override
public Set<String> queryTagAutocompleteKeys(TagType tagType, int limit, Duration duration) throws IOException {
MetadataRegistry.Schema schema = MetadataRegistry.INSTANCE.findMetadata(TagAutocompleteData.INDEX_NAME, DownSampling.Minute);
long startTB = 0;
long endTB = 0;
long startMinTB = 0;
long endMinTB = 0;
if (nonNull(duration)) {
startTB = TimeBucket.getMinuteTimeBucket(duration.getStartTimestamp());
endTB = TimeBucket.getMinuteTimeBucket(duration.getEndTimestamp());
startMinTB = duration.getStartTimeBucketInMin();
endMinTB = duration.getEndTimeBucketInMin();
}

long startTB = TimeBucket.retainToDay4MinuteBucket(startMinTB);
long endTB = TimeBucket.retainToDayLastMin4MinuteBucket(endMinTB);

TimestampRange range = null;
if (startTB > 0 && endTB > 0) {
range = new TimestampRange(TimeBucket.getTimestamp(startTB), TimeBucket.getTimestamp(endTB));
Expand Down Expand Up @@ -91,15 +95,15 @@ protected void apply(MeasureQuery query) {
@Override
public Set<String> queryTagAutocompleteValues(TagType tagType, String tagKey, int limit, Duration duration) throws IOException {
MetadataRegistry.Schema schema = MetadataRegistry.INSTANCE.findMetadata(TagAutocompleteData.INDEX_NAME, DownSampling.Minute);
long startSecondTB = 0;
long endSecondTB = 0;
long startMinTB = 0;
long endMinTB = 0;
if (nonNull(duration)) {
startSecondTB = duration.getStartTimeBucketInSec();
endSecondTB = duration.getEndTimeBucketInSec();
startMinTB = duration.getStartTimeBucketInMin();
endMinTB = duration.getEndTimeBucketInMin();
}

long startTB = startSecondTB / 1000000 * 10000;
long endTB = endSecondTB / 1000000 * 10000 + 2359;
long startTB = TimeBucket.retainToDay4MinuteBucket(startMinTB);
long endTB = TimeBucket.retainToDayLastMin4MinuteBucket(endMinTB);

TimestampRange range = null;
if (startTB > 0 && endTB > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.TagAutocompleteData;
import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.TagType;
import org.apache.skywalking.oap.server.core.query.input.Duration;
Expand Down Expand Up @@ -125,15 +126,15 @@ private void appendTagAutocompleteCondition(final TagType tagType,
final Duration duration,
final StringBuilder sql,
final List<Object> condition) {
long startSecondTB = 0;
long endSecondTB = 0;
long startMinTB = 0;
long endMinTB = 0;
if (nonNull(duration)) {
startSecondTB = duration.getStartTimeBucketInSec();
endSecondTB = duration.getEndTimeBucketInSec();
startMinTB = duration.getStartTimeBucketInMin();
endMinTB = duration.getEndTimeBucketInMin();
}

long startTB = startSecondTB / 1000000 * 10000;
long endTB = endSecondTB / 1000000 * 10000 + 2359;
long startTB = TimeBucket.retainToDay4MinuteBucket(startMinTB);
long endTB = TimeBucket.retainToDayLastMin4MinuteBucket(endMinTB);

sql.append(" and ");
sql.append(TagAutocompleteData.TAG_TYPE).append(" = ?");
Expand Down
16 changes: 16 additions & 0 deletions test/e2e-v2/cases/zipkin/expected/autocomplete-keys.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

["http.method"]
4 changes: 3 additions & 1 deletion test/e2e-v2/cases/zipkin/zipkin-cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ cases:
- query: curl http://${oap_host}:${oap_9412}/zipkin/api/v2/traces?serviceName=frontend&remoteServiceName=backend&spanName=get&annotationQuery=wr&limit=1
expected: expected/traces.yml
# autocomplete
- query: curl http://${oap_host}:${oap_9412}/zipkin/api/v2/autocompleteKeys
expected: expected/autocomplete-keys.yml
- query: curl http://${oap_host}:${oap_9412}/zipkin/api/v2/autocompleteValues?key=http.method
expected: expected/autocomplete.yml
expected: expected/autocomplete-value.yml

0 comments on commit 641163c

Please sign in to comment.