未验证 提交 576bd7e2 编写于 作者: K kezhenxu94 提交者: GitHub

Test: add E2E test for Python Agent (#4770)

上级 749af3e0
# 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.
name: E2E
on:
pull_request:
push:
branches:
- master
tags:
- 'v*'
env:
SKIP_TEST: true
SW_AGENT_JDK_VERSION: 8
jobs:
PythonAgent:
name: PythonAgent
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Compile and Build
run: make docker
- name: Copy dist package
run: cp -R dist test/e2e/
- name: Python Agent
run: ./mvnw --batch-mode -f test/e2e/pom.xml -am -DfailIfNoTests=false verify -Dit.test=org.apache.skywalking.e2e.PythonE2E
- uses: actions/upload-artifact@v1
if: failure()
with:
name: logs
path: logs
......@@ -18,10 +18,11 @@
package org.apache.skywalking.e2e.service.instance;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class Instances {
private List<Instance> instances;
private List<Instance> instances = 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.
FROM python:3.7
ENV COMMIT_HASH=445d64c162555a3ff92b98e8ccec3cdc1a66876d
WORKDIR /app
RUN git clone https://github.com/apache/skywalking-python.git --depth=1 $(pwd)
RUN git reset --hard ${COMMIT_HASH} && git submodule update --init
RUN make setup install
ADD ./consumer.py /consumer.py
ADD ./provider.py /provider.py
#
# 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.
#
import urllib.parse
from urllib import request
from skywalking import agent, config
if __name__ == '__main__':
config.service_name = 'consumer'
config.logging_level = 'DEBUG'
agent.start()
import socketserver
from http.server import BaseHTTPRequestHandler
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json; charset=utf-8')
self.end_headers()
data = '{"name": "whatever"}'.encode('utf8')
req = request.Request('http://medium:9092/users')
req.add_header('Content-Type', 'application/json; charset=utf-8')
req.add_header('Content-Length', str(len(data)))
with request.urlopen(req, data):
self.wfile.write(data)
PORT = 9090
Handler = SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
# 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.
version: '2.1'
services:
oap:
extends:
file: ../base-compose.yml
service: oap
ui:
extends:
file: ../base-compose.yml
service: ui
depends_on:
oap:
condition: service_healthy
provider:
build:
context: .
dockerfile: Dockerfile.python
networks:
- e2e
expose:
- 9091
environment:
SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
SW_AGENT_INSTANCE: provider-instance
depends_on:
oap:
condition: service_healthy
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9091"]
interval: 5s
timeout: 60s
retries: 120
entrypoint: ['python3', '/provider.py']
medium:
extends:
file: ../base-compose.yml
service: consumer
environment:
PROVIDER_URL: http://provider:9091
depends_on:
oap:
condition: service_healthy
provider:
condition: service_healthy
consumer:
build:
context: .
dockerfile: Dockerfile.python
networks:
- e2e
expose:
- 9090
environment:
SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
PROVIDER_URL: http://medium:9092/users
SW_AGENT_INSTANCE: consumer-instance
depends_on:
oap:
condition: service_healthy
medium:
condition: service_healthy
healthcheck:
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9090"]
interval: 5s
timeout: 60s
retries: 120
entrypoint: ['python3', '/consumer.py']
networks:
e2e:
#
# 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.
#
from urllib import request
from skywalking import agent, config
if __name__ == '__main__':
config.service_name = 'provider'
config.logging_level = 'DEBUG'
agent.start()
import socketserver
from http.server import BaseHTTPRequestHandler
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
req = request.Request('https://github.com/kezhenxu94')
with request.urlopen(req):
self.wfile.write('{"name": "whatever"}'.encode('ascii'))
PORT = 9091
Handler = SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
/*
* 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;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
import org.apache.skywalking.e2e.annotation.DockerCompose;
import org.apache.skywalking.e2e.base.SkyWalkingE2E;
import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
import org.apache.skywalking.e2e.common.HostAndPort;
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
import org.apache.skywalking.e2e.metrics.Metrics;
import org.apache.skywalking.e2e.metrics.MetricsQuery;
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
import org.apache.skywalking.e2e.retryable.RetryableTest;
import org.apache.skywalking.e2e.service.Service;
import org.apache.skywalking.e2e.service.ServicesMatcher;
import org.apache.skywalking.e2e.service.ServicesQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoint;
import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
import org.apache.skywalking.e2e.service.instance.Instance;
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.topo.Call;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
import org.apache.skywalking.e2e.topo.TopoMatcher;
import org.apache.skywalking.e2e.topo.TopoQuery;
import org.apache.skywalking.e2e.topo.Topology;
import org.apache.skywalking.e2e.trace.Trace;
import org.apache.skywalking.e2e.trace.TracesMatcher;
import org.apache.skywalking.e2e.trace.TracesQuery;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.DockerComposeContainer;
import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
import static org.apache.skywalking.e2e.utils.Times.now;
import static org.apache.skywalking.e2e.utils.Yamls.load;
@Slf4j
@SkyWalkingE2E
public class PythonE2E extends SkyWalkingTestAdapter {
@SuppressWarnings("unused")
@DockerCompose("docker/python/docker-compose.yml")
private DockerComposeContainer<?> justForSideEffects;
@SuppressWarnings("unused")
@ContainerHostAndPort(name = "ui", port = 8080)
private HostAndPort swWebappHostPort;
@SuppressWarnings("unused")
@ContainerHostAndPort(name = "consumer", port = 9090)
private HostAndPort pythonHostPort;
@BeforeAll
public void setUp() throws Exception {
queryClient(swWebappHostPort);
trafficController(pythonHostPort, "/test");
}
@AfterAll
public void tearDown() {
trafficController.stop();
}
@RetryableTest
void services() throws Exception {
final List<Service> services = graphql.services(new ServicesQuery().start(startTime).end(now()));
LOGGER.info("services: {}", services);
load("expected/python/services.yml").as(ServicesMatcher.class).verify(services);
for (Service service : services) {
if ("Your_ApplicationName".equals(service.getLabel())) {
continue;
}
LOGGER.info("verifying service instances: {}", service);
verifyServiceMetrics(service);
final Instances instances = verifyServiceInstances(service);
verifyInstancesMetrics(instances);
final Endpoints endpoints = verifyServiceEndpoints(service);
verifyEndpointsMetrics(endpoints);
}
}
@RetryableTest
void traces() throws Exception {
final List<Trace> traces = graphql.traces(new TracesQuery().start(startTime).end(now()).orderByStartTime());
LOGGER.info("traces: {}", traces);
load("expected/python/traces.yml").as(TracesMatcher.class).verifyLoosely(traces);
}
@RetryableTest
void topology() throws Exception {
final Topology topology = graphql.topo(new TopoQuery().stepByMinute().start(startTime.minusDays(1)).end(now()));
LOGGER.info("topology: {}", topology);
load("expected/python/topo.yml").as(TopoMatcher.class).verify(topology);
verifyServiceRelationMetrics(topology.getCalls());
}
@RetryableTest
void serviceInstances() throws Exception {
final ServiceInstanceTopology topology = graphql.serviceInstanceTopo(
new ServiceInstanceTopologyQuery().stepByMinute()
.start(startTime.minusDays(1))
.end(now())
.clientServiceId("Y29uc3VtZXI=.1")
.serverServiceId("WW91cl9BcHBsaWNhdGlvbk5hbWU=.1"));
LOGGER.info("topology: {}", topology);
load("expected/python/consumer-instance-topo.yml").as(ServiceInstanceTopologyMatcher.class).verify(topology);
verifyServiceInstanceRelationMetrics(topology.getCalls());
}
private Instances verifyServiceInstances(final Service service) throws Exception {
final Instances instances = graphql.instances(
new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
);
LOGGER.info("instances: {} {}", service.getLabel(), instances);
load(String.format("expected/python/%s-instances.yml", service.getLabel()))
.as(InstancesMatcher.class)
.verify(instances);
return instances;
}
private Endpoints verifyServiceEndpoints(final Service service) throws Exception {
final Endpoints endpoints = graphql.endpoints(new EndpointQuery().serviceId(service.getKey()));
LOGGER.info("endpoints: {} {}", service.getLabel(), endpoints);
load(String.format("expected/python/%s-endpoints.yml", service.getLabel()))
.as(EndpointsMatcher.class)
.verify(endpoints);
return endpoints;
}
private void verifyInstancesMetrics(Instances instances) throws Exception {
for (Instance instance : instances.getInstances()) {
for (String metricsName : ALL_INSTANCE_METRICS) {
LOGGER.info("verifying service instance response time: {}", instance);
final Metrics instanceMetrics = graphql.metrics(
new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
);
LOGGER.info("instance metrics: {}", instanceMetrics);
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(instanceMetrics);
LOGGER.info("{}: {}", metricsName, instanceMetrics);
}
}
}
private void verifyEndpointsMetrics(Endpoints endpoints) throws Exception {
for (Endpoint endpoint : endpoints.getEndpoints()) {
for (final String metricName : ALL_ENDPOINT_METRICS) {
LOGGER.info("verifying endpoint {}: {}", endpoint, metricName);
final Metrics metrics = graphql.metrics(
new MetricsQuery().stepByMinute().metricsName(metricName).id(endpoint.getKey())
);
LOGGER.info("metrics: {}", metrics);
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(metrics);
LOGGER.info("{}: {}", metricName, metrics);
}
}
}
private void verifyServiceMetrics(final Service service) throws Exception {
for (String metricName : ALL_SERVICE_METRICS) {
LOGGER.info("verifying service {}, metrics: {}", service, metricName);
final Metrics serviceMetrics = graphql.metrics(
new MetricsQuery().stepByMinute().metricsName(metricName).id(service.getKey())
);
LOGGER.info("serviceMetrics: {}", serviceMetrics);
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(serviceMetrics);
LOGGER.info("{}: {}", metricName, serviceMetrics);
}
}
private void verifyServiceInstanceRelationMetrics(final List<Call> calls) throws Exception {
verifyRelationMetrics(
calls, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
);
}
private void verifyServiceRelationMetrics(final List<Call> calls) throws Exception {
verifyRelationMetrics(calls, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
}
private void verifyRelationMetrics(final List<Call> calls,
final String[] relationClientMetrics,
final String[] relationServerMetrics) throws Exception {
for (Call call : calls) {
for (String detectPoint : call.getDetectPoints()) {
switch (detectPoint) {
case "CLIENT": {
for (String metricName : relationClientMetrics) {
verifyMetrics(graphql, metricName, call.getId(), startTime);
}
break;
}
case "SERVER": {
for (String metricName : relationServerMetrics) {
verifyMetrics(graphql, metricName, call.getId(), startTime);
}
break;
}
}
}
}
}
}
# 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.
endpoints:
- key: not null
label: /test
# 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.
nodes:
- id: not null
name: consumer-instance
serviceId: not null
serviceName: consumer
isReal: true
- id: not null
name: not null
serviceId: not null
serviceName: Your_ApplicationName
isReal: true
calls:
- id: not null
source: Y29uc3VtZXI=.1_Y29uc3VtZXItaW5zdGFuY2U=
detectPoints:
- CLIENT
- SERVER
target: not null
# 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.
instances:
- key: not null
label: not null
# 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.
endpoints:
- key: not null
label: /users
# 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.
instances:
- key: not null
label: not null
# 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.
services:
- key: not null
label: provider
- key: not null
label: consumer
- key: not null
label: Your_ApplicationName
# 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.
nodes:
- id: not null
name: User
type: USER
isReal: false
- id: not null
name: consumer
type: Python
isReal: true
- id: not null
name: provider
type: Python
isReal: true
- id: not null
name: Your_ApplicationName
type: Tomcat
isReal: true
- id: not null
name: github.com
type: Unknown
isReal: false
calls:
- id: not null
source: ${User[0]}
detectPoints:
- SERVER
target: ${consumer[0]}
- id: not null
source: ${consumer[0]}
detectPoints:
- CLIENT
- SERVER
target: ${Your_ApplicationName[0]}
- id: not null
source: ${Your_ApplicationName[0]}
detectPoints:
- CLIENT
- SERVER
target: ${provider[0]}
- id: not null
source: ${provider[0]}
detectPoints:
- CLIENT
target: ${github.com[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.
traces:
- key: not null
endpointNames:
- /users
duration: ge 0
start: gt 0
isError: false
traceIds:
- not null
- key: not null
endpointNames:
- /test
duration: ge 0
start: gt 0
isError: false
traceIds:
- not null
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册