provide multiple time ranges to query profile analyze (#4417)
* profide multi time range to query profile analyze * use method to avoid direct reference field
This commit is contained in:
parent
2ea341b890
commit
fa0b3df369
|
|
@ -25,9 +25,11 @@ import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord;
|
import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
||||||
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzeTimeRange;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileStackTree;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileStackTree;
|
||||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||||
import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO;
|
import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO;
|
||||||
|
|
@ -62,17 +64,17 @@ public class ProfileAnalyzer {
|
||||||
/**
|
/**
|
||||||
* search snapshots and analyze
|
* search snapshots and analyze
|
||||||
*/
|
*/
|
||||||
public ProfileAnalyzation analyze(String segmentId, long start, long end) throws IOException {
|
public ProfileAnalyzation analyze(String segmentId, List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
|
||||||
ProfileAnalyzation analyzation = new ProfileAnalyzation();
|
ProfileAnalyzation analyzation = new ProfileAnalyzation();
|
||||||
|
|
||||||
// query sequence range list
|
// query sequence range list
|
||||||
SequenceSearch sequenceSearch = getAllSequenceRange(segmentId, start, end);
|
SequenceSearch sequenceSearch = getAllSequenceRange(segmentId, timeRanges);
|
||||||
if (sequenceSearch == null) {
|
if (sequenceSearch == null) {
|
||||||
analyzation.setTip("Data not found");
|
analyzation.setTip("Data not found");
|
||||||
return analyzation;
|
return analyzation;
|
||||||
}
|
}
|
||||||
if (sequenceSearch.totalSequenceCount > analyzeSnapshotMaxSize) {
|
if (sequenceSearch.getTotalSequenceCount() > analyzeSnapshotMaxSize) {
|
||||||
analyzation.setTip("Out of snapshot analyze limit, " + sequenceSearch.totalSequenceCount + " snapshots found, but analysis first " + analyzeSnapshotMaxSize + " snapshots only.");
|
analyzation.setTip("Out of snapshot analyze limit, " + sequenceSearch.getTotalSequenceCount() + " snapshots found, but analysis first " + analyzeSnapshotMaxSize + " snapshots only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// query snapshots
|
// query snapshots
|
||||||
|
|
@ -91,6 +93,17 @@ public class ProfileAnalyzer {
|
||||||
return analyzation;
|
return analyzation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected SequenceSearch getAllSequenceRange(String segmentId, List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
|
||||||
|
return timeRanges.parallelStream().map(r -> {
|
||||||
|
try {
|
||||||
|
return getAllSequenceRange(segmentId, r.getStart(), r.getEnd());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.warn(e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).filter(Objects::nonNull).reduce(new SequenceSearch(0), SequenceSearch::combine);
|
||||||
|
}
|
||||||
|
|
||||||
protected SequenceSearch getAllSequenceRange(String segmentId, long start, long end) throws IOException {
|
protected SequenceSearch getAllSequenceRange(String segmentId, long start, long end) throws IOException {
|
||||||
// query min and max sequence
|
// query min and max sequence
|
||||||
int minSequence = getProfileThreadSnapshotQueryDAO().queryMinSequence(segmentId, start, end);
|
int minSequence = getProfileThreadSnapshotQueryDAO().queryMinSequence(segmentId, start, end);
|
||||||
|
|
@ -156,6 +169,12 @@ public class ProfileAnalyzer {
|
||||||
public int getTotalSequenceCount() {
|
public int getTotalSequenceCount() {
|
||||||
return totalSequenceCount;
|
return totalSequenceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SequenceSearch combine(SequenceSearch search) {
|
||||||
|
this.ranges.addAll(search.ranges);
|
||||||
|
this.totalSequenceCount += search.totalSequenceCount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SequenceRange {
|
private static class SequenceRange {
|
||||||
|
|
@ -175,8 +194,5 @@ public class ProfileAnalyzer {
|
||||||
return maxSequence;
|
return maxSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increaseMaxSequence() {
|
|
||||||
this.maxSequence++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.KeyValue;
|
import org.apache.skywalking.oap.server.core.query.entity.KeyValue;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.LogEntity;
|
import org.apache.skywalking.oap.server.core.query.entity.LogEntity;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
||||||
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzeTimeRange;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileTaskLog;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileTaskLog;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
|
||||||
|
|
@ -198,8 +199,8 @@ public class ProfileTaskQueryService implements Service {
|
||||||
return getProfileThreadSnapshotQueryDAO().queryProfiledSegments(taskId);
|
return getProfileThreadSnapshotQueryDAO().queryProfiledSegments(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileAnalyzation getProfileAnalyze(final String segmentId, final long start, final long end) throws IOException {
|
public ProfileAnalyzation getProfileAnalyze(final String segmentId, final List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
|
||||||
return profileAnalyzer.analyze(segmentId, start, end);
|
return profileAnalyzer.analyze(segmentId, timeRanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfiledSegment getProfiledSegment(String segmentId) throws IOException {
|
public ProfiledSegment getProfiledSegment(String segmentId) throws IOException {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.core.query.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ProfileAnalyzeTimeRange {
|
||||||
|
|
||||||
|
private long start;
|
||||||
|
private long end;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.skywalking.oap.server.core.profile.analyze;
|
package org.apache.skywalking.oap.server.core.profile.analyze;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ import lombok.Data;
|
||||||
import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
|
import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
|
||||||
import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord;
|
import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
|
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
|
||||||
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzeTimeRange;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileStackTree;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileStackTree;
|
||||||
import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO;
|
import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO;
|
||||||
|
|
||||||
|
|
@ -41,7 +43,10 @@ public class ProfileStackAnalyze {
|
||||||
public void analyzeAndAssert(int maxAnalyzeCount) throws IOException {
|
public void analyzeAndAssert(int maxAnalyzeCount) throws IOException {
|
||||||
List<ProfileThreadSnapshotRecord> stacks = data.transform();
|
List<ProfileThreadSnapshotRecord> stacks = data.transform();
|
||||||
|
|
||||||
List<ProfileStackTree> trees = buildAnalyzer(stacks, maxAnalyzeCount).analyze(null, 0, 0).getTrees();
|
final ProfileAnalyzeTimeRange range = new ProfileAnalyzeTimeRange();
|
||||||
|
range.setStart(0);
|
||||||
|
range.setEnd(0);
|
||||||
|
List<ProfileStackTree> trees = buildAnalyzer(stacks, maxAnalyzeCount).analyze(null, Collections.singletonList(range)).getTrees();
|
||||||
|
|
||||||
assertNotNull(trees);
|
assertNotNull(trees);
|
||||||
assertEquals(trees.size(), expected.size());
|
assertEquals(trees.size(), expected.size());
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import org.apache.skywalking.oap.server.core.CoreModule;
|
||||||
import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
|
import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
|
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
|
||||||
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzeTimeRange;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
|
||||||
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
|
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
|
||||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||||
|
|
@ -63,9 +64,8 @@ public class ProfileQuery implements GraphQLQueryResolver {
|
||||||
return getProfileTaskQueryService().getProfiledSegment(segmentId);
|
return getProfileTaskQueryService().getProfiledSegment(segmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileAnalyzation getProfileAnalyze(final String segmentId, final long start,
|
public ProfileAnalyzation getProfileAnalyze(final String segmentId, final List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
|
||||||
final long end) throws IOException {
|
return getProfileTaskQueryService().getProfileAnalyze(segmentId, timeRanges);
|
||||||
return getProfileTaskQueryService().getProfileAnalyze(segmentId, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6b26ddad2099b8782b2e298fd0df02dfd1d6609f
|
Subproject commit 8c9a8c45b9dbe954efa6de50202d05b1ef8e6be2
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
{
|
{
|
||||||
"query":"query getProfileAnalyze($segmentId: String!, $start: Long!, $end: Long!) {
|
"query":"query getProfileAnalyze($segmentId: String!, $timeRanges: [ProfileAnalyzeTimeRange!]!) {
|
||||||
data: getProfileAnalyze(segmentId: $segmentId, start: $start, end: $end) {
|
data: getProfileAnalyze(segmentId: $segmentId, timeRanges: $timeRanges) {
|
||||||
trees {
|
trees {
|
||||||
elements {
|
elements {
|
||||||
id
|
id
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
}",
|
}",
|
||||||
"variables": {
|
"variables": {
|
||||||
"segmentId": "{segmentId}",
|
"segmentId": "{segmentId}",
|
||||||
"start": "{start}",
|
"timeRanges": [{"start": "{start}", "end": "{end}"}]
|
||||||
"end": "{end}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue