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 e44bc36 provide profiled segment list query (#4322) e44bc36 is described below commit e44bc36281cc0c79f263906464c62698bbf5959d Author: mrproliu <741550...@qq.com> AuthorDate: Thu Feb 6 21:02:08 2020 +0800 provide profiled segment list query (#4322) * provide profiled segment query Co-authored-by: 吴晟 Wu Sheng <wu.sh...@foxmail.com> Co-authored-by: AirTrioa <44222967+airtr...@users.noreply.github.com> --- .../core/profile/ProfileTaskExecutionContext.java | 2 +- ...ecord.java => ProfileThreadSnapshotRecord.java} | 14 +-- .../core/profile/analyze/ProfileAnalyzer.java | 2 +- .../server/core/profile/analyze/ProfileStack.java | 6 +- .../server/core/query/ProfileTaskQueryService.java | 21 +++- .../oap/server/core/storage/StorageModule.java | 3 +- .../profile/IProfileThreadSnapshotQueryDAO.java | 41 ++++++++ .../oap/query/graphql/resolver/ProfileQuery.java | 4 +- .../handler/ProfileTaskServiceHandler.java | 4 +- .../StorageModuleElasticsearchProvider.java | 2 + .../query/ProfileThreadSnapshotQueryEsDAO.java | 108 +++++++++++++++++++++ .../StorageModuleElasticsearch7Provider.java | 7 +- .../storage/plugin/jdbc/h2/H2StorageProvider.java | 2 + .../h2/dao/H2ProfileThreadSnapshotQueryDAO.java | 101 +++++++++++++++++++ .../e2e-profile/e2e-profile-test-runner/pom.xml | 9 +- .../src/docker/profile_official_analysis.oal | 21 ++++ .../src/docker/rc.d/rc0-prepare.sh | 3 +- .../skywalking/e2e/profile/ProfileClient.java | 25 +++++ .../skywalking/e2e/profile/query/Traces.java | 35 +++++++ ...e.ProfileVerificationITCase.profileSegments.yml | 25 +++++ .../main/resources/getProfileTaskSegmentList.gql | 26 +++++ .../skywalking/e2e/ProfileVerificationITCase.java | 42 +++++++- 22 files changed, 472 insertions(+), 31 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java index b17414c..16d684c 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java @@ -150,7 +150,7 @@ public class ProfileTaskExecutionContext { public boolean isStartProfileable() { // check is out of max sampling count check - return totalStartedProfilingCount.incrementAndGet() > task.getMaxSamplingCount(); + return totalStartedProfilingCount.incrementAndGet() <= task.getMaxSamplingCount(); } @Override diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileTaskSegmentSnapshotRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileThreadSnapshotRecord.java similarity index 87% rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileTaskSegmentSnapshotRecord.java rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileThreadSnapshotRecord.java index 36a4cba..981a770 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileTaskSegmentSnapshotRecord.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/ProfileThreadSnapshotRecord.java @@ -42,9 +42,9 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.PR */ @Getter @Setter -@ScopeDeclaration(id = PROFILE_TASK_SEGMENT_SNAPSHOT, name = "ProfileTaskSegmentSnapshot") -@Stream(name = ProfileTaskSegmentSnapshotRecord.INDEX_NAME, scopeId = PROFILE_TASK_SEGMENT_SNAPSHOT, builder = ProfileTaskSegmentSnapshotRecord.Builder.class, processor = RecordStreamProcessor.class) -public class ProfileTaskSegmentSnapshotRecord extends Record { +@ScopeDeclaration(id = PROFILE_TASK_SEGMENT_SNAPSHOT, name = "ProfileThreadSnapshot") +@Stream(name = ProfileThreadSnapshotRecord.INDEX_NAME, scopeId = PROFILE_TASK_SEGMENT_SNAPSHOT, builder = ProfileThreadSnapshotRecord.Builder.class, processor = RecordStreamProcessor.class) +public class ProfileThreadSnapshotRecord extends Record { public static final String INDEX_NAME = "profile_task_segment_snapshot"; public static final String TASK_ID = "task_id"; @@ -64,11 +64,11 @@ public class ProfileTaskSegmentSnapshotRecord extends Record { return getTaskId() + Const.ID_SPLIT + getSegmentId() + Const.ID_SPLIT + getSequence() + Const.ID_SPLIT; } - public static class Builder implements StorageBuilder<ProfileTaskSegmentSnapshotRecord> { + public static class Builder implements StorageBuilder<ProfileThreadSnapshotRecord> { @Override - public ProfileTaskSegmentSnapshotRecord map2Data(Map<String, Object> dbMap) { - final ProfileTaskSegmentSnapshotRecord snapshot = new ProfileTaskSegmentSnapshotRecord(); + public ProfileThreadSnapshotRecord map2Data(Map<String, Object> dbMap) { + final ProfileThreadSnapshotRecord snapshot = new ProfileThreadSnapshotRecord(); snapshot.setTaskId((String)dbMap.get(TASK_ID)); snapshot.setSegmentId((String)dbMap.get(SEGMENT_ID)); snapshot.setDumpTime(((Number)dbMap.get(DUMP_TIME)).longValue()); @@ -83,7 +83,7 @@ public class ProfileTaskSegmentSnapshotRecord extends Record { } @Override - public Map<String, Object> data2Map(ProfileTaskSegmentSnapshotRecord storageData) { + public Map<String, Object> data2Map(ProfileThreadSnapshotRecord storageData) { final HashMap<String, Object> map = new HashMap<>(); map.put(TASK_ID, storageData.getTaskId()); map.put(SEGMENT_ID, storageData.getSegmentId()); diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileAnalyzer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileAnalyzer.java index df59270..72857f8 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileAnalyzer.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileAnalyzer.java @@ -28,7 +28,7 @@ import java.util.stream.Collectors; /** * Analyze {@link ProfileStack} data to {@link ProfileAnalyzation} * - * See: https://github.com/apache/skywalking/blob/docs/en/guides/backend-profile.md#thread-analyst + * See: https://github.com/apache/skywalking/blob/421ba88dbfba48cdc5845547381aa4763775b4b1/docs/en/guides/backend-profile.md#thread-analyst */ public class ProfileAnalyzer { diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileStack.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileStack.java index a3e02b0..c31b609 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileStack.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profile/analyze/ProfileStack.java @@ -22,12 +22,12 @@ import com.google.common.primitives.Ints; import com.google.protobuf.InvalidProtocolBufferException; import lombok.Data; import org.apache.skywalking.apm.network.language.profile.ThreadStack; -import org.apache.skywalking.oap.server.core.profile.ProfileTaskSegmentSnapshotRecord; +import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord; import java.util.List; /** - * Deserialize from {@link ProfileTaskSegmentSnapshotRecord} + * Deserialize from {@link ProfileThreadSnapshotRecord} */ @Data public class ProfileStack implements Comparable<ProfileStack> { @@ -36,7 +36,7 @@ public class ProfileStack implements Comparable<ProfileStack> { private long dumpTime; private List<String> stack; - public static ProfileStack deserialize(ProfileTaskSegmentSnapshotRecord record) { + public static ProfileStack deserialize(ProfileThreadSnapshotRecord record) { ThreadStack threadStack = null; try { threadStack = ThreadStack.parseFrom(record.getStackBinary()); diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProfileTaskQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProfileTaskQueryService.java index df4ebff..656262c 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProfileTaskQueryService.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProfileTaskQueryService.java @@ -21,6 +21,7 @@ import com.google.common.base.Objects; import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.cache.ServiceInstanceInventoryCache; import org.apache.skywalking.oap.server.core.cache.ServiceInventoryCache; +import org.apache.skywalking.oap.server.core.query.entity.BasicTrace; import org.apache.skywalking.oap.server.core.query.entity.ProfileTask; import org.apache.skywalking.oap.server.core.query.entity.ProfileTaskLog; import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory; @@ -28,6 +29,7 @@ import org.apache.skywalking.oap.server.core.register.ServiceInventory; import org.apache.skywalking.oap.server.core.storage.StorageModule; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; 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; @@ -48,6 +50,7 @@ public class ProfileTaskQueryService implements Service { private final ModuleManager moduleManager; private IProfileTaskQueryDAO profileTaskQueryDAO; private IProfileTaskLogQueryDAO profileTaskLogQueryDAO; + private IProfileThreadSnapshotQueryDAO profileThreadSnapshotQueryDAO; private ServiceInventoryCache serviceInventoryCache; private ServiceInstanceInventoryCache serviceInstanceInventoryCache; @@ -69,20 +72,27 @@ public class ProfileTaskQueryService implements Service { return serviceInventoryCache; } - public IProfileTaskLogQueryDAO getProfileTaskLogQueryDAO() { + private IProfileTaskLogQueryDAO getProfileTaskLogQueryDAO() { if (isNull(profileTaskLogQueryDAO)) { profileTaskLogQueryDAO = moduleManager.find(StorageModule.NAME).provider().getService(IProfileTaskLogQueryDAO.class); } return profileTaskLogQueryDAO; } - public ServiceInstanceInventoryCache getServiceInstanceInventoryCache() { + private ServiceInstanceInventoryCache getServiceInstanceInventoryCache() { if (isNull(serviceInstanceInventoryCache)) { serviceInstanceInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(ServiceInstanceInventoryCache.class); } return serviceInstanceInventoryCache; } + private IProfileThreadSnapshotQueryDAO getProfileThreadSnapshotQueryDAO() { + if (isNull(profileThreadSnapshotQueryDAO)) { + profileThreadSnapshotQueryDAO = moduleManager.find(StorageModule.NAME).provider().getService(IProfileThreadSnapshotQueryDAO.class); + } + return profileThreadSnapshotQueryDAO; + } + /** * search profile task list * @param serviceId monitor service @@ -123,4 +133,11 @@ public class ProfileTaskQueryService implements Service { return tasks; } + /** + * search profiled traces + */ + public List<BasicTrace> getTaskTraces(String taskId) throws IOException { + return getProfileThreadSnapshotQueryDAO().queryProfiledSegments(taskId); + } + } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java index 1ae6d54..135976e 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java @@ -21,6 +21,7 @@ package org.apache.skywalking.oap.server.core.storage; import org.apache.skywalking.oap.server.core.storage.cache.*; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.*; import org.apache.skywalking.oap.server.library.module.*; @@ -42,6 +43,6 @@ public class StorageModule extends ModuleDefine { IServiceInventoryCacheDAO.class, IServiceInstanceInventoryCacheDAO.class, IEndpointInventoryCacheDAO.class, INetworkAddressInventoryCacheDAO.class, ITopologyQueryDAO.class, IMetricsQueryDAO.class, ITraceQueryDAO.class, IMetadataQueryDAO.class, IAggregationQueryDAO.class, IAlarmQueryDAO.class, - ITopNRecordsQueryDAO.class, ILogQueryDAO.class, IProfileTaskQueryDAO.class, IProfileTaskLogQueryDAO.class}; + ITopNRecordsQueryDAO.class, ILogQueryDAO.class, IProfileTaskQueryDAO.class, IProfileTaskLogQueryDAO.class, IProfileThreadSnapshotQueryDAO.class}; } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profile/IProfileThreadSnapshotQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profile/IProfileThreadSnapshotQueryDAO.java new file mode 100644 index 0000000..99396c8 --- /dev/null +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profile/IProfileThreadSnapshotQueryDAO.java @@ -0,0 +1,41 @@ +/* + * 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.storage.profile; + +import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord; +import org.apache.skywalking.oap.server.core.query.entity.BasicTrace; +import org.apache.skywalking.oap.server.core.storage.DAO; + +import java.io.IOException; +import java.util.List; + +/** + * {@link ProfileThreadSnapshotRecord} database queries + */ +public interface IProfileThreadSnapshotQueryDAO extends DAO { + + /** + * search all profiled segments, need appoint taskId and snapshot sequence equals 0 + * sort by segment start time + * @param taskId + * @return it represents the segments having profile snapshot data. + */ + List<BasicTrace> queryProfiledSegments(String taskId) throws IOException; + +} 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 5c9abb2..350157a 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 @@ -55,8 +55,8 @@ public class ProfileQuery implements GraphQLQueryResolver { return getProfileTaskQueryService().getTaskList(serviceId, endpointName); } - public List<BasicTrace> getProfileTaskSegmentList(final String taskID) { - return Collections.emptyList(); + public List<BasicTrace> getProfileTaskSegmentList(final String taskID) throws IOException { + return getProfileTaskQueryService().getTaskTraces(taskID); } public ProfileAnalyzation getProfileAnalyze(final String segmentId, final long start, final long end) { diff --git a/oap-server/server-receiver-plugin/skywalking-profile-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/profile/provider/handler/ProfileTaskServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-profile-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/profile/provider/handler/ProfileTaskServiceHandler.java index b181fd3..6c7e5b8 100644 --- a/oap-server/server-receiver-plugin/skywalking-profile-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/profile/provider/handler/ProfileTaskServiceHandler.java +++ b/oap-server/server-receiver-plugin/skywalking-profile-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/profile/provider/handler/ProfileTaskServiceHandler.java @@ -31,7 +31,7 @@ import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcess import org.apache.skywalking.oap.server.core.cache.ProfileTaskCache; import org.apache.skywalking.oap.server.core.command.CommandService; import org.apache.skywalking.oap.server.core.profile.ProfileTaskLogRecord; -import org.apache.skywalking.oap.server.core.profile.ProfileTaskSegmentSnapshotRecord; +import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord; import org.apache.skywalking.oap.server.core.query.entity.ProfileTask; import org.apache.skywalking.oap.server.core.query.entity.ProfileTaskLogOperationType; import org.apache.skywalking.oap.server.library.module.ModuleManager; @@ -110,7 +110,7 @@ public class ProfileTaskServiceHandler extends ProfileTaskGrpc.ProfileTaskImplBa } // build database data - final ProfileTaskSegmentSnapshotRecord record = new ProfileTaskSegmentSnapshotRecord(); + final ProfileThreadSnapshotRecord record = new ProfileThreadSnapshotRecord(); record.setTaskId(snapshot.getTaskId()); record.setSegmentId(segmentIdBuilder.toString()); record.setDumpTime(snapshot.getTime()); diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java index e451ac6..c01679f 100644 --- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java +++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java @@ -38,6 +38,7 @@ import org.apache.skywalking.oap.server.core.storage.cache.IServiceInstanceInven import org.apache.skywalking.oap.server.core.storage.cache.IServiceInventoryCacheDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO; @@ -121,6 +122,7 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider { this.registerServiceImplementation(IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(elasticSearchClient, config.getProfileTaskQueryMaxSize())); this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(elasticSearchClient, config.getProfileTaskQueryMaxSize())); + this.registerServiceImplementation(IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEsDAO(elasticSearchClient, config.getProfileTaskQueryMaxSize())); } @Override 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 new file mode 100644 index 0000000..44d7d88 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ProfileThreadSnapshotQueryEsDAO.java @@ -0,0 +1,108 @@ +/* + * 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.storage.plugin.elasticsearch.query; + +import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord; +import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord; +import org.apache.skywalking.oap.server.core.query.entity.BasicTrace; +import org.apache.skywalking.oap.server.core.storage.profile.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.EsDAO; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.sort.SortOrder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class ProfileThreadSnapshotQueryEsDAO extends EsDAO implements IProfileThreadSnapshotQueryDAO { + + private final int querySegemntMaxSize; + + public ProfileThreadSnapshotQueryEsDAO(ElasticSearchClient client, int profileTaskQueryMaxSize) { + super(client); + this.querySegemntMaxSize = profileTaskQueryMaxSize; + } + + @Override + public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException { + // search segment id list + SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource(); + + BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); + sourceBuilder.query(boolQueryBuilder); + + boolQueryBuilder.must().add(QueryBuilders.termQuery(ProfileThreadSnapshotRecord.TASK_ID, taskId)); + boolQueryBuilder.must().add(QueryBuilders.termQuery(ProfileThreadSnapshotRecord.SEQUENCE, 0)); + + sourceBuilder.size(querySegemntMaxSize); + sourceBuilder.sort(ProfileThreadSnapshotRecord.DUMP_TIME, SortOrder.DESC); + + SearchResponse response = getClient().search(ProfileThreadSnapshotRecord.INDEX_NAME, sourceBuilder); + + final LinkedList<String> segments = new LinkedList<>(); + for (SearchHit searchHit : response.getHits().getHits()) { + segments.add((String) searchHit.getSourceAsMap().get(ProfileThreadSnapshotRecord.SEGMENT_ID)); + } + + if (CollectionUtils.isEmpty(segments)) { + return Collections.emptyList(); + } + + // search traces + sourceBuilder = SearchSourceBuilder.searchSource(); + + boolQueryBuilder = QueryBuilders.boolQuery(); + sourceBuilder.query(boolQueryBuilder); + List<QueryBuilder> shouldQueryList = boolQueryBuilder.should(); + + for (String segmentId : segments) { + shouldQueryList.add(QueryBuilders.termQuery(SegmentRecord.SEGMENT_ID, segmentId)); + } + sourceBuilder.size(segments.size()); + sourceBuilder.sort(SegmentRecord.START_TIME, SortOrder.DESC); + + response = getClient().search(SegmentRecord.INDEX_NAME, sourceBuilder); + + List<BasicTrace> result = new ArrayList<>(); + for (SearchHit searchHit : response.getHits().getHits()) { + BasicTrace basicTrace = new BasicTrace(); + + basicTrace.setSegmentId((String)searchHit.getSourceAsMap().get(SegmentRecord.SEGMENT_ID)); + basicTrace.setStart(String.valueOf(searchHit.getSourceAsMap().get(SegmentRecord.START_TIME))); + basicTrace.getEndpointNames().add((String)searchHit.getSourceAsMap().get(SegmentRecord.ENDPOINT_NAME)); + basicTrace.setDuration(((Number)searchHit.getSourceAsMap().get(SegmentRecord.LATENCY)).intValue()); + basicTrace.setError(BooleanUtils.valueToBoolean(((Number)searchHit.getSourceAsMap().get(SegmentRecord.IS_ERROR)).intValue())); + basicTrace.getTraceIds().add((String)searchHit.getSourceAsMap().get(SegmentRecord.TRACE_ID)); + + result.add(basicTrace); + } + + return result; + } +} diff --git a/oap-server/server-storage-plugin/storage-elasticsearch7-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch7/StorageModuleElasticsearch7Provider.java b/oap-server/server-storage-plugin/storage-elasticsearch7-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch7/StorageModuleElasticsearch7Provider.java index 5fe5775..14bd616 100644 --- a/oap-server/server-storage-plugin/storage-elasticsearch7-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch7/StorageModuleElasticsearch7Provider.java +++ b/oap-server/server-storage-plugin/storage-elasticsearch7-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch7/StorageModuleElasticsearch7Provider.java @@ -33,6 +33,7 @@ import org.apache.skywalking.oap.server.core.storage.cache.IServiceInstanceInven import org.apache.skywalking.oap.server.core.storage.cache.IServiceInventoryCacheDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO; @@ -48,10 +49,7 @@ import org.apache.skywalking.oap.server.library.module.ModuleStartException; import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.BatchProcessEsDAO; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.HistoryDeleteEsDAO; -import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.ProfileTaskLogEsDAO; -import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.ProfileTaskQueryEsDAO; -import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopNRecordsQueryEsDAO; -import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopologyQueryEsDAO; +import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.*; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.ttl.ElasticsearchStorageTTL; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.cache.EndpointInventoryCacheEs7DAO; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.cache.NetworkAddressInventoryCacheEs7DAO; @@ -127,6 +125,7 @@ public class StorageModuleElasticsearch7Provider extends ModuleProvider { this.registerServiceImplementation(IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(elasticSearch7Client, config.getProfileTaskQueryMaxSize())); this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(elasticSearch7Client, config.getProfileTaskQueryMaxSize())); + this.registerServiceImplementation(IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEsDAO(elasticSearch7Client, config.getProfileTaskQueryMaxSize())); } @Override diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java index 0562648..11783a4 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java @@ -24,6 +24,7 @@ import org.apache.skywalking.oap.server.core.storage.*; import org.apache.skywalking.oap.server.core.storage.cache.*; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO; import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.*; import org.apache.skywalking.oap.server.core.storage.ttl.GeneralStorageTTL; import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; @@ -94,6 +95,7 @@ public class H2StorageProvider extends ModuleProvider { this.registerServiceImplementation(IProfileTaskQueryDAO.class, new H2ProfileTaskQueryDAO(h2Client)); this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new H2ProfileTaskLogQueryDAO(h2Client)); + this.registerServiceImplementation(IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(h2Client)); } @Override public void start() throws ServiceNotProvidedException, ModuleStartException { diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ProfileThreadSnapshotQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ProfileThreadSnapshotQueryDAO.java new file mode 100644 index 0000000..439a2e2 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ProfileThreadSnapshotQueryDAO.java @@ -0,0 +1,101 @@ +/* + * 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.storage.plugin.jdbc.h2.dao; + +import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord; +import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord; +import org.apache.skywalking.oap.server.core.query.entity.BasicTrace; +import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.library.util.BooleanUtils; +import org.apache.skywalking.oap.server.library.util.CollectionUtils; +import org.elasticsearch.search.sort.SortOrder; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class H2ProfileThreadSnapshotQueryDAO implements IProfileThreadSnapshotQueryDAO { + private JDBCHikariCPClient h2Client; + + public H2ProfileThreadSnapshotQueryDAO(JDBCHikariCPClient h2Client) { + this.h2Client = h2Client; + } + + @Override + public List<BasicTrace> queryProfiledSegments(String taskId) throws IOException { + // search segment id list + StringBuilder sql = new StringBuilder(); + sql.append("select ").append(ProfileThreadSnapshotRecord.SEGMENT_ID).append(" from ").append(ProfileThreadSnapshotRecord.INDEX_NAME); + + sql.append(" where ").append(ProfileThreadSnapshotRecord.TASK_ID).append(" = ? and ").append(ProfileThreadSnapshotRecord.SEQUENCE).append(" = 0"); + + final LinkedList<String> segments = new LinkedList<>(); + try (Connection connection = h2Client.getConnection()) { + try (ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), taskId)) { + while (resultSet.next()) { + segments.add(resultSet.getString(ProfileThreadSnapshotRecord.SEGMENT_ID)); + } + } + } catch (SQLException e) { + throw new IOException(e); + } + + if (CollectionUtils.isEmpty(segments)) { + return Collections.emptyList(); + } + + // search traces + sql = new StringBuilder(); + sql.append("select * from ").append(SegmentRecord.INDEX_NAME).append(" where "); + sql.append(" 1=1 "); + for (int i = 0; i < segments.size(); i++) { + sql.append(" and ").append(SegmentRecord.SEGMENT_ID).append(" = ? "); + } + sql.append(" order by ").append(SegmentRecord.START_TIME).append(" ").append(SortOrder.DESC); + + ArrayList<BasicTrace> result = new ArrayList<>(segments.size()); + try (Connection connection = h2Client.getConnection()) { + + try (ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), segments.toArray(new String[segments.size()]))) { + while (resultSet.next()) { + BasicTrace basicTrace = new BasicTrace(); + + basicTrace.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID)); + basicTrace.setStart(resultSet.getString(SegmentRecord.START_TIME)); + basicTrace.getEndpointNames().add(resultSet.getString(SegmentRecord.ENDPOINT_NAME)); + 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); + + result.add(basicTrace); + } + } + } catch (SQLException e) { + throw new IOException(e); + } + return result; + } +} diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/pom.xml b/test/e2e/e2e-profile/e2e-profile-test-runner/pom.xml index 203813a..e3cfb07 100644 --- a/test/e2e/e2e-profile/e2e-profile-test-runner/pom.xml +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/pom.xml @@ -115,7 +115,8 @@ <volume>${project.build.directory}:/home</volume> <volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume> <volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume> - <volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume> + <volume>${project.basedir}/src/docker/adapt_storage.awk:/adapt_storage.awk</volume> + <volume>${project.basedir}/src/docker/profile_official_analysis.oal:/profile_official_analysis.oal</volume> </bind> </volumes> <wait> @@ -168,7 +169,8 @@ <volume>${sw.home}:/sw</volume> <volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume> <volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume> - <volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume> + <volume>${project.basedir}/src/docker/adapt_storage.awk:/adapt_storage.awk</volume> + <volume>${project.basedir}/src/docker/profile_official_analysis.oal:/profile_official_analysis.oal</volume> </bind> </volumes> <wait> @@ -251,7 +253,8 @@ <volume>${sw.home}:/sw</volume> <volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume> <volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume> - <volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume> + <volume>${project.basedir}/src/docker/adapt_storage.awk:/adapt_storage.awk</volume> + <volume>${project.basedir}/src/docker/profile_official_analysis.oal:/profile_official_analysis.oal</volume> </bind> </volumes> <wait> diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/profile_official_analysis.oal b/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/profile_official_analysis.oal new file mode 100755 index 0000000..cc6894b --- /dev/null +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/profile_official_analysis.oal @@ -0,0 +1,21 @@ +/* + * 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. + * + */ + + +// Disable all oal in profile e2e testing. + diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/rc.d/rc0-prepare.sh b/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/rc.d/rc0-prepare.sh index 4693ad0..9b18d3e 100755 --- a/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/rc.d/rc0-prepare.sh +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/docker/rc.d/rc0-prepare.sh @@ -33,6 +33,7 @@ fi # substitute application.yml to adapt the storage cd ${SW_HOME}/config \ && gawk -f /adapt_storage.awk application.yml > clusterized_app.yml \ - && mv clusterized_app.yml application.yml + && mv clusterized_app.yml application.yml \ + && cp /profile_official_analysis.oal official_analysis.oal \ cd ${original_wd} diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/ProfileClient.java b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/ProfileClient.java index d01c0a3..16bfc9b 100644 --- a/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/ProfileClient.java +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/ProfileClient.java @@ -26,6 +26,8 @@ import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResult; import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResultWrapper; import org.apache.skywalking.e2e.profile.query.ProfileTaskQuery; import org.apache.skywalking.e2e.profile.query.ProfileTasks; +import org.apache.skywalking.e2e.profile.query.Traces; +import org.apache.skywalking.e2e.trace.Trace; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -36,6 +38,8 @@ import java.io.IOException; import java.net.URI; import java.net.URL; import java.nio.charset.Charset; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -95,5 +99,26 @@ public class ProfileClient extends SimpleQueryClient { return responseEntity.getBody().getData(); } + public List<Trace> getProfiledTraces(final String taskId) throws Exception { + final URL queryFileUrl = Resources.getResource("getProfileTaskSegmentList.gql"); + final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8")) + .stream() + .filter(it -> !it.startsWith("#")) + .collect(Collectors.joining()) + .replace("{taskID}", taskId); + final ResponseEntity<GQLResponse<Traces>> responseEntity = restTemplate.exchange( + new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)), + new ParameterizedTypeReference<GQLResponse<Traces>>() { + } + ); + + if (responseEntity.getStatusCode() != HttpStatus.OK) { + throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode()); + } + + return Objects.requireNonNull(responseEntity.getBody()).getData().getTraces(); + } + + } diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/query/Traces.java b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/query/Traces.java new file mode 100644 index 0000000..118131a --- /dev/null +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/java/org/apache/skywalking/e2e/profile/query/Traces.java @@ -0,0 +1,35 @@ +/* + * 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.e2e.profile.query; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.apache.skywalking.e2e.trace.Trace; + +import java.util.List; + +@Setter +@Getter +@ToString +public class Traces { + + private List<Trace> traces; + +} diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileSegments.yml b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileSegments.yml new file mode 100644 index 0000000..4542e5d --- /dev/null +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileSegments.yml @@ -0,0 +1,25 @@ +# 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. + +traces: + - key: not null + endpointNames: + - /e2e/users + duration: ge 0 + start: gt 0 + isError: false + traceIds: + - not null diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/getProfileTaskSegmentList.gql b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/getProfileTaskSegmentList.gql new file mode 100644 index 0000000..560d844 --- /dev/null +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/main/resources/getProfileTaskSegmentList.gql @@ -0,0 +1,26 @@ +# 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. + +{ + "query":"query getProfileTaskSegmentList($taskID: String!) { + traces: getProfileTaskSegmentList(taskID: $taskID) { + key: segmentId endpointNames duration start isError traceIds + } + }", + "variables": { + "taskID": "{taskID}" + } +} \ No newline at end of file diff --git a/test/e2e/e2e-profile/e2e-profile-test-runner/src/test/java/org/apache/skywalking/e2e/ProfileVerificationITCase.java b/test/e2e/e2e-profile/e2e-profile-test-runner/src/test/java/org/apache/skywalking/e2e/ProfileVerificationITCase.java index 2289ae8..25b05df 100644 --- a/test/e2e/e2e-profile/e2e-profile-test-runner/src/test/java/org/apache/skywalking/e2e/ProfileVerificationITCase.java +++ b/test/e2e/e2e-profile/e2e-profile-test-runner/src/test/java/org/apache/skywalking/e2e/ProfileVerificationITCase.java @@ -35,6 +35,7 @@ import org.apache.skywalking.e2e.service.instance.Instances; import org.apache.skywalking.e2e.service.instance.InstancesMatcher; import org.apache.skywalking.e2e.service.instance.InstancesQuery; import org.apache.skywalking.e2e.trace.Trace; +import org.apache.skywalking.e2e.trace.TracesMatcher; import org.apache.skywalking.e2e.trace.TracesQuery; import org.junit.Before; import org.junit.Test; @@ -75,11 +76,9 @@ public class ProfileVerificationITCase { @Before public void setUp() { final String swWebappHost = System.getProperty("sw.webapp.host", "127.0.0.1"); - // final String swWebappPort = System.getProperty("sw.webapp.port", "32783"); final String swWebappPort = System.getProperty("sw.webapp.port", "12800"); final String instrumentedServiceHost = System.getProperty("service.host", "127.0.0.1"); - final String instrumentedServicePort = System.getProperty("service.port", "32782"); - // final String instrumentedServicePort = System.getProperty("service.port", "9090"); + final String instrumentedServicePort = System.getProperty("service.port", "9090"); profileClient = new ProfileClient(swWebappHost, swWebappPort); instrumentedServiceUrl = "http://" + instrumentedServiceHost + ":" + instrumentedServicePort; } @@ -109,7 +108,16 @@ public class ProfileVerificationITCase { } // verify basic info - verifyServices(minutesAgo); + int verifyServiceCount = 3; + for (int i = 1; i <= verifyServiceCount; i++) { + try { + verifyServices(minutesAgo); + } catch (Exception e) { + if (i == verifyServiceCount) { + throw new IllegalStateException("match services fail!", e); + } + } + } // create profile task verifyCreateProfileTask(minutesAgo); @@ -159,6 +167,32 @@ public class ProfileVerificationITCase { // verify task execution finish verifyProfileTask(creationRequest.getServiceId(), "expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileTasks.finished.yml"); + + // verify profiled segment + verifyProfiledSegment(creationResult.getId()); + } + + private void verifyProfiledSegment(String taskId) throws InterruptedException { + // found segment id + String foundedSegmentId = null; + for (int i = 0; i < 10; i++) { + try { + List<Trace> traces = profileClient.getProfiledTraces(taskId); + LOGGER.info("get profiled segemnt list: {}", traces); + + InputStream expectedInputStream = new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileSegments.yml").getInputStream(); + final TracesMatcher tracesMatcher = new Yaml().loadAs(expectedInputStream, TracesMatcher.class); + tracesMatcher.verifyLoosely(traces); + foundedSegmentId = traces.get(0).getKey(); + break; + + } catch (Exception e) { + if (i == 10 - 1) { + throw new IllegalStateException("match profiled segment list fail!", e); + } + TimeUnit.SECONDS.sleep(retryInterval); + } + } } private void verifyProfileTask(int serviceId, String verifyResources) throws InterruptedException {