You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/03/22 15:50:43 UTC
[skywalking] branch master updated: [Breaking Change] Support cross-thread trace profiling. (#10575)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 0de087a100 [Breaking Change] Support cross-thread trace profiling. (#10575)
0de087a100 is described below
commit 0de087a100c89d299f3f6536e191314c21330761
Author: mrproliu <74...@qq.com>
AuthorDate: Wed Mar 22 23:50:26 2023 +0800
[Breaking Change] Support cross-thread trace profiling. (#10575)
The data structure and query APIs are changed.
---
docs/en/changes/changes.md | 1 +
.../profiling/trace/ProfileTaskQueryService.java | 172 ++++++++++++++++++---
.../profiling/trace/analyze/ProfileAnalyzer.java | 28 ++--
.../SegmentProfileAnalyzeQuery.java} | 31 ++--
.../oap/server/core/query/type/KVInt.java | 1 +
.../{ProfiledSegment.java => NullableValue.java} | 20 +--
.../oap/server/core/query/type/ProfiledSpan.java | 3 +
...iledSegment.java => ProfiledTraceSegments.java} | 27 +++-
.../trace/IProfileThreadSnapshotQueryDAO.java | 10 +-
.../server/core/storage/query/ITraceQueryDAO.java | 4 +
.../trace/ProfileTaskQueryServiceTest.java | 139 +++++++++++++++++
.../trace/analyze/ProfileStackAnalyze.java | 15 +-
.../profiling/trace/analyze/ProfileStackData.java | 9 +-
.../core/storage/query/MetricsQueryUtilTest.java | 24 +--
.../oap/query/graphql/resolver/MetricQuery.java | 9 ++
.../oap/query/graphql/resolver/ProfileQuery.java | 17 +-
.../src/main/resources/query-protocol | 2 +-
.../BanyanDBProfileThreadSnapshotQueryDAO.java | 63 +-------
.../banyandb/stream/BanyanDBTraceQueryDAO.java | 41 ++++-
.../query/ProfileThreadSnapshotQueryEsDAO.java | 97 ++----------
.../elasticsearch/query/TraceQueryEsDAO.java | 46 +++++-
.../dao/JDBCProfileThreadSnapshotQueryDAO.java | 112 +-------------
.../plugin/jdbc/common/dao/JDBCTraceQueryDAO.java | 112 +++++++++++---
.../profile/exporter/ProfileSnapshotDumper.java | 13 +-
.../exporter/ProfileSnapshotExporterBootstrap.java | 6 +-
.../tool/profile/exporter/ProfiledBasicInfo.java | 94 ++++++-----
.../exporter/ProfileAnalyzeSnapshotDAO.java | 9 +-
.../profile/exporter/ProfileExportedAnalyze.java | 14 +-
.../exporter/test/ProfileExportSnapshotDAO.java | 16 +-
.../exporter/test/ProfileSnapshotExporterTest.java | 4 +-
.../profile/exporter/test/ProfileTraceDAO.java | 29 ++++
.../trace/expected/profile-segment-detail.yml | 40 -----
.../trace/expected/profile-segment-list.yml | 37 ++++-
.../cases/profiling/trace/profiling-cases.yaml | 24 +--
.../cases/satellite/native-protocols/e2e.yaml | 23 +--
.../expected/profile-segment-detail.yml | 38 -----
.../expected/profile-segment-list.yml | 37 ++++-
test/e2e-v2/script/env | 2 +-
38 files changed, 770 insertions(+), 599 deletions(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index d1ca54287a..3d34aab7cb 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -17,6 +17,7 @@
* Support continuous profiling feature.
* Support collect process level related metrics.
* Fix K8sRetag reads the wrong k8s service from the cache due to a possible namespace mismatch.
+* [Breaking Change] Support cross-thread trace profiling. The data structure and query APIs are changed.
#### UI
* Revert: cpm5d function. This feature is cancelled from backend.
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java
index 4e88a82e22..efa9487ecb 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java
@@ -22,8 +22,16 @@ import com.google.common.base.Objects;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import io.vavr.Tuple;
+import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.network.language.agent.v3.SegmentObject;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
@@ -32,19 +40,21 @@ import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentReco
import org.apache.skywalking.oap.server.core.cache.NetworkAddressAliasCache;
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.profiling.trace.analyze.ProfileAnalyzer;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.KeyValue;
import org.apache.skywalking.oap.server.core.query.type.LogEntity;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzation;
-import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import org.apache.skywalking.oap.server.core.query.type.ProfileTask;
import org.apache.skywalking.oap.server.core.query.type.ProfileTaskLog;
-import org.apache.skywalking.oap.server.core.query.type.ProfiledSegment;
+import org.apache.skywalking.oap.server.core.query.type.ProfiledTraceSegments;
import org.apache.skywalking.oap.server.core.query.type.ProfiledSpan;
+import org.apache.skywalking.oap.server.core.query.type.Ref;
+import org.apache.skywalking.oap.server.core.query.type.RefType;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.ITraceQueryDAO;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.module.Service;
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
@@ -54,6 +64,7 @@ import static java.util.Objects.isNull;
/**
* handle profile task queries
*/
+@Slf4j
public class ProfileTaskQueryService implements Service {
private final ModuleManager moduleManager;
private IProfileTaskQueryDAO profileTaskQueryDAO;
@@ -61,6 +72,7 @@ public class ProfileTaskQueryService implements Service {
private IProfileThreadSnapshotQueryDAO profileThreadSnapshotQueryDAO;
private NetworkAddressAliasCache networkAddressAliasCache;
private IComponentLibraryCatalogService componentLibraryCatalogService;
+ private ITraceQueryDAO traceQueryDAO;
private final ProfileAnalyzer profileAnalyzer;
@@ -117,6 +129,15 @@ public class ProfileTaskQueryService implements Service {
return componentLibraryCatalogService;
}
+ private ITraceQueryDAO getTraceQueryDAO() {
+ if (traceQueryDAO == null) {
+ this.traceQueryDAO = moduleManager.find(StorageModule.NAME)
+ .provider()
+ .getService(ITraceQueryDAO.class);
+ }
+ return traceQueryDAO;
+ }
+
/**
* search profile task list
*
@@ -161,38 +182,131 @@ public class ProfileTaskQueryService implements Service {
return findMatchedLogs(taskID, taskLogList);
}
- /**
- * search profiled traces
- */
- public List<BasicTrace> getTaskTraces(String taskId) throws IOException {
- return getProfileThreadSnapshotQueryDAO().queryProfiledSegments(taskId);
+ public ProfileAnalyzation getProfileAnalyze(final List<SegmentProfileAnalyzeQuery> queries) throws IOException {
+ return profileAnalyzer.analyze(queries);
+ }
+
+ public List<SegmentRecord> getTaskSegments(String taskId) throws IOException {
+ final List<String> profiledSegmentIdList = getProfileThreadSnapshotQueryDAO().queryProfiledSegmentIdList(taskId);
+ return getTraceQueryDAO().queryBySegmentIdList(profiledSegmentIdList);
}
- public ProfileAnalyzation getProfileAnalyze(final String segmentId,
- final List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
- return profileAnalyzer.analyze(segmentId, timeRanges);
+ public List<ProfiledTraceSegments> getProfileTaskSegments(String taskId) throws IOException {
+ // query all profiled segments
+ final List<String> profiledSegmentIdList = getProfileThreadSnapshotQueryDAO().queryProfiledSegmentIdList(taskId);
+ final List<SegmentRecord> segmentRecords = getTraceQueryDAO().queryBySegmentIdList(profiledSegmentIdList);
+ if (CollectionUtils.isEmpty(segmentRecords)) {
+ return Collections.emptyList();
+ }
+ final Map<String, List<String>> traceWithInstances = segmentRecords.stream().collect(Collectors.toMap(
+ SegmentRecord::getTraceId,
+ s -> new ArrayList(List.of(s.getServiceInstanceId())),
+ (s1, s2) -> {
+ s1.addAll(s2);
+ return s1;
+ }));
+
+ // query all profiled segments related segments(same traceId and instanceId)
+ final Set<String> traceIdList = new HashSet<>(segmentRecords.size());
+ final Set<String> instanceIdList = new HashSet<>(segmentRecords.size());
+ for (SegmentRecord segment : segmentRecords) {
+ traceIdList.add(segment.getTraceId());
+ instanceIdList.add(segment.getServiceInstanceId());
+ }
+ final List<SegmentRecord> traceRelatedSegments = getTraceQueryDAO().queryByTraceIdWithInstanceId(
+ new ArrayList<>(traceIdList),
+ new ArrayList<>(instanceIdList));
+
+ // group by the traceId + service instanceId
+ final Map<String, List<SegmentRecord>> instanceTraceWithSegments = traceRelatedSegments.stream().filter(s -> {
+ final List<String> includingInstances = traceWithInstances.get(s.getTraceId());
+ return includingInstances.contains(s.getServiceInstanceId());
+ }).collect(Collectors.toMap(
+ s -> s.getTraceId() + s.getServiceInstanceId(),
+ s -> new ArrayList<>(List.of(s)),
+ (s1, s2) -> {
+ s1.addAll(s2);
+ return s1;
+ }));
+
+ // build result
+ return instanceTraceWithSegments.values().stream()
+ .flatMap(s -> buildProfiledSegmentsList(s, profiledSegmentIdList).stream())
+ .collect(Collectors.toList());
}
- public ProfiledSegment getProfiledSegment(String segmentId) throws IOException {
- SegmentRecord segmentRecord = getProfileThreadSnapshotQueryDAO().getProfiledSegment(segmentId);
- if (segmentRecord == null) {
- return null;
+ protected List<ProfiledTraceSegments> buildProfiledSegmentsList(List<SegmentRecord> segmentRecords, List<String> profiledSegmentIdList) {
+ final Map<String, ProfiledTraceSegments> segments = segmentRecords.stream().map(s -> {
+ try {
+ return Tuple.of(s, SegmentObject.parseFrom(s.getDataBinary()));
+ } catch (InvalidProtocolBufferException e) {
+ log.warn("parsing segment data error", e);
+ return null;
+ }
+ }).filter(java.util.Objects::nonNull).filter(s -> CollectionUtils.isNotEmpty(s._2.getSpansList())).collect(Collectors.toMap(
+ tuple -> tuple._1.getSegmentId(),
+ tuple -> {
+ final IDManager.ServiceInstanceID.InstanceIDDefinition serviceInstance = IDManager.ServiceInstanceID.analysisId(tuple._1.getServiceInstanceId());
+ final ProfiledTraceSegments seg = new ProfiledTraceSegments();
+ final boolean profiled = profiledSegmentIdList.contains(tuple._1.getSegmentId());
+ seg.setTraceId(tuple._1.getTraceId());
+ seg.setInstanceId(tuple._1.getServiceInstanceId());
+ seg.setInstanceName(serviceInstance.getName());
+ seg.getEndpointNames().add(IDManager.EndpointID.analysisId(tuple._1.getEndpointId()).getEndpointName());
+ seg.setDuration(tuple._1.getLatency());
+ seg.setStart(String.valueOf(tuple._1.getStartTime()));
+ seg.getSpans().addAll(buildProfiledSpanList(tuple._2, profiled));
+ seg.setContainsProfiled(profiled);
+ return seg;
+ }
+ ));
+
+ // trying to find parent
+ final ArrayList<ProfiledTraceSegments> results = new ArrayList<>();
+ final Iterator<Map.Entry<String, ProfiledTraceSegments>> entryIterator = segments.entrySet().iterator();
+ while (entryIterator.hasNext()) {
+ // keep segment if no ref
+ final Map.Entry<String, ProfiledTraceSegments> current = entryIterator.next();
+ if (CollectionUtils.isEmpty(current.getValue().getSpans().get(0).getRefs())) {
+ results.add(current.getValue());
+ continue;
+ }
+ // keep segment if ref type is not same process(analyze only match with the same process)
+ final Ref ref = current.getValue().getSpans().get(0).getRefs().get(0);
+ if (RefType.CROSS_PROCESS.equals(ref.getType())) {
+ results.add(current.getValue());
+ continue;
+ }
+
+ // find parent segment if exist
+ final ProfiledTraceSegments parentSegments = segments.get(ref.getParentSegmentId());
+ if (parentSegments == null) {
+ results.add(current.getValue());
+ continue;
+ }
+
+ // add current segments into parent
+ parentSegments.merge(current.getValue());
+ // set parent segments(combined) as current segment
+ current.setValue(parentSegments);
}
- ProfiledSegment profiledSegment = new ProfiledSegment();
- SegmentObject segmentObject = SegmentObject.parseFrom(segmentRecord.getDataBinary());
- profiledSegment.getSpans().addAll(buildProfiledSpanList(segmentObject));
+ return results.stream().filter(ProfiledTraceSegments::isContainsProfiled).peek(this::removeAllCrossProcessRef).collect(Collectors.toList());
+ }
- return profiledSegment;
+ private void removeAllCrossProcessRef(ProfiledTraceSegments segments) {
+ segments.getSpans().stream().filter(s -> CollectionUtils.isNotEmpty(s.getRefs()))
+ .forEach(s -> s.getRefs().removeIf(ref -> RefType.CROSS_PROCESS.equals(ref.getType())));
}
- private List<ProfiledSpan> buildProfiledSpanList(SegmentObject segmentObject) {
+ private List<ProfiledSpan> buildProfiledSpanList(SegmentObject segmentObject, boolean profiled) {
List<ProfiledSpan> spans = new ArrayList<>();
segmentObject.getSpansList().forEach(spanObject -> {
ProfiledSpan span = new ProfiledSpan();
span.setSpanId(spanObject.getSpanId());
span.setParentSpanId(spanObject.getParentSpanId());
+ span.setSegmentId(segmentObject.getTraceSegmentId());
span.setStartTime(spanObject.getStartTime());
span.setEndTime(spanObject.getEndTime());
span.setError(spanObject.getIsError());
@@ -230,6 +344,24 @@ public class ProfileTaskQueryService implements Service {
span.getLogs().add(logEntity);
});
+ final List<Ref> refs = spanObject.getRefsList().stream().map(r -> {
+ final Ref ref = new Ref();
+ ref.setTraceId(r.getTraceId());
+ ref.setParentSegmentId(r.getParentTraceSegmentId());
+ ref.setParentSpanId(r.getParentSpanId());
+ switch (r.getRefType()) {
+ case CrossThread:
+ ref.setType(org.apache.skywalking.oap.server.core.query.type.RefType.CROSS_THREAD);
+ break;
+ case CrossProcess:
+ ref.setType(org.apache.skywalking.oap.server.core.query.type.RefType.CROSS_PROCESS);
+ break;
+ }
+ return ref;
+ }).collect(Collectors.toList());
+ span.setRefs(refs);
+ span.setProfiled(profiled);
+
spans.add(span);
});
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileAnalyzer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileAnalyzer.java
index 91be9a8654..65d67cd454 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileAnalyzer.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileAnalyzer.java
@@ -28,8 +28,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzation;
-import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import org.apache.skywalking.oap.server.core.query.type.ProfileStackTree;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
@@ -64,11 +64,11 @@ public class ProfileAnalyzer {
/**
* search snapshots and analyze
*/
- public ProfileAnalyzation analyze(String segmentId, List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
+ public ProfileAnalyzation analyze(final List<SegmentProfileAnalyzeQuery> queries) throws IOException {
ProfileAnalyzation analyzation = new ProfileAnalyzation();
// query sequence range list
- SequenceSearch sequenceSearch = getAllSequenceRange(segmentId, timeRanges);
+ SequenceSearch sequenceSearch = getAllSequenceRange(queries);
if (sequenceSearch == null) {
analyzation.setTip("Data not found");
return analyzation;
@@ -80,7 +80,7 @@ public class ProfileAnalyzer {
// query snapshots
List<ProfileStack> stacks = sequenceSearch.getRanges().parallelStream().map(r -> {
try {
- return getProfileThreadSnapshotQueryDAO().queryRecords(segmentId, r.getMinSequence(), r.getMaxSequence());
+ return getProfileThreadSnapshotQueryDAO().queryRecords(r.getSegmentId(), r.getMinSequence(), r.getMaxSequence());
} catch (IOException e) {
LOGGER.warn(e.getMessage(), e);
return Collections.<ProfileThreadSnapshotRecord>emptyList();
@@ -88,7 +88,7 @@ public class ProfileAnalyzer {
}).flatMap(Collection::stream).map(ProfileStack::deserialize).distinct().collect(Collectors.toList());
// analyze
- final List<ProfileStackTree> trees = analyze(stacks);
+ final List<ProfileStackTree> trees = analyzeByStack(stacks);
if (trees != null) {
analyzation.getTrees().addAll(trees);
}
@@ -96,10 +96,10 @@ public class ProfileAnalyzer {
return analyzation;
}
- protected SequenceSearch getAllSequenceRange(String segmentId, List<ProfileAnalyzeTimeRange> timeRanges) {
- final List<SequenceSearch> searches = timeRanges.parallelStream().map(r -> {
+ protected SequenceSearch getAllSequenceRange(final List<SegmentProfileAnalyzeQuery> queries) {
+ final List<SequenceSearch> searches = queries.parallelStream().map(r -> {
try {
- return getAllSequenceRange(segmentId, r.getStart(), r.getEnd());
+ return getAllSequenceRange(r.getSegmentId(), r.getTimeRange().getStart(), r.getTimeRange().getEnd());
} catch (IOException e) {
LOGGER.warn(e.getMessage(), e);
return null;
@@ -125,7 +125,7 @@ public class ProfileAnalyzer {
do {
int batchMax = Math.min(minSequence + threadSnapshotAnalyzeBatchSize, maxSequence);
- sequenceSearch.getRanges().add(new SequenceRange(minSequence, batchMax));
+ sequenceSearch.getRanges().add(new SequenceRange(segmentId, minSequence, batchMax));
minSequence = batchMax;
}
while (minSequence < maxSequence);
@@ -136,7 +136,7 @@ public class ProfileAnalyzer {
/**
* Analyze records
*/
- protected List<ProfileStackTree> analyze(List<ProfileStack> stacks) {
+ protected List<ProfileStackTree> analyzeByStack(List<ProfileStack> stacks) {
if (CollectionUtils.isEmpty(stacks)) {
return null;
}
@@ -184,14 +184,20 @@ public class ProfileAnalyzer {
}
private static class SequenceRange {
+ private String segmentId;
private int minSequence;
private int maxSequence;
- public SequenceRange(int minSequence, int maxSequence) {
+ public SequenceRange(String segmentId, int minSequence, int maxSequence) {
+ this.segmentId = segmentId;
this.minSequence = minSequence;
this.maxSequence = maxSequence;
}
+ public String getSegmentId() {
+ return segmentId;
+ }
+
public int getMinSequence() {
return minSequence;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/SegmentProfileAnalyzeQuery.java
similarity index 65%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/SegmentProfileAnalyzeQuery.java
index 08acc5a155..5d0b3c8d4a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/SegmentProfileAnalyzeQuery.java
@@ -16,22 +16,19 @@
*
*/
-package org.apache.skywalking.oap.server.core.query.type;
+package org.apache.skywalking.oap.server.core.query.input;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
-import java.util.ArrayList;
-import java.util.List;
-
-@Getter
-@Setter
-public class ProfiledSegment {
-
- private final List<ProfiledSpan> spans;
-
- public ProfiledSegment() {
- this.spans = new ArrayList<>();
- }
-
-}
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class SegmentProfileAnalyzeQuery {
+ private String segmentId;
+ private ProfileAnalyzeTimeRange timeRange;
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/KVInt.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/KVInt.java
index 6cbe687259..cbe6b2c5e1 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/KVInt.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/KVInt.java
@@ -26,4 +26,5 @@ import lombok.Setter;
public class KVInt {
private String id;
private long value;
+ private boolean isEmptyValue;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/NullableValue.java
similarity index 76%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/NullableValue.java
index 08acc5a155..8462ea693c 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/NullableValue.java
@@ -18,20 +18,10 @@
package org.apache.skywalking.oap.server.core.query.type;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Getter
-@Setter
-public class ProfiledSegment {
-
- private final List<ProfiledSpan> spans;
-
- public ProfiledSegment() {
- this.spans = new ArrayList<>();
- }
+import lombok.Data;
+@Data
+public class NullableValue {
+ private long value;
+ private boolean isEmptyValue;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSpan.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSpan.java
index 0bce4e93c6..6930f7b6f8 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSpan.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSpan.java
@@ -29,6 +29,8 @@ public class ProfiledSpan {
private int spanId;
private int parentSpanId;
+ private String segmentId;
+ private List<Ref> refs;
private String serviceCode;
private String serviceInstanceName;
private long startTime;
@@ -41,6 +43,7 @@ public class ProfiledSpan {
private String layer;
private final List<KeyValue> tags;
private final List<LogEntity> logs;
+ private boolean profiled;
public ProfiledSpan() {
this.tags = new ArrayList<>();
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledTraceSegments.java
similarity index 61%
rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledTraceSegments.java
index 08acc5a155..04996a38ae 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledSegment.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProfiledTraceSegments.java
@@ -18,20 +18,31 @@
package org.apache.skywalking.oap.server.core.query.type;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
import java.util.ArrayList;
import java.util.List;
-@Getter
-@Setter
-public class ProfiledSegment {
+@Data
+public class ProfiledTraceSegments {
+ private String traceId;
+ private String instanceId;
+ private String instanceName;
+ private List<String> endpointNames;
+ private int duration;
+ private String start;
+ private List<ProfiledSpan> spans;
+ private boolean containsProfiled;
- private final List<ProfiledSpan> spans;
-
- public ProfiledSegment() {
+ public ProfiledTraceSegments() {
+ this.endpointNames = new ArrayList<>();
this.spans = new ArrayList<>();
}
+ public void merge(ProfiledTraceSegments other) {
+ this.spans.addAll(other.spans);
+ if (!this.containsProfiled) {
+ this.containsProfiled = other.containsProfiled;
+ }
+ }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/trace/IProfileThreadSnapshotQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/trace/IProfileThreadSnapshotQueryDAO.java
index c063fa50f9..d5894b0746 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/trace/IProfileThreadSnapshotQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/trace/IProfileThreadSnapshotQueryDAO.java
@@ -21,9 +21,7 @@ package org.apache.skywalking.oap.server.core.storage.profiling.trace;
import java.io.IOException;
import java.util.List;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.DAO;
/**
@@ -32,11 +30,11 @@ import org.apache.skywalking.oap.server.core.storage.DAO;
public interface IProfileThreadSnapshotQueryDAO extends DAO {
/**
- * search all profiled segments, need appoint taskId and snapshot sequence equals 0 sort by segment start time
+ * search all profiled segment id list, need appoint taskId and snapshot sequence equals 0 sort by segment start time
*
* @return it represents the segments having profile snapshot data.
*/
- List<BasicTrace> queryProfiledSegments(String taskId) throws IOException;
+ List<String> queryProfiledSegmentIdList(String taskId) throws IOException;
/**
* search snapshots min sequence
@@ -58,8 +56,4 @@ public interface IProfileThreadSnapshotQueryDAO extends DAO {
*/
List<ProfileThreadSnapshotRecord> queryRecords(String segmentId, int minSequence, int maxSequence) throws IOException;
- /**
- * search segment data
- */
- SegmentRecord getProfiledSegment(String segmentId) throws IOException;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITraceQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITraceQueryDAO.java
index d5fc9e923c..2bf1ae7f87 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITraceQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITraceQueryDAO.java
@@ -46,6 +46,10 @@ public interface ITraceQueryDAO extends Service {
List<SegmentRecord> queryByTraceId(String traceId) throws IOException;
+ List<SegmentRecord> queryBySegmentIdList(List<String> segmentIdList) throws IOException;
+
+ List<SegmentRecord> queryByTraceIdWithInstanceId(List<String> traceIdList, List<String> instanceIdList) throws IOException;
+
/**
* This method gives more flexible for 3rd trace without segment concept, which can't search data through {@link #queryByTraceId(String)}
*/
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryServiceTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryServiceTest.java
new file mode 100644
index 0000000000..11550f7f07
--- /dev/null
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryServiceTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.profiling.trace;
+
+import org.apache.skywalking.apm.network.language.agent.v3.RefType;
+import org.apache.skywalking.apm.network.language.agent.v3.SegmentObject;
+import org.apache.skywalking.apm.network.language.agent.v3.SegmentReference;
+import org.apache.skywalking.apm.network.language.agent.v3.SpanObject;
+import org.apache.skywalking.oap.server.core.CoreModuleConfig;
+import org.apache.skywalking.oap.server.core.CoreModuleProvider;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
+import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
+import org.apache.skywalking.oap.server.core.query.type.ProfiledTraceSegments;
+import org.apache.skywalking.oap.server.core.query.type.ProfiledSpan;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.library.module.ModuleProviderHolder;
+import org.apache.skywalking.oap.server.library.util.StringUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.opentest4j.AssertionFailedError;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class ProfileTaskQueryServiceTest {
+
+ @Mock
+ private ModuleManager moduleManager;
+ @Mock
+ private CoreModuleConfig moduleConfig;
+ @Mock
+ private ModuleProviderHolder providerHolder;
+ @Mock
+ private CoreModuleProvider coreModuleProvider;
+ @Mock
+ private IComponentLibraryCatalogService catalogService;
+
+ @BeforeEach
+ public void setup() {
+ when(moduleManager.find(anyString())).thenReturn(providerHolder);
+ when(providerHolder.provider()).thenReturn(coreModuleProvider);
+ when(coreModuleProvider.getService(IComponentLibraryCatalogService.class)).thenReturn(catalogService);
+ when(catalogService.getComponentName(anyInt())).thenReturn("");
+ when(moduleConfig.getMaxPageSizeOfQueryProfileSnapshot()).thenReturn(1);
+ when(moduleConfig.getMaxSizeOfAnalyzeProfileSnapshot()).thenReturn(1);
+ }
+
+ @Test
+ public void testBuildProfiledSegmentsList() {
+ // all segment in same process
+ validate(Arrays.asList(
+ buildRecord("1B", "2A", RefType.CrossThread),
+ buildRecord("2A", "", null),
+ buildRecord("3C", "1B", RefType.CrossThread)
+ ), Arrays.asList(
+ Arrays.asList("2A", "1B", "3C")
+ ));
+
+ // segment with different process
+ validate(Arrays.asList(
+ buildRecord("A", "", null),
+ buildRecord("B", "A", RefType.CrossThread),
+
+ buildRecord("C", "B", RefType.CrossProcess),
+
+ buildRecord("D", "Z", RefType.CrossThread)
+ ), Arrays.asList(
+ Arrays.asList("A", "B"),
+ Arrays.asList("C"),
+ Arrays.asList("D")
+ ));
+ }
+
+ private void validate(List<SegmentRecord> records, List<List<String>> excepted) {
+ final ProfileTaskQueryService profileTaskQueryService = new ProfileTaskQueryService(moduleManager, moduleConfig);
+ final List<ProfiledTraceSegments> result = profileTaskQueryService.buildProfiledSegmentsList(records, records.stream().map(SegmentRecord::getSegmentId).collect(Collectors.toList()));
+ assertEquals(result.size(), excepted.size(), "result size not same");
+ for (List<String> exceptedSegments : excepted) {
+ boolean found = false;
+ for (ProfiledTraceSegments segments : result) {
+ if (segments.getSpans().stream().map(ProfiledSpan::getSegmentId).collect(Collectors.toList()).equals(exceptedSegments)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new AssertionFailedError("cannot find any matches result of {}, all actual data: {}",
+ exceptedSegments, result.stream().map(segments -> segments.getSpans().stream().map(ProfiledSpan::getSegmentId).collect(Collectors.toList())).collect(Collectors.toList()));
+ }
+ }
+ }
+
+ private SegmentRecord buildRecord(String segmentId, String parentSegmentId, RefType refType) {
+ final SegmentRecord record = new SegmentRecord();
+ record.setSegmentId(segmentId);
+ final String testServiceId = IDManager.ServiceID.buildId("test", true);
+ record.setServiceInstanceId(IDManager.ServiceInstanceID.buildId(testServiceId, "test"));
+ record.setEndpointId(IDManager.EndpointID.buildId(testServiceId, "test"));
+ final SegmentObject.Builder builder = SegmentObject.newBuilder();
+ builder.setTraceSegmentId(segmentId);
+ final SpanObject.Builder firstSpan = SpanObject.newBuilder();
+ if (StringUtil.isNotEmpty(parentSegmentId)) {
+ firstSpan.addRefs(SegmentReference.newBuilder()
+ .setParentTraceSegmentId(parentSegmentId)
+ .setRefType(refType).build());
+ }
+ builder.addSpans(firstSpan.build());
+ record.setDataBinary(builder.build().toByteArray());
+ return record;
+ }
+}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackAnalyze.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackAnalyze.java
index 6844cee254..fa0272da7a 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackAnalyze.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackAnalyze.java
@@ -23,10 +23,8 @@ import java.util.List;
import java.util.stream.Collectors;
import lombok.Data;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
-import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileStackTree;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
@@ -41,9 +39,9 @@ public class ProfileStackAnalyze {
public void analyzeAndAssert(int maxAnalyzeCount) throws IOException {
List<ProfileThreadSnapshotRecord> stacks = data.transformSnapshots();
- final List<ProfileAnalyzeTimeRange> ranges = data.transformTimeRanges();
+ final List<SegmentProfileAnalyzeQuery> queries = data.transformQueries();
- List<ProfileStackTree> trees = buildAnalyzer(stacks, maxAnalyzeCount).analyze(null, ranges).getTrees();
+ List<ProfileStackTree> trees = buildAnalyzer(stacks, maxAnalyzeCount).analyze(queries).getTrees();
assertNotNull(trees);
assertEquals(trees.size(), expected.size());
@@ -67,7 +65,7 @@ public class ProfileStackAnalyze {
}
@Override
- public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException {
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
return null;
}
@@ -99,11 +97,6 @@ public class ProfileStackAnalyze {
.collect(Collectors.toList());
}
- @Override
- public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
- return null;
- }
-
}
}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackData.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackData.java
index 7948518da2..aee8ae0dbd 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackData.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/profiling/trace/analyze/ProfileStackData.java
@@ -22,6 +22,7 @@ import com.google.common.base.Splitter;
import lombok.Data;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadStack;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import java.util.ArrayList;
@@ -49,19 +50,19 @@ public class ProfileStackData {
return result;
}
- public List<ProfileAnalyzeTimeRange> transformTimeRanges() {
+ public List<SegmentProfileAnalyzeQuery> transformQueries() {
final String[] timeRangeString = this.timeRanges.split(",");
- final ArrayList<ProfileAnalyzeTimeRange> ranges = new ArrayList<>();
+ final ArrayList<SegmentProfileAnalyzeQuery> result = new ArrayList<>();
for (String timeRange : timeRangeString) {
final ProfileAnalyzeTimeRange range = new ProfileAnalyzeTimeRange();
final String[] startEndTimes = timeRange.split("-");
range.setStart(Integer.parseInt(startEndTimes[0]) * limit);
range.setEnd(Integer.parseInt(startEndTimes[1]) * limit);
- ranges.add(range);
+ result.add(SegmentProfileAnalyzeQuery.builder().timeRange(range).build());
}
- return ranges;
+ return result;
}
}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
index 4cb19b1803..00ea8c0979 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
@@ -52,43 +52,43 @@ public class MetricsQueryUtilTest {
asList("200", "400"),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2"), "202007291426", new DataTable("200,3|400,8")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":3}]}}," +
- "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2},{\"id\":\"202007291426\",\"value\":8}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":3,\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":8,\"isEmptyValue\":false}]}}]"
},
{
asList("400", "200"),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2"), "202007291426", new DataTable("200,3|400,8")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":3}]}}," +
- "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2},{\"id\":\"202007291426\",\"value\":8}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":3,\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":8,\"isEmptyValue\":false}]}}]"
},
{
Collections.emptyList(),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2"), "202007291426", new DataTable("200,3|400,8")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":3}]}}," +
- "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2},{\"id\":\"202007291426\",\"value\":8}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":3,\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":8,\"isEmptyValue\":false}]}}]"
},
{
Collections.singletonList("200"),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2"), "202007291426", new DataTable("200,3|400,8")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":3}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":3,\"isEmptyValue\":false}]}}]"
},
{
asList("200", "400", "500"),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2"), "202007291426", new DataTable("200,3|400,8")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":3}]}}," +
- "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2},{\"id\":\"202007291426\",\"value\":8}]}}," +
- "{\"label\":\"500\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":" + DEFAULT_VALUE + "},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + "}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":3,\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":8,\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"500\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":" + DEFAULT_VALUE + ",\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + ",\"isEmptyValue\":false}]}}]"
},
{
asList("200", "400"),
asList("202007291425", "202007291426"),
of("202007291425", new DataTable("200,1|400,2")),
- "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + "}]}}," +
- "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + "}]}}]"
+ "[{\"label\":\"200\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":1,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + ",\"isEmptyValue\":false}]}}," +
+ "{\"label\":\"400\",\"values\":{\"values\":[{\"id\":\"202007291425\",\"value\":2,\"isEmptyValue\":false},{\"id\":\"202007291426\",\"value\":" + DEFAULT_VALUE + ",\"isEmptyValue\":false}]}}]"
},
});
}
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
index d4b6f9cc34..06977eed16 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
@@ -35,6 +35,7 @@ import org.apache.skywalking.oap.server.core.query.type.HeatMap;
import org.apache.skywalking.oap.server.core.query.type.IntValues;
import org.apache.skywalking.oap.server.core.query.type.KVInt;
import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
+import org.apache.skywalking.oap.server.core.query.type.NullableValue;
import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -92,6 +93,14 @@ public class MetricQuery implements GraphQLQueryResolver {
return metricsValues.getValues();
}
+ public NullableValue readNullableMetricsValue(MetricsCondition condition, Duration duration) {
+ // TODO default implantation
+ final NullableValue nullableValue = new NullableValue();
+ nullableValue.setValue(0);
+ nullableValue.setEmptyValue(true);
+ return nullableValue;
+ }
+
public List<IntValues> getMultipleLinearIntValues(final MetricCondition metrics, final int numOfLinear,
final Duration duration) throws IOException {
MetricsCondition condition = new MetricsCondition();
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ProfileQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ProfileQuery.java
index 6ac4f93752..3811cfd1e6 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ProfileQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ProfileQuery.java
@@ -21,12 +21,11 @@ package org.apache.skywalking.oap.query.graphql.resolver;
import graphql.kickstart.tools.GraphQLQueryResolver;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileTaskQueryService;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzation;
-import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import org.apache.skywalking.oap.server.core.query.type.ProfileTask;
import org.apache.skywalking.oap.server.core.query.type.ProfileTaskLog;
-import org.apache.skywalking.oap.server.core.query.type.ProfiledSegment;
+import org.apache.skywalking.oap.server.core.query.type.ProfiledTraceSegments;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import java.io.IOException;
@@ -61,16 +60,12 @@ public class ProfileQuery implements GraphQLQueryResolver {
return getProfileTaskQueryService().getProfileTaskLogs(taskID);
}
- public List<BasicTrace> getProfileTaskSegmentList(final String taskID) throws IOException {
- return getProfileTaskQueryService().getTaskTraces(taskID);
+ public List<ProfiledTraceSegments> getProfileTaskSegments(String taskId) throws IOException {
+ return getProfileTaskQueryService().getProfileTaskSegments(taskId);
}
- public ProfiledSegment getProfiledSegment(final String segmentId) throws IOException {
- return getProfileTaskQueryService().getProfiledSegment(segmentId);
- }
-
- public ProfileAnalyzation getProfileAnalyze(final String segmentId, final List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
- return getProfileTaskQueryService().getProfileAnalyze(segmentId, timeRanges);
+ public ProfileAnalyzation getSegmentsProfileAnalyze(final List<SegmentProfileAnalyzeQuery> queries) throws IOException {
+ return getProfileTaskQueryService().getProfileAnalyze(queries);
}
}
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
index 4749946962..06789e114b 160000
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
@@ -1 +1 @@
-Subproject commit 4749946962b9c685111876d1abe8c745d3cf3253
+Subproject commit 06789e114b321b19cd23802ea7cb210732b3dbf3
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBProfileThreadSnapshotQueryDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBProfileThreadSnapshotQueryDAO.java
index 3072d6337f..d688a84686 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBProfileThreadSnapshotQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBProfileThreadSnapshotQueryDAO.java
@@ -19,16 +19,12 @@
package org.apache.skywalking.oap.server.storage.plugin.banyandb.stream;
import com.google.common.collect.ImmutableSet;
-import org.apache.skywalking.banyandb.v1.client.Element;
import org.apache.skywalking.banyandb.v1.client.RowEntity;
import org.apache.skywalking.banyandb.v1.client.StreamQuery;
import org.apache.skywalking.banyandb.v1.client.StreamQueryResponse;
-import org.apache.skywalking.oap.server.core.analysis.IDManager;
import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
-import org.apache.skywalking.oap.server.library.util.BooleanUtils;
import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBConverter;
import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBStorageClient;
@@ -80,7 +76,7 @@ public class BanyanDBProfileThreadSnapshotQueryDAO extends AbstractBanyanDBDAO i
}
@Override
- public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException {
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
StreamQueryResponse resp = query(ProfileThreadSnapshotRecord.INDEX_NAME,
TAGS_BASIC,
new QueryBuilder<StreamQuery>() {
@@ -102,42 +98,7 @@ public class BanyanDBProfileThreadSnapshotQueryDAO extends AbstractBanyanDBDAO i
segmentIds.add(rowEntity.getTagValue(ProfileThreadSnapshotRecord.SEGMENT_ID));
}
- if (segmentIds.isEmpty()) {
- return Collections.emptyList();
- }
-
- final StreamQueryResponse segmentRecordResp = query(SegmentRecord.INDEX_NAME,
- TAGS_TRACE,
- new QueryBuilder<StreamQuery>() {
- @Override
- public void apply(StreamQuery traceQuery) {
- // TODO: use "in" operator
- for (final String segmentID : segmentIds) {
- traceQuery.or(eq(SegmentRecord.SEGMENT_ID, segmentID));
- }
- traceQuery.setLimit(segmentIds.size());
- traceQuery.setOrderBy(desc(SegmentRecord.START_TIME));
- }
- });
-
- List<BasicTrace> basicTraces = new ArrayList<>();
- for (final Element row : segmentRecordResp.getElements()) {
- BasicTrace basicTrace = new BasicTrace();
-
- basicTrace.setSegmentId(row.getId());
- basicTrace.setStart(String.valueOf((Number) row.getTagValue(SegmentRecord.START_TIME)));
- basicTrace.getEndpointNames().add(IDManager.EndpointID.analysisId(
- row.getTagValue(SegmentRecord.ENDPOINT_ID)
- ).getEndpointName());
- basicTrace.setDuration(((Number) row.getTagValue(SegmentRecord.LATENCY)).intValue());
- basicTrace.setError(BooleanUtils.valueToBoolean(
- ((Number) row.getTagValue(SegmentRecord.IS_ERROR)).intValue()
- ));
- basicTrace.getTraceIds().add(row.getTagValue(SegmentRecord.TRACE_ID));
-
- basicTraces.add(basicTrace);
- }
- return basicTraces;
+ return segmentIds;
}
@Override
@@ -172,26 +133,6 @@ public class BanyanDBProfileThreadSnapshotQueryDAO extends AbstractBanyanDBDAO i
return result;
}
- @Override
- public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
- StreamQueryResponse resp = query(SegmentRecord.INDEX_NAME,
- TAGS_TRACE_ALL,
- new QueryBuilder<StreamQuery>() {
- @Override
- public void apply(StreamQuery query) {
- query.and(eq(SegmentRecord.SEGMENT_ID, segmentId));
- }
- });
-
- if (resp.size() == 0) {
- return null;
- }
-
- final RowEntity rowEntity = resp.getElements().iterator().next();
- return new SegmentRecord.Builder().storage2Entity(
- new BanyanDBConverter.StorageToStream(SegmentRecord.INDEX_NAME, rowEntity));
- }
-
private int querySequenceWithAgg(AggType aggType, String segmentId, long start, long end) throws IOException {
StreamQueryResponse resp = query(ProfileThreadSnapshotRecord.INDEX_NAME,
TAGS_ALL,
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBTraceQueryDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBTraceQueryDAO.java
index 641204bc3d..69113c005c 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBTraceQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBTraceQueryDAO.java
@@ -68,6 +68,7 @@ public class BanyanDBTraceQueryDAO extends AbstractBanyanDBDAO implements ITrace
SegmentRecord.ENDPOINT_ID,
SegmentRecord.LATENCY,
SegmentRecord.START_TIME,
+ SegmentRecord.SEGMENT_ID,
SegmentRecord.DATA_BINARY);
public BanyanDBTraceQueryDAO(BanyanDBStorageClient client) {
@@ -182,20 +183,48 @@ public class BanyanDBTraceQueryDAO extends AbstractBanyanDBDAO implements ITrace
query.and(eq(SegmentRecord.TRACE_ID, traceId));
}
});
+ return buildRecords(resp);
+ }
+
+ @Override
+ public List<SegmentRecord> queryBySegmentIdList(List<String> segmentIdList) throws IOException {
+ StreamQueryResponse resp = query(SegmentRecord.INDEX_NAME, TAGS,
+ new QueryBuilder<StreamQuery>() {
+ @Override
+ public void apply(StreamQuery query) {
+ query.and(in(SegmentRecord.SEGMENT_ID, segmentIdList));
+ }
+ });
+ return buildRecords(resp);
+ }
+
+ @Override
+ public List<SegmentRecord> queryByTraceIdWithInstanceId(List<String> traceIdList, List<String> instanceIdList) throws IOException {
+ StreamQueryResponse resp = query(SegmentRecord.INDEX_NAME, TAGS,
+ new QueryBuilder<StreamQuery>() {
+ @Override
+ public void apply(StreamQuery query) {
+ query.and(in(SegmentRecord.TRACE_ID, traceIdList));
+ query.and(in(SegmentRecord.SERVICE_INSTANCE_ID, instanceIdList));
+ }
+ });
+ return buildRecords(resp);
+ }
+ @Override
+ public List<Span> doFlexibleTraceQuery(String traceId) throws IOException {
+ return Collections.emptyList();
+ }
+
+ private List<SegmentRecord> buildRecords(StreamQueryResponse resp) {
List<SegmentRecord> segmentRecords = new ArrayList<>(resp.getElements().size());
for (final RowEntity rowEntity : resp.getElements()) {
SegmentRecord segmentRecord = new SegmentRecord.Builder().storage2Entity(
- new BanyanDBConverter.StorageToStream(SegmentRecord.INDEX_NAME, rowEntity));
+ new BanyanDBConverter.StorageToStream(SegmentRecord.INDEX_NAME, rowEntity));
segmentRecords.add(segmentRecord);
}
return segmentRecords;
}
-
- @Override
- public List<Span> doFlexibleTraceQuery(String traceId) throws IOException {
- return Collections.emptyList();
- }
}
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ProfileThreadSnapshotQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ProfileThreadSnapshotQueryEsDAO.java
index 97f2ee26c5..5669ead679 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ProfileThreadSnapshotQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ProfileThreadSnapshotQueryEsDAO.java
@@ -18,13 +18,12 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
-import com.google.common.base.Strings;
+import java.io.IOException;
import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+
import org.apache.skywalking.library.elasticsearch.requests.search.BoolQueryBuilder;
import org.apache.skywalking.library.elasticsearch.requests.search.Query;
import org.apache.skywalking.library.elasticsearch.requests.search.Search;
@@ -34,14 +33,9 @@ import org.apache.skywalking.library.elasticsearch.requests.search.aggregation.A
import org.apache.skywalking.library.elasticsearch.requests.search.aggregation.AggregationBuilder;
import org.apache.skywalking.library.elasticsearch.response.search.SearchHit;
import org.apache.skywalking.library.elasticsearch.response.search.SearchResponse;
-import org.apache.skywalking.oap.server.core.analysis.IDManager;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
-import org.apache.skywalking.oap.server.library.util.BooleanUtils;
-import org.apache.skywalking.oap.server.library.util.CollectionUtils;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.ElasticSearchConverter;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.IndexController;
@@ -61,22 +55,22 @@ public class ProfileThreadSnapshotQueryEsDAO extends EsDAO
}
@Override
- public List<BasicTrace> queryProfiledSegments(String taskId) {
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
final BoolQueryBuilder segmentIdQuery =
Query.bool()
- .must(Query.term(ProfileThreadSnapshotRecord.TASK_ID, taskId))
- .must(Query.term(ProfileThreadSnapshotRecord.SEQUENCE, 0));
+ .must(Query.term(ProfileThreadSnapshotRecord.TASK_ID, taskId))
+ .must(Query.term(ProfileThreadSnapshotRecord.SEQUENCE, 0));
if (IndexController.LogicIndicesRegister.isMergedTable(ProfileThreadSnapshotRecord.INDEX_NAME)) {
segmentIdQuery.must(Query.term(IndexController.LogicIndicesRegister.RECORD_TABLE_NAME, ProfileThreadSnapshotRecord.INDEX_NAME));
}
final SearchBuilder search =
Search.builder().query(segmentIdQuery)
- .size(querySegmentMaxSize)
- .sort(
- ProfileThreadSnapshotRecord.DUMP_TIME,
- Sort.Order.DESC
- );
+ .size(querySegmentMaxSize)
+ .sort(
+ ProfileThreadSnapshotRecord.DUMP_TIME,
+ Sort.Order.DESC
+ );
SearchResponse response =
getClient().search(
@@ -90,44 +84,7 @@ public class ProfileThreadSnapshotQueryEsDAO extends EsDAO
segmentIds.add(
(String) searchHit.getSource().get(ProfileThreadSnapshotRecord.SEGMENT_ID));
}
-
- if (CollectionUtils.isEmpty(segmentIds)) {
- return Collections.emptyList();
- }
-
- final BoolQueryBuilder traceQuery = Query.bool();
- for (String segmentId : segmentIds) {
- traceQuery.should(Query.term(SegmentRecord.SEGMENT_ID, segmentId));
- }
- final SearchBuilder traceSearch =
- Search.builder().query(traceQuery)
- .size(segmentIds.size())
- .sort(SegmentRecord.START_TIME, Sort.Order.DESC);
-
- response = getClient().search(SegmentRecord.INDEX_NAME, traceSearch.build());
-
- List<BasicTrace> result = new ArrayList<>();
- for (SearchHit searchHit : response.getHits().getHits()) {
- BasicTrace basicTrace = new BasicTrace();
-
- basicTrace.setSegmentId((String) searchHit.getSource().get(SegmentRecord.SEGMENT_ID));
- basicTrace.setStart(
- String.valueOf(searchHit.getSource().get(SegmentRecord.START_TIME)));
- basicTrace.getEndpointNames().add(
- IDManager.EndpointID.analysisId(
- (String) searchHit.getSource().get(SegmentRecord.ENDPOINT_ID)
- ).getEndpointName());
- basicTrace.setDuration(
- ((Number) searchHit.getSource().get(SegmentRecord.LATENCY)).intValue());
- basicTrace.setError(BooleanUtils.valueToBoolean(
- ((Number) searchHit.getSource().get(SegmentRecord.IS_ERROR)).intValue()));
- basicTrace.getTraceIds()
- .add((String) searchHit.getSource().get(SegmentRecord.TRACE_ID));
-
- result.add(basicTrace);
- }
-
- return result;
+ return segmentIds;
}
@Override
@@ -177,38 +134,6 @@ public class ProfileThreadSnapshotQueryEsDAO extends EsDAO
return result;
}
- @Override
- public SegmentRecord getProfiledSegment(String segmentId) {
- final String index =
- IndexController.LogicIndicesRegister.getPhysicalTableName(SegmentRecord.INDEX_NAME);
- final SearchBuilder search =
- Search.builder()
- .query(Query.term(SegmentRecord.SEGMENT_ID, segmentId))
- .size(1);
-
- final SearchResponse response = getClient().search(index, search.build());
-
- if (response.getHits().getHits().isEmpty()) {
- return null;
- }
- final SearchHit searchHit = response.getHits().iterator().next();
- final SegmentRecord segmentRecord = new SegmentRecord();
- segmentRecord.setSegmentId((String) searchHit.getSource().get(SegmentRecord.SEGMENT_ID));
- segmentRecord.setTraceId((String) searchHit.getSource().get(SegmentRecord.TRACE_ID));
- segmentRecord.setServiceId((String) searchHit.getSource().get(SegmentRecord.SERVICE_ID));
- segmentRecord.setStartTime(
- ((Number) searchHit.getSource().get(SegmentRecord.START_TIME)).longValue());
- segmentRecord.setLatency(
- ((Number) searchHit.getSource().get(SegmentRecord.LATENCY)).intValue());
- segmentRecord.setIsError(
- ((Number) searchHit.getSource().get(SegmentRecord.IS_ERROR)).intValue());
- String dataBinaryBase64 = (String) searchHit.getSource().get(SegmentRecord.DATA_BINARY);
- if (!Strings.isNullOrEmpty(dataBinaryBase64)) {
- segmentRecord.setDataBinary(Base64.getDecoder().decode(dataBinaryBase64));
- }
- return segmentRecord;
- }
-
protected int querySequenceWithAgg(AggregationBuilder aggregationBuilder,
String segmentId, long start, long end) {
final BoolQueryBuilder query =
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TraceQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TraceQueryEsDAO.java
index 7e98512f18..c8fdb2eef6 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TraceQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TraceQueryEsDAO.java
@@ -184,6 +184,47 @@ public class TraceQueryEsDAO extends EsDAO implements ITraceQueryDAO {
final SearchResponse response = getClient().search(index, search.build(), searchParams);
+ return buildRecords(response);
+ }
+
+ @Override
+ public List<SegmentRecord> queryBySegmentIdList(List<String> segmentIdList) throws IOException {
+ final String index =
+ IndexController.LogicIndicesRegister.getPhysicalTableName(SegmentRecord.INDEX_NAME);
+
+ final SearchBuilder search =
+ Search.builder()
+ .query(Query.terms(SegmentRecord.SEGMENT_ID, segmentIdList))
+ .size(segmentQueryMaxSize);
+
+ SearchParams searchParams = new SearchParams();
+ final SearchResponse response = getClient().search(index, search.build(), searchParams);
+
+ return buildRecords(response);
+ }
+
+ @Override
+ public List<SegmentRecord> queryByTraceIdWithInstanceId(List<String> traceIdList, List<String> instanceIdList) throws IOException {
+ final String index =
+ IndexController.LogicIndicesRegister.getPhysicalTableName(SegmentRecord.INDEX_NAME);
+
+ final SearchBuilder search =
+ Search.builder()
+ .query(Query.bool().must(Query.terms(SegmentRecord.TRACE_ID, traceIdList)).must(Query.terms(SegmentRecord.SERVICE_INSTANCE_ID, instanceIdList)))
+ .size(segmentQueryMaxSize);
+
+ SearchParams searchParams = new SearchParams();
+ final SearchResponse response = getClient().search(index, search.build(), searchParams);
+
+ return buildRecords(response);
+ }
+
+ @Override
+ public List<Span> doFlexibleTraceQuery(String traceId) throws IOException {
+ return Collections.emptyList();
+ }
+
+ private List<SegmentRecord> buildRecords(SearchResponse response) {
List<SegmentRecord> segmentRecords = new ArrayList<>();
for (SearchHit searchHit : response.getHits().getHits()) {
SegmentRecord segmentRecord = new SegmentRecord.Builder().storage2Entity(
@@ -192,9 +233,4 @@ public class TraceQueryEsDAO extends EsDAO implements ITraceQueryDAO {
}
return segmentRecords;
}
-
- @Override
- public List<Span> doFlexibleTraceQuery(String traceId) throws IOException {
- return Collections.emptyList();
- }
}
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCProfileThreadSnapshotQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCProfileThreadSnapshotQueryDAO.java
index 5370a5b43b..2da30dd129 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCProfileThreadSnapshotQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCProfileThreadSnapshotQueryDAO.java
@@ -18,100 +18,36 @@
package org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao;
-import com.google.common.base.Strings;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
-import org.apache.skywalking.oap.server.core.analysis.IDManager;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
-import org.apache.skywalking.oap.server.library.util.BooleanUtils;
import org.apache.skywalking.oap.server.library.util.StringUtil;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
-import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.SQLAndParameters;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Base64;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.stream.IntStream;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
-
@RequiredArgsConstructor
public class JDBCProfileThreadSnapshotQueryDAO implements IProfileThreadSnapshotQueryDAO {
private final JDBCClient jdbcClient;
private final TableHelper tableHelper;
- @Override
@SneakyThrows
- public List<BasicTrace> queryProfiledSegments(String taskId) {
- final var tables = tableHelper.getTablesWithinTTL(ProfileThreadSnapshotRecord.INDEX_NAME);
- final var results = new ArrayList<BasicTrace>();
- final var segments = new ArrayList<>();
-
- for (String table : tables) {
+ @Override
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
+ final var snapshotTables = tableHelper.getTablesWithinTTL(ProfileThreadSnapshotRecord.INDEX_NAME);
+ final var segments = new ArrayList<String>();
+ for (String table : snapshotTables) {
segments.addAll(querySegments(taskId, table));
}
-
- if (segments.isEmpty()) {
- return Collections.emptyList();
- }
-
- final var segmentTables = tableHelper.getTablesWithinTTL(SegmentRecord.INDEX_NAME);
- for (String table : segmentTables) {
- final var sql = new StringBuilder();
- final var parameters = new ArrayList<>();
-
- sql.append("select * from ").append(table).append(" where ")
- .append(JDBCTableInstaller.TABLE_COLUMN).append(" = ? and ");
- parameters.add(SegmentRecord.INDEX_NAME);
-
- final var segmentQuery =
- segments
- .stream()
- .map(it -> SegmentRecord.SEGMENT_ID + " = ? ")
- .collect(joining(" or ", "(", ")"));
- sql.append(segmentQuery);
- parameters.addAll(segments);
- sql.append(" order by ").append(SegmentRecord.START_TIME).append(" ").append("desc");
-
- final var sqlAndParameters = new SQLAndParameters(sql.toString(), parameters);
-
- jdbcClient.executeQuery(
- sqlAndParameters.sql(),
- resultSet -> {
- while (resultSet.next()) {
- BasicTrace basicTrace = new BasicTrace();
-
- basicTrace.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID));
- basicTrace.setStart(resultSet.getString(SegmentRecord.START_TIME));
- basicTrace.getEndpointNames().add(
- IDManager.EndpointID.analysisId(
- resultSet.getString(SegmentRecord.ENDPOINT_ID)).getEndpointName()
- );
- basicTrace.setDuration(resultSet.getInt(SegmentRecord.LATENCY));
- basicTrace.setError(BooleanUtils.valueToBoolean(resultSet.getInt(SegmentRecord.IS_ERROR)));
- String traceIds = resultSet.getString(SegmentRecord.TRACE_ID);
- basicTrace.getTraceIds().add(traceIds);
-
- results.add(basicTrace);
- }
- return null;
- },
- sqlAndParameters.parameters());
- }
- return results
- .stream()
- .sorted(Comparator.<BasicTrace, Long>comparing(it -> Long.parseLong(it.getStart())).reversed())
- .collect(toList());
+ return segments;
}
protected ArrayList<String> querySegments(String taskId, String table) throws SQLException {
@@ -193,42 +129,6 @@ public class JDBCProfileThreadSnapshotQueryDAO implements IProfileThreadSnapshot
return results;
}
- @Override
- @SneakyThrows
- public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
- final var tables = tableHelper.getTablesWithinTTL(SegmentRecord.INDEX_NAME);
- for (final var table : tables) {
- final var r = jdbcClient.executeQuery(
- "select * from " + table +
- " where " + JDBCTableInstaller.TABLE_COLUMN + " = ?" +
- " and " + SegmentRecord.SEGMENT_ID + " = ?",
- resultSet -> {
- if (resultSet.next()) {
- SegmentRecord segmentRecord = new SegmentRecord();
- segmentRecord.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID));
- segmentRecord.setTraceId(resultSet.getString(SegmentRecord.TRACE_ID));
- segmentRecord.setServiceId(resultSet.getString(SegmentRecord.SERVICE_ID));
- segmentRecord.setServiceInstanceId(resultSet.getString(SegmentRecord.SERVICE_INSTANCE_ID));
- segmentRecord.setStartTime(resultSet.getLong(SegmentRecord.START_TIME));
- segmentRecord.setLatency(resultSet.getInt(SegmentRecord.LATENCY));
- segmentRecord.setIsError(resultSet.getInt(SegmentRecord.IS_ERROR));
- String dataBinaryBase64 = resultSet.getString(SegmentRecord.DATA_BINARY);
- if (!Strings.isNullOrEmpty(dataBinaryBase64)) {
- segmentRecord.setDataBinary(Base64.getDecoder().decode(dataBinaryBase64));
- }
- return segmentRecord;
- }
- return null;
- },
- SegmentRecord.INDEX_NAME, segmentId
- );
- if (r != null) {
- return r;
- }
- }
- return null;
- }
-
@SneakyThrows
private int querySequenceWithAgg(String aggType, String segmentId, long start, long end) throws IOException {
final var tables = tableHelper.getTablesWithinTTL(ProfileThreadSnapshotRecord.INDEX_NAME);
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCTraceQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCTraceQueryDAO.java
index ad5fc9a811..b01af83985 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCTraceQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCTraceQueryDAO.java
@@ -44,6 +44,8 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInst
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
@@ -51,6 +53,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import static java.util.Objects.nonNull;
import static java.util.function.Predicate.not;
@@ -65,6 +68,16 @@ public class JDBCTraceQueryDAO implements ITraceQueryDAO {
private Set<String> searchableTagKeys;
+ private static String DETAIL_SELECT_QUERY = "select " + SegmentRecord.SEGMENT_ID + ", " +
+ SegmentRecord.TRACE_ID + ", " +
+ SegmentRecord.ENDPOINT_ID + ", " +
+ SegmentRecord.SERVICE_ID + ", " +
+ SegmentRecord.SERVICE_INSTANCE_ID + ", " +
+ SegmentRecord.START_TIME + ", " +
+ SegmentRecord.LATENCY + ", " +
+ SegmentRecord.IS_ERROR + ", " +
+ SegmentRecord.DATA_BINARY;
+
@Override
@SneakyThrows
public TraceBrief queryBasicTraces(Duration duration,
@@ -228,32 +241,11 @@ public class JDBCTraceQueryDAO implements ITraceQueryDAO {
for (String table : tables) {
jdbcClient.executeQuery(
- "select " + SegmentRecord.SEGMENT_ID + ", " +
- SegmentRecord.TRACE_ID + ", " +
- SegmentRecord.SERVICE_ID + ", " +
- SegmentRecord.SERVICE_INSTANCE_ID + ", " +
- SegmentRecord.START_TIME + ", " +
- SegmentRecord.LATENCY + ", " +
- SegmentRecord.IS_ERROR + ", " +
- SegmentRecord.DATA_BINARY + " from " + table + " where " +
+ DETAIL_SELECT_QUERY + " from " + table + " where " +
JDBCTableInstaller.TABLE_COLUMN + " = ? and " +
SegmentRecord.TRACE_ID + " = ?",
resultSet -> {
- while (resultSet.next()) {
- SegmentRecord segmentRecord = new SegmentRecord();
- segmentRecord.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID));
- segmentRecord.setTraceId(resultSet.getString(SegmentRecord.TRACE_ID));
- segmentRecord.setServiceId(resultSet.getString(SegmentRecord.SERVICE_ID));
- segmentRecord.setServiceInstanceId(resultSet.getString(SegmentRecord.SERVICE_INSTANCE_ID));
- segmentRecord.setStartTime(resultSet.getLong(SegmentRecord.START_TIME));
- segmentRecord.setLatency(resultSet.getInt(SegmentRecord.LATENCY));
- segmentRecord.setIsError(resultSet.getInt(SegmentRecord.IS_ERROR));
- String dataBinaryBase64 = resultSet.getString(SegmentRecord.DATA_BINARY);
- if (!Strings.isNullOrEmpty(dataBinaryBase64)) {
- segmentRecord.setDataBinary(Base64.getDecoder().decode(dataBinaryBase64));
- }
- segmentRecords.add(segmentRecord);
- }
+ segmentRecords.addAll(buildRecords(resultSet));
return null;
},
SegmentRecord.INDEX_NAME, traceId
@@ -262,8 +254,82 @@ public class JDBCTraceQueryDAO implements ITraceQueryDAO {
return segmentRecords;
}
+ @SneakyThrows
+ @Override
+ public List<SegmentRecord> queryBySegmentIdList(List<String> segmentIdList) throws IOException {
+ final var tables = tableHelper.getTablesWithinTTL(SegmentRecord.INDEX_NAME);
+ final var segmentRecords = new ArrayList<SegmentRecord>();
+ final ArrayList<String> conditions = new ArrayList<>();
+ conditions.add(SegmentRecord.INDEX_NAME);
+ conditions.addAll(segmentIdList);
+
+ for (String table : tables) {
+ jdbcClient.executeQuery(
+ DETAIL_SELECT_QUERY + " from " + table + " where " +
+ JDBCTableInstaller.TABLE_COLUMN + " = ? and " +
+ SegmentRecord.SEGMENT_ID + " in " +
+ segmentIdList.stream().map(it -> "?").collect(Collectors.joining(",", "(", ")")),
+ resultSet -> {
+ segmentRecords.addAll(buildRecords(resultSet));
+ return null;
+ },
+ conditions.toArray()
+ );
+ }
+ return segmentRecords;
+ }
+
+ @SneakyThrows
+ @Override
+ public List<SegmentRecord> queryByTraceIdWithInstanceId(List<String> traceIdList, List<String> instanceIdList) throws IOException {
+ final var tables = tableHelper.getTablesWithinTTL(SegmentRecord.INDEX_NAME);
+ final var segmentRecords = new ArrayList<SegmentRecord>();
+ final ArrayList<String> conditions = new ArrayList<>();
+ conditions.add(SegmentRecord.INDEX_NAME);
+ conditions.addAll(traceIdList);
+ conditions.addAll(instanceIdList);
+
+ for (String table : tables) {
+ jdbcClient.executeQuery(
+ DETAIL_SELECT_QUERY + " from " + table + " where " +
+ JDBCTableInstaller.TABLE_COLUMN + " = ? and " +
+ SegmentRecord.TRACE_ID + " in " +
+ traceIdList.stream().map(it -> "?").collect(Collectors.joining(",", "(", ") and ")) +
+ SegmentRecord.SERVICE_INSTANCE_ID + " in " +
+ instanceIdList.stream().map(it -> "?").collect(Collectors.joining(",", "(", ")")),
+ resultSet -> {
+ segmentRecords.addAll(buildRecords(resultSet));
+ return null;
+ },
+ conditions.toArray()
+ );
+ }
+ return segmentRecords;
+ }
+
@Override
public List<Span> doFlexibleTraceQuery(String traceId) {
return Collections.emptyList();
}
+
+ private List<SegmentRecord> buildRecords(ResultSet resultSet) throws SQLException {
+ final List<SegmentRecord> records = new ArrayList<>();
+ while (resultSet.next()) {
+ SegmentRecord segmentRecord = new SegmentRecord();
+ segmentRecord.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID));
+ segmentRecord.setTraceId(resultSet.getString(SegmentRecord.TRACE_ID));
+ segmentRecord.setEndpointId(resultSet.getString(SegmentRecord.ENDPOINT_ID));
+ segmentRecord.setServiceId(resultSet.getString(SegmentRecord.SERVICE_ID));
+ segmentRecord.setServiceInstanceId(resultSet.getString(SegmentRecord.SERVICE_INSTANCE_ID));
+ segmentRecord.setStartTime(resultSet.getLong(SegmentRecord.START_TIME));
+ segmentRecord.setLatency(resultSet.getInt(SegmentRecord.LATENCY));
+ segmentRecord.setIsError(resultSet.getInt(SegmentRecord.IS_ERROR));
+ String dataBinaryBase64 = resultSet.getString(SegmentRecord.DATA_BINARY);
+ if (!Strings.isNullOrEmpty(dataBinaryBase64)) {
+ segmentRecord.setDataBinary(Base64.getDecoder().decode(dataBinaryBase64));
+ }
+ records.add(segmentRecord);
+ }
+ return records;
+ }
}
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotDumper.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotDumper.java
index deb2924450..8c490833ba 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotDumper.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotDumper.java
@@ -22,7 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadSnapshot;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadStack;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -50,13 +50,12 @@ public class ProfileSnapshotDumper {
List<ProfiledBasicInfo.SequenceRange> sequenceRanges = basicInfo.buildSequenceRanges();
int rangeCount = sequenceRanges.size();
- String segmentId = basicInfo.getSegmentId();
File snapshotFile = new File(basicInfo.getConfig().getAnalyzeResultDist() + File.separator + "snapshot.data");
// reading data and write to file
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(snapshotFile))) {
for (int i = 0; i < rangeCount; i++) {
- List<ProfileThreadSnapshotRecord> records = querySnapshot(segmentId, snapshotQueryDAO, sequenceRanges.get(i));
+ List<ProfileThreadSnapshotRecord> records = querySnapshot(snapshotQueryDAO, sequenceRanges.get(i));
for (ProfileThreadSnapshotRecord record : records) {
// transform to proto data and save it
ThreadSnapshot.newBuilder()
@@ -80,10 +79,10 @@ public class ProfileSnapshotDumper {
/**
* query snapshots with retry mechanism
*/
- private static List<ProfileThreadSnapshotRecord> querySnapshot(String segmentId, IProfileThreadSnapshotQueryDAO threadSnapshotQueryDAO, ProfiledBasicInfo.SequenceRange sequenceRange) throws IOException {
+ private static List<ProfileThreadSnapshotRecord> querySnapshot(IProfileThreadSnapshotQueryDAO threadSnapshotQueryDAO, ProfiledBasicInfo.SequenceRange sequenceRange) throws IOException {
for (int i = 1; i <= QUERY_PROFILE_SNAPSHOT_RETRY_COUNT; i++) {
try {
- return threadSnapshotQueryDAO.queryRecords(segmentId, sequenceRange.getMin(), sequenceRange.getMax());
+ return threadSnapshotQueryDAO.queryRecords(sequenceRange.getSegmentId(), sequenceRange.getMin(), sequenceRange.getMax());
} catch (IOException e) {
if (i == QUERY_PROFILE_SNAPSHOT_RETRY_COUNT) {
throw e;
@@ -96,13 +95,13 @@ public class ProfileSnapshotDumper {
/**
* load thread snapshots in appointing time range
*/
- public static List<ThreadSnapshot> parseFromFileWithTimeRange(File file, List<ProfileAnalyzeTimeRange> timeRanges) throws IOException {
+ public static List<ThreadSnapshot> parseFromFileWithTimeRange(File file, final List<SegmentProfileAnalyzeQuery> queries) throws IOException {
try (final FileInputStream fileInputStream = new FileInputStream(file)) {
ThreadSnapshot snapshot;
final ArrayList<ThreadSnapshot> data = new ArrayList<>();
while ((snapshot = ThreadSnapshot.parseDelimitedFrom(fileInputStream)) != null) {
ThreadSnapshot finalSnapshot = snapshot;
- if (timeRanges.stream().filter(t -> finalSnapshot.getTime() >= t.getStart() && finalSnapshot.getTime() <= t.getEnd()).findFirst().isPresent()) {
+ if (queries.stream().anyMatch(t -> finalSnapshot.getTime() >= t.getTimeRange().getStart() && finalSnapshot.getTime() <= t.getTimeRange().getEnd())) {
data.add(snapshot);
}
}
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotExporterBootstrap.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotExporterBootstrap.java
index 8afb452d43..9ff9e5ffa0 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotExporterBootstrap.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileSnapshotExporterBootstrap.java
@@ -41,9 +41,9 @@ public class ProfileSnapshotExporterBootstrap {
// prepare basic info
ProfiledBasicInfo profiledBaseInfo = ProfiledBasicInfo.build(exporterConfig, manager);
- log.info("Queried profiled basic info, profiled segment start time:{}, duration:{}, total span count:{}, snapshot count:{}",
- profiledBaseInfo.getSegmentStartTime(), profiledBaseInfo.getDuration(), profiledBaseInfo.getProfiledSegmentSpans().size(),
- profiledBaseInfo.getMaxSequence() - profiledBaseInfo.getMinSequence());
+ log.info("Queried profiled basic info, segment count: {}, total span count:{}",
+ profiledBaseInfo.getSegments().size(),
+ profiledBaseInfo.getProfiledSegmentSpans().size());
// write basic info to file
File basicInfoFile = profiledBaseInfo.writeFile();
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfiledBasicInfo.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfiledBasicInfo.java
index 923640f552..c9a824443d 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfiledBasicInfo.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/main/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfiledBasicInfo.java
@@ -22,9 +22,9 @@ import lombok.Data;
import lombok.Getter;
import org.apache.commons.io.FileUtils;
import org.apache.skywalking.oap.server.core.CoreModule;
+import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.TraceQueryService;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.query.type.Span;
import org.apache.skywalking.oap.server.core.query.type.Trace;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
@@ -49,18 +49,11 @@ public class ProfiledBasicInfo {
private ExporterConfig config;
// profiled segment
- private String segmentId;
- private long segmentStartTime;
- private long segmentEndTime;
- private int duration;
+ private List<ProfiledSegment> segments;
// spans
private List<Span> profiledSegmentSpans;
- // snapshot sequence
- private int minSequence;
- private int maxSequence;
-
/**
* reading data from storage and build data
*/
@@ -73,35 +66,43 @@ public class ProfiledBasicInfo {
IProfileThreadSnapshotQueryDAO threadSnapshotQueryDAO = manager.find(StorageModule.NAME).provider().getService(IProfileThreadSnapshotQueryDAO.class);
// query and found profiled segment
- List<BasicTrace> taskTraces = taskQueryService.getTaskTraces(config.getTaskId());
- BasicTrace profiledTrace = taskTraces.stream().filter(t -> t.getTraceIds().contains(config.getTraceId())).findFirst().orElse(null);
- if (profiledTrace == null) {
+ List<SegmentRecord> taskTraces = taskQueryService.getTaskSegments(config.getTaskId());
+ List<SegmentRecord> segments = taskTraces.stream().filter(t -> Objects.equals(t.getTraceId(), config.getTraceId())).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(segments)) {
throw new IllegalArgumentException("Cannot fount profiled segment in current task: " + config.getTaskId()
+ ", segment id: " + config.getTraceId() + ", current task total profiled trace count is " + taskTraces.size());
}
// setting segment basic info
- String segmentId = profiledTrace.getSegmentId();
- long startTime = Long.parseLong(profiledTrace.getStart());
- long endTime = startTime + profiledTrace.getDuration();
- data.setSegmentId(segmentId);
- data.setSegmentStartTime(startTime);
- data.setSegmentEndTime(endTime);
- data.setDuration(profiledTrace.getDuration());
-
- // query spans
- Trace trace = traceQueryService.queryTrace(config.getTraceId());
- List<Span> profiledSegmentSpans = trace.getSpans().stream().filter(s -> Objects.equals(s.getSegmentId(), segmentId)).collect(Collectors.toList());
- if (CollectionUtils.isEmpty(profiledSegmentSpans)) {
- throw new IllegalArgumentException("Current segment cannot found any span");
+ data.setSegments(new ArrayList<>());
+ data.setProfiledSegmentSpans(new ArrayList<>());
+ for (SegmentRecord segment : segments) {
+ final ProfiledSegment profiledSegment = new ProfiledSegment();
+
+ String segmentId = segment.getSegmentId();
+ long startTime = segment.getStartTime();
+ long endTime = startTime + segment.getLatency();
+ profiledSegment.setSegmentId(segmentId);
+ profiledSegment.setSegmentStartTime(startTime);
+ profiledSegment.setSegmentEndTime(endTime);
+ profiledSegment.setDuration(segment.getLatency());
+
+ // query spans
+ Trace trace = traceQueryService.queryTrace(config.getTraceId());
+ List<Span> profiledSegmentSpans = trace.getSpans().stream().filter(s -> Objects.equals(s.getSegmentId(), segmentId)).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(profiledSegmentSpans)) {
+ throw new IllegalArgumentException("Current segment cannot found any span");
+ }
+ data.getProfiledSegmentSpans().addAll(profiledSegmentSpans);
+
+ // query snapshots sequences
+ int minSequence = threadSnapshotQueryDAO.queryMinSequence(segmentId, startTime, endTime);
+ int maxSequence = threadSnapshotQueryDAO.queryMaxSequence(segmentId, startTime, endTime);
+ profiledSegment.setMinSequence(minSequence);
+ profiledSegment.setMaxSequence(maxSequence);
+
+ data.getSegments().add(profiledSegment);
}
- data.setProfiledSegmentSpans(profiledSegmentSpans);
-
- // query snapshots sequences
- int minSequence = threadSnapshotQueryDAO.queryMinSequence(segmentId, startTime, endTime);
- int maxSequence = threadSnapshotQueryDAO.queryMaxSequence(segmentId, startTime, endTime);
- data.setMinSequence(minSequence);
- data.setMaxSequence(maxSequence);
return data;
}
@@ -130,25 +131,42 @@ public class ProfiledBasicInfo {
*/
public List<SequenceRange> buildSequenceRanges() {
ArrayList<SequenceRange> ranges = new ArrayList<>();
- do {
- int batchMax = Math.min(minSequence + SEQUENCE_RANGE_BATCH_SIZE, maxSequence);
- ranges.add(new SequenceRange(minSequence, batchMax));
- minSequence = batchMax;
+ for (ProfiledSegment segment : this.segments) {
+ int minSequence = segment.minSequence;
+ do {
+ int batchMax = Math.min(minSequence + SEQUENCE_RANGE_BATCH_SIZE, segment.maxSequence);
+ ranges.add(new SequenceRange(segment.getSegmentId(), minSequence, batchMax));
+ minSequence = batchMax;
+ }
+ while (minSequence < segment.maxSequence);
}
- while (minSequence < maxSequence);
return ranges;
}
@Getter
public static class SequenceRange {
+ private String segmentId;
private int min;
private int max;
- public SequenceRange(int min, int max) {
+ public SequenceRange(String segmentId, int min, int max) {
+ this.segmentId = segmentId;
this.min = min;
this.max = max;
}
}
+ @Data
+ public static class ProfiledSegment {
+ private String segmentId;
+ private long segmentStartTime;
+ private long segmentEndTime;
+ private int duration;
+
+ // snapshot sequence
+ private int minSequence;
+ private int maxSequence;
+ }
+
}
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileAnalyzeSnapshotDAO.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileAnalyzeSnapshotDAO.java
index 5c00eacb5d..4822589710 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileAnalyzeSnapshotDAO.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileAnalyzeSnapshotDAO.java
@@ -20,9 +20,7 @@ package org.apache.skywalking.oap.server.tool.profile.exporter;
import com.google.common.primitives.Ints;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadSnapshot;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
import java.io.IOException;
@@ -39,7 +37,7 @@ public class ProfileAnalyzeSnapshotDAO implements IProfileThreadSnapshotQueryDAO
}
@Override
- public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException {
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
return null;
}
@@ -61,11 +59,6 @@ public class ProfileAnalyzeSnapshotDAO implements IProfileThreadSnapshotQueryDAO
.collect(Collectors.toList());
}
- @Override
- public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
- return null;
- }
-
private ProfileThreadSnapshotRecord buildFromSnapshot(ThreadSnapshot snapshot) {
final ProfileThreadSnapshotRecord record = new ProfileThreadSnapshotRecord();
record.setStackBinary(snapshot.getStack().toByteArray());
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileExportedAnalyze.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileExportedAnalyze.java
index 0c3688d8e7..fc5763095a 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileExportedAnalyze.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/ProfileExportedAnalyze.java
@@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadSnapshot;
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
import org.apache.skywalking.oap.server.core.profiling.trace.analyze.ProfileAnalyzer;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzation;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import org.apache.skywalking.oap.server.core.query.type.ProfileStackElement;
@@ -33,7 +34,6 @@ import org.apache.skywalking.oap.server.library.util.CollectionUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
@@ -59,13 +59,13 @@ public class ProfileExportedAnalyze {
final Span span = sameNameSpans.get(0);
// build time ranges
- final List<ProfileAnalyzeTimeRange> timeRanges = buildTimeRanges(basicInfo, span, includeChildren);
- final List<ThreadSnapshot> snapshots = ProfileSnapshotDumper.parseFromFileWithTimeRange(snapshotFile, timeRanges);
+ final List<SegmentProfileAnalyzeQuery> queries = buildAnalyzeQueries(basicInfo, span, includeChildren);
+ final List<ThreadSnapshot> snapshots = ProfileSnapshotDumper.parseFromFileWithTimeRange(snapshotFile, queries);
log.info("Total found snapshot count: {}", snapshots.size());
// analyze and print
final ProfileAnalyzer profileAnalyzer = new Analyzer(snapshots);
- final ProfileAnalyzation analyzation = profileAnalyzer.analyze(null, timeRanges);
+ final ProfileAnalyzation analyzation = profileAnalyzer.analyze(queries);
printAnalyzation(analyzation);
}
@@ -100,12 +100,12 @@ public class ProfileExportedAnalyze {
}
}
- private static List<ProfileAnalyzeTimeRange> buildTimeRanges(ProfiledBasicInfo basicInfo, Span currentSpan, boolean includeChildren) {
+ private static final List<SegmentProfileAnalyzeQuery> buildAnalyzeQueries(ProfiledBasicInfo basicInfo, Span currentSpan, boolean includeChildren) {
if (includeChildren) {
final ProfileAnalyzeTimeRange range = new ProfileAnalyzeTimeRange();
range.setStart(currentSpan.getStartTime());
range.setEnd(currentSpan.getEndTime());
- return Collections.singletonList(range);
+ return List.of(SegmentProfileAnalyzeQuery.builder().timeRange(range).build());
}
// find children spans
@@ -137,7 +137,7 @@ public class ProfileExportedAnalyze {
ranges.add(range);
}
- return ranges;
+ return ranges.stream().map(r -> SegmentProfileAnalyzeQuery.builder().timeRange(r).build()).collect(Collectors.toList());
}
private static class Analyzer extends ProfileAnalyzer {
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileExportSnapshotDAO.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileExportSnapshotDAO.java
index 343f7a7046..880bbca7a1 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileExportSnapshotDAO.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileExportSnapshotDAO.java
@@ -19,15 +19,12 @@
package org.apache.skywalking.oap.server.tool.profile.exporter.test;
import org.apache.skywalking.apm.network.language.profile.v3.ThreadStack;
-import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
-import org.apache.skywalking.oap.server.core.query.type.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
public class ProfileExportSnapshotDAO implements IProfileThreadSnapshotQueryDAO {
@@ -39,13 +36,8 @@ public class ProfileExportSnapshotDAO implements IProfileThreadSnapshotQueryDAO
}
@Override
- public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException {
- final BasicTrace basicTrace = new BasicTrace();
- basicTrace.setSegmentId(exportedData.getSegmentId());
- basicTrace.getTraceIds().add(exportedData.getTraceId());
- basicTrace.setStart(exportedData.getSpans().get(0).getStart() + "");
- basicTrace.setDuration(exportedData.getSpans().get(0).getEnd());
- return Collections.singletonList(basicTrace);
+ public List<String> queryProfiledSegmentIdList(String taskId) throws IOException {
+ return Arrays.asList(exportedData.getSegmentId());
}
@Override
@@ -85,8 +77,4 @@ public class ProfileExportSnapshotDAO implements IProfileThreadSnapshotQueryDAO
return records;
}
- @Override
- public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
- return null;
- }
}
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileSnapshotExporterTest.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileSnapshotExporterTest.java
index ebf39d1b37..221062944e 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileSnapshotExporterTest.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileSnapshotExporterTest.java
@@ -26,6 +26,7 @@ import org.apache.skywalking.oap.server.core.config.ComponentLibraryCatalogServi
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.TraceQueryService;
+import org.apache.skywalking.oap.server.core.query.input.SegmentProfileAnalyzeQuery;
import org.apache.skywalking.oap.server.core.query.type.ProfileAnalyzeTimeRange;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileThreadSnapshotQueryDAO;
@@ -49,7 +50,6 @@ import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
-import java.util.Collections;
import java.util.List;
@ExtendWith(MockitoExtension.class)
@@ -107,7 +107,7 @@ public class ProfileSnapshotExporterTest {
timeRange.setStart(exportedData.getSpans().get(0).getStart());
timeRange.setEnd(exportedData.getSpans().get(0).getEnd());
final List<ThreadSnapshot> threadSnapshots = ProfileSnapshotDumper.parseFromFileWithTimeRange(
- writeFile, Collections.singletonList(timeRange));
+ writeFile, List.of(SegmentProfileAnalyzeQuery.builder().timeRange(timeRange).build()));
Assertions.assertEquals(threadSnapshots.size(), exportedData.getSnapshots().size());
for (int i = 0; i < threadSnapshots.size(); i++) {
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileTraceDAO.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileTraceDAO.java
index 62d19cead9..2c5639c2a5 100644
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileTraceDAO.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-bootstrap/src/test/java/org/apache/skywalking/oap/server/tool/profile/exporter/test/ProfileTraceDAO.java
@@ -79,6 +79,35 @@ public class ProfileTraceDAO implements ITraceQueryDAO {
return segments;
}
+ @Override
+ public List<SegmentRecord> queryBySegmentIdList(List<String> segmentIdList) throws IOException {
+ final ArrayList<SegmentRecord> segments = new ArrayList<>();
+ final SegmentRecord segment = new SegmentRecord();
+ segments.add(segment);
+
+ final SegmentObject.Builder segmentBuilder = SegmentObject.newBuilder();
+ segmentBuilder.setTraceSegmentId(exportData.getSegmentId());
+ for (ExportedData.Span span : exportData.getSpans()) {
+ segmentBuilder.addSpans(SpanObject.newBuilder()
+ .setOperationName(span.getOperation())
+ .setStartTime(span.getStart())
+ .setEndTime(span.getEnd())
+ .setSpanId(span.getId())
+ .setParentSpanId(span.getParentId()));
+ }
+ segment.setDataBinary(segmentBuilder.build().toByteArray());
+ segment.setTraceId(exportData.getTraceId());
+ segment.setServiceId("service");
+ segment.setSegmentId(exportData.getSegmentId());
+ segment.setLatency(exportData.getLimit() * 10);
+ return segments;
+ }
+
+ @Override
+ public List<SegmentRecord> queryByTraceIdWithInstanceId(List<String> traceIdList, List<String> instanceIdList) throws IOException {
+ return null;
+ }
+
@Override
public List<Span> doFlexibleTraceQuery(String traceId) throws IOException {
return null;
diff --git a/test/e2e-v2/cases/profiling/trace/expected/profile-segment-detail.yml b/test/e2e-v2/cases/profiling/trace/expected/profile-segment-detail.yml
deleted file mode 100644
index 7b2236357c..0000000000
--- a/test/e2e-v2/cases/profiling/trace/expected/profile-segment-detail.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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.
-
-spans:
-{{- contains .spans }}
-- spanid: 0
- parentspanid: -1
- servicecode: e2e-service-provider
- serviceinstancename: ""
- starttime: {{ gt .starttime 0 }}
- endtime: {{ gt .endtime 0 }}
- endpointname: POST:/profile/{name}
- type: Entry
- peer: ""
- component: SpringMVC
- iserror: false
- layer: Http
- tags:
- {{- contains .tags }}
- - key: url
- value: {{ notEmpty .value }}
- - key: http.method
- value: POST
- - key: http.params
- value: "e2e=[true]"
- {{- end }}
- logs: []
-{{- end }}
diff --git a/test/e2e-v2/cases/profiling/trace/expected/profile-segment-list.yml b/test/e2e-v2/cases/profiling/trace/expected/profile-segment-list.yml
index a92304683f..5c45b8e704 100644
--- a/test/e2e-v2/cases/profiling/trace/expected/profile-segment-list.yml
+++ b/test/e2e-v2/cases/profiling/trace/expected/profile-segment-list.yml
@@ -14,14 +14,39 @@
# limitations under the License.
{{- contains . }}
-- segmentid: {{ notEmpty .segmentid }}
+- traceid: {{ notEmpty .traceid }}
+ instanceid: {{ notEmpty .instanceid }}
+ instancename: provider1
endpointnames:
- POST:/profile/{name}
duration: {{ gt .duration 0 }}
start: "{{ notEmpty .start }}"
- iserror: false
- traceids:
- {{- contains .traceids }}
- - {{ notEmpty . }}
- {{- end }}
+ spans:
+ {{- contains .spans}}
+ - spanid: {{ ge .spanid 0 }}
+ parentspanid: {{ .parentspanid }}
+ segmentid: {{ notEmpty .segmentid }}
+ refs: []
+ servicecode: e2e-service-provider
+ serviceinstancename: provider1
+ starttime: {{ gt .starttime 0 }}
+ endtime: {{ gt .endtime 0 }}
+ endpointname: POST:/profile/{name}
+ type: Entry
+ peer: ""
+ component: SpringMVC
+ iserror: false
+ layer: Http
+ tags:
+ {{- contains .tags }}
+ - key: url
+ value: {{ notEmpty .value }}
+ - key: http.method
+ value: POST
+ - key: http.params
+ value: "e2e=[true]"
+ {{- end }}
+ logs: []
+ profiled: true
+ {{- end}}
{{- end }}
diff --git a/test/e2e-v2/cases/profiling/trace/profiling-cases.yaml b/test/e2e-v2/cases/profiling/trace/profiling-cases.yaml
index 7a395c2a01..69fc65576b 100644
--- a/test/e2e-v2/cases/profiling/trace/profiling-cases.yaml
+++ b/test/e2e-v2/cases/profiling/trace/profiling-cases.yaml
@@ -55,22 +55,22 @@
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/profile/{name} | yq e '.[0].id' - \
)
expected: expected/profile-segment-list.yml
- # profiled segment detail
- - query: |
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$( \
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/profile/{name} | yq e '.[0].id' - \
- ) | yq e '.[0].segmentid' - \
- )
- expected: expected/profile-segment-detail.yml
# query profiled segment analyze
- query: |
segmentid=$( \
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/profile/{name} | yq e '.[0].id' - \
- ) | yq e '.[0].segmentid' - \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .segmentid' - \
+ );
+ start=$(
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/profile/{name} | yq e '.[0].id' - \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .starttime' - \
+ );
+ end=$(
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/profile/{name} | yq e '.[0].id' - \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .endtime' - \
);
- start=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$segmentid | yq e '.spans[] | select(.spanid == 0).starttime' -);
- end=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$segmentid | yq e '.spans[] | select(.spanid == 0).endtime' -);
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace analysis --segment-id=$segmentid --time-ranges=$(echo $start"-"$end)
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace analysis --segment-ids=$segmentid --time-ranges=$(echo $start"-"$end)
expected: expected/profile-segment-analyze.yml
diff --git a/test/e2e-v2/cases/satellite/native-protocols/e2e.yaml b/test/e2e-v2/cases/satellite/native-protocols/e2e.yaml
index f11afee4e1..9d99188180 100644
--- a/test/e2e-v2/cases/satellite/native-protocols/e2e.yaml
+++ b/test/e2e-v2/cases/satellite/native-protocols/e2e.yaml
@@ -115,24 +115,25 @@ verify:
expected: expected/profile-segment-list.yml
# native profile: query profiled segment
- query: |
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$( \
+ segmentid=$( \
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/info | yq e '.[0].id' - \
- ) | yq e '.[0].segmentid' - \
- )
- expected: expected/profile-segment-detail.yml
- # native profile: query profiled segment
- - query: |
- segmentid=$( \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .segmentid' - \
+ );
+ start=$(
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/info | yq e '.[0].id' - \
- ) | yq e '.[0].segmentid' - \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .starttime' - \
);
- start=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$segmentid|yq e '.spans.[0].starttime' -);
- end=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace profiled-segment --segment-id=$segmentid|yq e '.spans.[0].endtime' -);
- swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace analysis --segment-id=$segmentid --time-ranges=$(echo $start"-"$end)
+ end=$(
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace segment-list --task-id=$( \
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace list --service-name=e2e-service-provider --endpoint-name=POST:/info | yq e '.[0].id' - \
+ ) | yq e '.[0].spans.[] | select(.spanid == 0) | .endtime' - \
+ );
+ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql profiling trace analysis --segment-ids=$segmentid --time-ranges=$(echo $start"-"$end)
expected: expected/profile-segment-analyze.yml
+
# native CDS: using etcdctl to update trace span limit, "/users" should have more than one span because it need DB save
- query: |
etcdctl --endpoints http://${etcd_host}:${etcd_2379}/ put /skywalking/configuration-discovery.default.agentConfigurations 'configurations:
diff --git a/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-detail.yml b/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-detail.yml
deleted file mode 100644
index 43f5b6b539..0000000000
--- a/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-detail.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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.
-
-spans:
-{{- contains .spans }}
-- spanid: 0
- parentspanid: -1
- servicecode: e2e-service-provider
- serviceinstancename: ""
- starttime: {{ gt .starttime 0 }}
- endtime: {{ gt .endtime 0 }}
- endpointname: POST:/info
- type: Entry
- peer: ""
- component: Tomcat
- iserror: false
- layer: Http
- tags:
- {{- contains .tags }}
- - key: url
- value: {{ notEmpty .value }}
- - key: http.method
- value: POST
- {{- end }}
- logs: []
-{{- end }}
diff --git a/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-list.yml b/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-list.yml
index b65f72a46d..9dfacc3d74 100644
--- a/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-list.yml
+++ b/test/e2e-v2/cases/satellite/native-protocols/expected/profile-segment-list.yml
@@ -13,15 +13,38 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-{{- contains . }}
-- segmentid: {{ notEmpty .segmentid }}
+ {{- contains . }}
+- traceid: {{ notEmpty .traceid }}
+ instanceid: {{ notEmpty .instanceid }}
+ instancename: provider1
endpointnames:
- POST:/info
duration: {{ gt .duration 0 }}
start: "{{ notEmpty .start }}"
- iserror: false
- traceids:
- {{- contains .traceids }}
- - {{ notEmpty . }}
+ spans:
+ {{- contains .spans}}
+ - spanid: {{ ge .spanid 0 }}
+ parentspanid: {{ .parentspanid }}
+ segmentid: {{ notEmpty .segmentid }}
+ refs: []
+ servicecode: e2e-service-provider
+ serviceinstancename: provider1
+ starttime: {{ gt .starttime 0 }}
+ endtime: {{ gt .endtime 0 }}
+ endpointname: POST:/info
+ type: Entry
+ peer: ""
+ component: Tomcat
+ iserror: false
+ layer: Http
+ tags:
+ {{- contains .tags }}
+ - key: url
+ value: {{ notEmpty .value }}
+ - key: http.method
+ value: POST
+ {{- end }}
+ logs: []
+ profiled: true
+ {{- end}}
{{- end }}
-{{- end }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/script/env
index 506a9a6d7d..074f84a380 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/script/env
@@ -25,4 +25,4 @@ SW_KUBERNETES_COMMIT_SHA=b670c41d94a82ddefcf466d54bab5c492d88d772
SW_ROVER_COMMIT=fc8d074c6d34ecfee585a7097cbd5aef1ca680a5
SW_BANYANDB_COMMIT=adbd3e87df7f84e5d1904fcf40476d2e81842058
-SW_CTL_COMMIT=9aa1e75af41407a8b85106cc6bc711ab937f6fb5
\ No newline at end of file
+SW_CTL_COMMIT=f3eed66ee2ff330e3218fdc995b6f9952901e37c
\ No newline at end of file