未验证 提交 2ea341b8 编写于 作者: 静夜思朝颜's avatar 静夜思朝颜 提交者: GitHub

Add missed profiled segment query (#4413)

* add profiled segment query

* fix query field error
上级 d63f2c94
......@@ -20,18 +20,31 @@ package org.apache.skywalking.oap.server.core.query;
import com.google.common.base.Objects;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.skywalking.apm.network.language.agent.v2.SegmentObject;
import org.apache.skywalking.oap.server.core.Const;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.cache.EndpointInventoryCache;
import org.apache.skywalking.oap.server.core.cache.NetworkAddressInventoryCache;
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.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.profile.analyze.ProfileAnalyzer;
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
import org.apache.skywalking.oap.server.core.query.entity.KeyValue;
import org.apache.skywalking.oap.server.core.query.entity.LogEntity;
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
import org.apache.skywalking.oap.server.core.query.entity.ProfileTaskLog;
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSpan;
import org.apache.skywalking.oap.server.core.register.EndpointInventory;
import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory;
import org.apache.skywalking.oap.server.core.register.ServiceInventory;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
......@@ -43,6 +56,7 @@ import org.apache.skywalking.oap.server.library.module.Service;
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
/**
* handle profile task queries
......@@ -54,6 +68,9 @@ public class ProfileTaskQueryService implements Service {
private IProfileThreadSnapshotQueryDAO profileThreadSnapshotQueryDAO;
private ServiceInventoryCache serviceInventoryCache;
private ServiceInstanceInventoryCache serviceInstanceInventoryCache;
private NetworkAddressInventoryCache networkAddressInventoryCache;
private IComponentLibraryCatalogService componentLibraryCatalogService;
private EndpointInventoryCache endpointInventoryCache;
private final ProfileAnalyzer profileAnalyzer;
......@@ -107,6 +124,33 @@ public class ProfileTaskQueryService implements Service {
return profileThreadSnapshotQueryDAO;
}
private NetworkAddressInventoryCache getNetworkAddressInventoryCache() {
if (networkAddressInventoryCache == null) {
this.networkAddressInventoryCache = moduleManager.find(CoreModule.NAME)
.provider()
.getService(NetworkAddressInventoryCache.class);
}
return networkAddressInventoryCache;
}
private IComponentLibraryCatalogService getComponentLibraryCatalogService() {
if (componentLibraryCatalogService == null) {
this.componentLibraryCatalogService = moduleManager.find(CoreModule.NAME)
.provider()
.getService(IComponentLibraryCatalogService.class);
}
return componentLibraryCatalogService;
}
private EndpointInventoryCache getEndpointInventoryCache() {
if (endpointInventoryCache == null) {
this.endpointInventoryCache = moduleManager.find(CoreModule.NAME)
.provider()
.getService(EndpointInventoryCache.class);
}
return endpointInventoryCache;
}
/**
* search profile task list
*
......@@ -158,4 +202,87 @@ public class ProfileTaskQueryService implements Service {
return profileAnalyzer.analyze(segmentId, start, end);
}
public ProfiledSegment getProfiledSegment(String segmentId) throws IOException {
SegmentRecord segmentRecord = getProfileThreadSnapshotQueryDAO().getProfiledSegment(segmentId);
if (segmentRecord == null) {
return null;
}
ProfiledSegment profiledSegment = new ProfiledSegment();
SegmentObject segmentObject = SegmentObject.parseFrom(segmentRecord.getDataBinary());
profiledSegment.getSpans().addAll(buildProfiledSpanList(segmentObject));
return profiledSegment;
}
private List<ProfiledSpan> buildProfiledSpanList(SegmentObject segmentObject) {
List<ProfiledSpan> spans = new ArrayList<>();
segmentObject.getSpansList().forEach(spanObject -> {
ProfiledSpan span = new ProfiledSpan();
span.setSpanId(spanObject.getSpanId());
span.setParentSpanId(spanObject.getParentSpanId());
span.setStartTime(spanObject.getStartTime());
span.setEndTime(spanObject.getEndTime());
span.setError(spanObject.getIsError());
span.setLayer(spanObject.getSpanLayer().name());
span.setType(spanObject.getSpanType().name());
if (spanObject.getPeerId() == 0) {
span.setPeer(spanObject.getPeer());
} else {
span.setPeer(getNetworkAddressInventoryCache().get(spanObject.getPeerId()).getName());
}
String endpointName = spanObject.getOperationName();
if (spanObject.getOperationNameId() != 0) {
EndpointInventory endpointInventory = getEndpointInventoryCache().get(spanObject.getOperationNameId());
if (nonNull(endpointInventory)) {
endpointName = endpointInventory.getName();
} else {
endpointName = Const.EMPTY_STRING;
}
}
span.setEndpointName(endpointName);
final ServiceInventory serviceInventory = getServiceInventoryCache().get(segmentObject.getServiceId());
if (serviceInventory != null) {
span.setServiceCode(serviceInventory.getName());
} else {
span.setServiceCode("unknown");
}
if (spanObject.getComponentId() == 0) {
span.setComponent(spanObject.getComponent());
} else {
span.setComponent(getComponentLibraryCatalogService().getComponentName(spanObject.getComponentId()));
}
spanObject.getTagsList().forEach(tag -> {
KeyValue keyValue = new KeyValue();
keyValue.setKey(tag.getKey());
keyValue.setValue(tag.getValue());
span.getTags().add(keyValue);
});
spanObject.getLogsList().forEach(log -> {
LogEntity logEntity = new LogEntity();
logEntity.setTime(log.getTime());
log.getDataList().forEach(data -> {
KeyValue keyValue = new KeyValue();
keyValue.setKey(data.getKey());
keyValue.setValue(data.getValue());
logEntity.getData().add(keyValue);
});
span.getLogs().add(logEntity);
});
spans.add(span);
});
return spans;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.oap.server.core.query.entity;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
public class ProfiledSegment {
private final List<ProfiledSpan> spans;
public ProfiledSegment() {
this.spans = new ArrayList<>();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.oap.server.core.query.entity;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
public class ProfiledSpan {
private int spanId;
private int parentSpanId;
private String serviceCode;
private long startTime;
private long endTime;
private String endpointName;
private String type;
private String peer;
private String component;
private boolean isError;
private String layer;
private final List<KeyValue> tags;
private final List<LogEntity> logs;
public ProfiledSpan() {
this.tags = new ArrayList<>();
this.logs = new ArrayList<>();
}
}
......@@ -20,6 +20,8 @@ package org.apache.skywalking.oap.server.core.storage.profile;
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.profile.ProfileThreadSnapshotRecord;
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
import org.apache.skywalking.oap.server.core.storage.DAO;
......@@ -56,4 +58,8 @@ 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;
}
......@@ -23,6 +23,7 @@ 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.profile.ProfileThreadSnapshotRecord;
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
import org.apache.skywalking.oap.server.core.query.entity.ProfileStackTree;
......@@ -86,6 +87,11 @@ public class ProfileStackAnalyze {
.collect(Collectors.toList());
}
@Override
public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
return null;
}
}
}
......@@ -24,6 +24,7 @@ import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.entity.BasicTrace;
import org.apache.skywalking.oap.server.core.query.entity.ProfileAnalyzation;
import org.apache.skywalking.oap.server.core.query.entity.ProfileTask;
import org.apache.skywalking.oap.server.core.query.entity.ProfiledSegment;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import java.io.IOException;
......@@ -58,6 +59,10 @@ public class ProfileQuery implements GraphQLQueryResolver {
return getProfileTaskQueryService().getTaskTraces(taskID);
}
public ProfiledSegment getProfiledSegment(final String segmentId) throws IOException {
return getProfileTaskQueryService().getProfiledSegment(segmentId);
}
public ProfileAnalyzation getProfileAnalyze(final String segmentId, final long start,
final long end) throws IOException {
return getProfileTaskQueryService().getProfileAnalyze(segmentId, start, end);
......
Subproject commit 1018b795021e0d96e6c131c8695fb9ddc9d66916
Subproject commit 6b26ddad2099b8782b2e298fd0df02dfd1d6609f
......@@ -18,6 +18,7 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
import com.google.common.base.Strings;
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;
......@@ -39,6 +40,7 @@ import org.elasticsearch.search.sort.SortOrder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
......@@ -146,6 +148,35 @@ public class ProfileThreadSnapshotQueryEsDAO extends EsDAO implements IProfileTh
return result;
}
@Override
public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
sourceBuilder.query(QueryBuilders.termQuery(SegmentRecord.SEGMENT_ID, segmentId));
sourceBuilder.size(1);
SearchResponse response = getClient().search(SegmentRecord.INDEX_NAME, sourceBuilder);
if (response.getHits().getHits().length == 0) {
return null;
}
SearchHit searchHit = response.getHits().getHits()[0];
SegmentRecord segmentRecord = new SegmentRecord();
segmentRecord.setSegmentId((String) searchHit.getSourceAsMap().get(SegmentRecord.SEGMENT_ID));
segmentRecord.setTraceId((String) searchHit.getSourceAsMap().get(SegmentRecord.TRACE_ID));
segmentRecord.setServiceId(((Number) searchHit.getSourceAsMap().get(SegmentRecord.SERVICE_ID)).intValue());
segmentRecord.setEndpointName((String) searchHit.getSourceAsMap().get(SegmentRecord.ENDPOINT_NAME));
segmentRecord.setStartTime(((Number) searchHit.getSourceAsMap().get(SegmentRecord.START_TIME)).longValue());
segmentRecord.setEndTime(((Number) searchHit.getSourceAsMap().get(SegmentRecord.END_TIME)).longValue());
segmentRecord.setLatency(((Number) searchHit.getSourceAsMap().get(SegmentRecord.LATENCY)).intValue());
segmentRecord.setIsError(((Number) searchHit.getSourceAsMap().get(SegmentRecord.IS_ERROR)).intValue());
String dataBinaryBase64 = (String) searchHit.getSourceAsMap().get(SegmentRecord.DATA_BINARY);
if (!Strings.isNullOrEmpty(dataBinaryBase64)) {
segmentRecord.setDataBinary(Base64.getDecoder().decode(dataBinaryBase64));
}
segmentRecord.setVersion(((Number) searchHit.getSourceAsMap().get(SegmentRecord.VERSION)).intValue());
return segmentRecord;
}
protected int querySequenceWithAgg(AbstractAggregationBuilder aggregationBuilder, String segmentId, long start, long end) throws IOException {
SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
......
......@@ -33,6 +33,7 @@ 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.util.BooleanUtils;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxClient;
import org.elasticsearch.common.Strings;
import org.influxdb.dto.QueryResult;
import org.influxdb.querybuilder.WhereQueryImpl;
......@@ -148,6 +149,47 @@ public class ProfileThreadSnapshotQuery implements IProfileThreadSnapshotQueryDA
return result;
}
@Override
public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
WhereQueryImpl query = select().column(SegmentRecord.SEGMENT_ID)
.column(SegmentRecord.TRACE_ID)
.column(SegmentRecord.SERVICE_ID)
.column(SegmentRecord.ENDPOINT_NAME)
.column(SegmentRecord.START_TIME)
.column(SegmentRecord.END_TIME)
.column(SegmentRecord.LATENCY)
.column(SegmentRecord.IS_ERROR)
.column(SegmentRecord.DATA_BINARY)
.column(SegmentRecord.VERSION)
.from(client.getDatabase(), SegmentRecord.INDEX_NAME)
.where()
.and(eq(SegmentRecord.SEGMENT_ID, segmentId));
List<QueryResult.Series> series = client.queryForSeries(query);
if (series == null || series.isEmpty()) {
return null;
}
List<Object> values = series.get(0).getValues().get(0);
SegmentRecord segmentRecord = new SegmentRecord();
segmentRecord.setSegmentId((String) values.get(1));
segmentRecord.setTraceId((String) values.get(2));
segmentRecord.setServiceId((int) values.get(3));
segmentRecord.setEndpointName((String) values.get(4));
segmentRecord.setStartTime((long) values.get(5));
segmentRecord.setEndTime((long) values.get(6));
segmentRecord.setLatency((int) values.get(7));
segmentRecord.setIsError((int) values.get(8));
segmentRecord.setVersion((int) values.get(10));
String base64 = (String) values.get(9);
if (!Strings.isNullOrEmpty(base64)) {
segmentRecord.setDataBinary(Base64.getDecoder().decode(base64));
}
return segmentRecord;
}
private int querySequenceWithAgg(String function, String segmentId, long start, long end) throws IOException {
WhereQueryImpl query = select()
.function(function, ProfileThreadSnapshotRecord.SEQUENCE)
......
......@@ -27,6 +27,8 @@ import java.util.Base64;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import com.google.common.base.Strings;
import org.apache.skywalking.apm.util.StringUtil;
import org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
import org.apache.skywalking.oap.server.core.profile.ProfileThreadSnapshotRecord;
......@@ -155,6 +157,36 @@ public class H2ProfileThreadSnapshotQueryDAO implements IProfileThreadSnapshotQu
return result;
}
@Override
public SegmentRecord getProfiledSegment(String segmentId) throws IOException {
try (Connection connection = h2Client.getConnection()) {
try (ResultSet resultSet = h2Client.executeQuery(connection, "select * from " + SegmentRecord.INDEX_NAME + " where " + SegmentRecord.SEGMENT_ID + " = ?", segmentId)) {
if (resultSet.next()) {
SegmentRecord segmentRecord = new SegmentRecord();
segmentRecord.setSegmentId(resultSet.getString(SegmentRecord.SEGMENT_ID));
segmentRecord.setTraceId(resultSet.getString(SegmentRecord.TRACE_ID));
segmentRecord.setServiceId(resultSet.getInt(SegmentRecord.SERVICE_ID));
segmentRecord.setEndpointName(resultSet.getString(SegmentRecord.ENDPOINT_NAME));
segmentRecord.setStartTime(resultSet.getLong(SegmentRecord.START_TIME));
segmentRecord.setEndTime(resultSet.getLong(SegmentRecord.END_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));
}
segmentRecord.setVersion(resultSet.getInt(SegmentRecord.VERSION));
return segmentRecord;
}
}
} catch (SQLException e) {
throw new IOException(e);
}
return null;
}
private int querySequenceWithAgg(String aggType, String segmentId, long start, long end) throws IOException {
StringBuilder sql = new StringBuilder();
sql.append("select ").append(aggType).append("(").append(ProfileThreadSnapshotRecord.SEQUENCE).append(") from ").append(ProfileThreadSnapshotRecord.INDEX_NAME).append(" where ");
......
......@@ -121,6 +121,26 @@ public class ProfileClient extends SimpleQueryClient {
return Objects.requireNonNull(responseEntity.getBody()).getData().getTraces();
}
public ProfiledSegment.ProfiledSegmentData getProfiledSegment(final String segmentId) throws IOException {
final URL queryFileUrl = Resources.getResource("getProfiledSegment.gql");
final String queryString = Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{segmentId}", segmentId);
final ResponseEntity<GQLResponse<ProfiledSegment>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<ProfiledSegment>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getSegment();
}
public ProfileAnalyzation getProfileAnalyzation(final String segmentId, long start, long end) throws IOException {
final URL queryFileUrl = Resources.getResource("getProfileAnalyzation.gql");
final String queryString = Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
......@@ -143,4 +163,5 @@ public class ProfileClient extends SimpleQueryClient {
return Objects.requireNonNull(responseEntity.getBody()).getData();
}
}
/*
* 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.Data;
import lombok.ToString;
import java.util.List;
@Data
public class ProfiledSegment {
private ProfiledSegmentData segment;
@Data
@ToString
public static class ProfiledSegmentData {
private List<ProfiledSpan> spans;
}
}
/*
* 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 com.google.common.primitives.Ints;
import lombok.Data;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@Data
public class ProfiledSegmentMatcher extends AbstractMatcher<ProfiledSegment.ProfiledSegmentData> {
private List<ProfiledSpanMatcher> spans;
@Override
public void verify(ProfiledSegment.ProfiledSegmentData profiledSegmentData) {
assertThat(spans).hasSameSizeAs(profiledSegmentData.getSpans());
profiledSegmentData.setSpans(profiledSegmentData.getSpans().stream().sorted().collect(Collectors.toList()));
for (int i = 0; i < profiledSegmentData.getSpans().size(); i++) {
spans.get(i).verify(profiledSegmentData.getSpans().get(i));
}
}
}
/*
* 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 com.google.common.primitives.Ints;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class ProfiledSpan implements Comparable<ProfiledSpan> {
private String spanId;
private String parentSpanId;
private String serviceCode;
private String startTime;
private String endTime;
private String endpointName;
@Override
public int compareTo(ProfiledSpan o) {
return Ints.compare(Integer.parseInt(spanId), Integer.parseInt(o.spanId));
}
}
/*
* 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.Data;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
@Data
public class ProfiledSpanMatcher extends AbstractMatcher<ProfiledSpan> {
private String spanId;
private String parentSpanId;
private String serviceCode;
private String startTime;
private String endTime;
private String endpointName;
@Override
public void verify(ProfiledSpan span) {
doVerify(spanId, span.getSpanId());
doVerify(parentSpanId, span.getParentSpanId());
doVerify(serviceCode, span.getServiceCode());
doVerify(startTime, span.getStartTime());
doVerify(endTime, span.getEndTime());
doVerify(endpointName, span.getEndpointName());
}
}
# 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:
- spanId: 0
parentSpanId: -1
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: /e2e/users
- spanId: 1
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/PreparedStatement/executeQuery
- spanId: 2
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/PreparedStatement/executeUpdate
- spanId: 3
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/Connection/commit
- spanId: 4
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/Connection/commit
# 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 getProfiledSegment($segmentId: String!) {
segment: getProfiledSegment(segmentId: $segmentId) {
spans {
spanId parentSpanId serviceCode startTime endTime endpointName type peer component isError layer
}
}
}",
"variables": {
"segmentId": "{segmentId}"
}
}
\ No newline at end of file
......@@ -34,6 +34,8 @@ import org.apache.skywalking.e2e.profile.query.ProfileAnalyzation;
import org.apache.skywalking.e2e.profile.query.ProfileStackTreeMatcher;
import org.apache.skywalking.e2e.profile.query.ProfileTaskQuery;
import org.apache.skywalking.e2e.profile.query.ProfileTasks;
import org.apache.skywalking.e2e.profile.query.ProfiledSegment;
import org.apache.skywalking.e2e.profile.query.ProfiledSegmentMatcher;
import org.apache.skywalking.e2e.profile.query.ProfilesTasksMatcher;
import org.apache.skywalking.e2e.service.Service;
import org.apache.skywalking.e2e.service.ServicesMatcher;
......@@ -192,6 +194,15 @@ public class ProfileVerificationITCase {
}
String segmentId = foundedTrace.getKey();
// verify segment
ProfiledSegment.ProfiledSegmentData segmentData = profileClient.getProfiledSegment(foundedTrace.getKey());
LOGGER.info("get profiled segment : {}", segmentData);
InputStream inputStream = new ClassPathResource(
"expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileSegment.yml").getInputStream();
final ProfiledSegmentMatcher tracesMatcher = new Yaml().loadAs(inputStream, ProfiledSegmentMatcher.class);
tracesMatcher.verify(segmentData);
long start = Long.parseLong(foundedTrace.getStart());
long end = start + foundedTrace.getDuration();
ProfileAnalyzation analyzation = profileClient.getProfileAnalyzation(segmentId, start, end);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册