Support continuous profiling feature (#10473)
This commit is contained in:
parent
3662b01365
commit
7dcdb279ef
|
|
@ -528,6 +528,28 @@ jobs:
|
|||
config: test/e2e-v2/cases/profiling/ebpf/network/opensearch/e2e.yaml
|
||||
env: OPENSEARCH_VERSION=2.4.0
|
||||
|
||||
- name: Continuous Profiling BanyanDB
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/e2e.yaml
|
||||
- name: Continuous Profiling H2
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/h2/e2e.yaml
|
||||
- name: Continuous Profiling ES
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/es/e2e.yaml
|
||||
- name: Continuous Profiling Sharding ES
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/e2e.yaml
|
||||
- name: Continuous Profiling MySQL
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/mysql/e2e.yaml
|
||||
- name: Continuous Profiling Postgres
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml
|
||||
- name: Continuous Profiling OpenSearch 1.1.0
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
|
||||
env: OPENSEARCH_VERSION=1.1.0
|
||||
- name: Continuous Profiling OpenSearch 1.3.6
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
|
||||
env: OPENSEARCH_VERSION=1.3.6
|
||||
- name: Continuous Profiling OpenSearch 2.4.0
|
||||
config: test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
|
||||
env: OPENSEARCH_VERSION=2.4.0
|
||||
|
||||
- name: Kafka Basic
|
||||
config: test/e2e-v2/cases/kafka/simple-so11y/e2e.yaml
|
||||
- name: Kafka Profiling
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.network.trace.component.command;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class ContinuousProfilingPolicy {
|
||||
@SerializedName("ServiceName")
|
||||
private String serviceName;
|
||||
@SerializedName("UUID")
|
||||
private String uuid;
|
||||
@SerializedName("Profiling")
|
||||
private Map<String, Map<String, Item>> profiling;
|
||||
|
||||
@Data
|
||||
public static class Item {
|
||||
@SerializedName("Threshold")
|
||||
private String threshold;
|
||||
@SerializedName("Period")
|
||||
private int period;
|
||||
@SerializedName("Count")
|
||||
private int count;
|
||||
@SerializedName("URIList")
|
||||
private List<String> uriList;
|
||||
@SerializedName("URIRegex")
|
||||
private String uriRegex;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.network.trace.component.command;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.skywalking.apm.network.common.v3.Command;
|
||||
import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContinuousProfilingPolicyCommand extends BaseCommand implements Serializable {
|
||||
public static final String NAME = "ContinuousProfilingPolicyQuery";
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private List<ContinuousProfilingPolicy> policies;
|
||||
|
||||
public ContinuousProfilingPolicyCommand(String serialNumber, List<ContinuousProfilingPolicy> policies) {
|
||||
super(NAME, serialNumber);
|
||||
this.policies = policies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.Builder serialize() {
|
||||
final Command.Builder builder = commandBuilder();
|
||||
builder.addArgs(KeyStringValuePair.newBuilder()
|
||||
.setKey("ServiceWithPolicyJSON").setValue(GSON.toJson(policies)).build());
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
@ -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.network.trace.component.command;
|
||||
|
||||
import org.apache.skywalking.apm.network.common.v3.Command;
|
||||
import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
|
||||
|
||||
public class ContinuousProfilingReportCommand extends BaseCommand implements Serializable {
|
||||
public static final String NAME = "ContinuousProfilingReportTask";
|
||||
|
||||
private final String taskId;
|
||||
|
||||
public ContinuousProfilingReportCommand(String serialNumber, String taskId) {
|
||||
super(NAME, serialNumber);
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.Builder serialize() {
|
||||
final Command.Builder builder = commandBuilder();
|
||||
builder.addArgs(KeyStringValuePair.newBuilder()
|
||||
.setKey("TaskId").setValue(taskId).build());
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 9c7a0bf8e0c2195280adf65f50cbd3161dd588ff
|
||||
Subproject commit 0da9c8b3e111fb51c9f8854cae16d4519462ecfe
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
* [Breaking Change] Enhance JDBC storage through merging tables and managing day-based table rolling.
|
||||
* [Breaking Change] Sharding-MySQL implementations and tests get removed due to we have the day-based rolling mechanism by default
|
||||
* Fix otel k8s-cluster rule add namespace dimension for MAL aggregation calculation(Deployment Status,Deployment Spec Replicas)
|
||||
* Support continuous profiling feature.
|
||||
* Support collect process level related metrics.
|
||||
|
||||
#### Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -247,6 +247,8 @@ They extract level relevant labels from metric labels, then informs the meter-sy
|
|||
extracts instance level labels from the second array argument, extracts layer from `Layer` argument, `propertiesExtractor` is an optional closure that extracts instance properties from `tags`, e.g. `{ tags -> ['pod': tags.pod, 'namespace': tags.namespace] }`.
|
||||
- `endpoint([svc_label1, svc_label2...], [ep_label1, ep_label2...])` extracts service level labels from the first array argument,
|
||||
extracts endpoint level labels from the second array argument, extracts layer from `Layer` argument.
|
||||
- `process([svc_label1, svc_label2...], [ins_label1, ins_label2...], [ps_label1, ps_label2...], layer_lable)` extracts service level labels from the first array argument,
|
||||
extracts instance level labels from the second array argument, extracts process level labels from the third array argument, extracts layer label from fourse argument.
|
||||
- `serviceRelation(DetectPoint, [source_svc_label1...], [dest_svc_label1...], Layer)` DetectPoint including `DetectPoint.CLIENT` and `DetectPoint.SERVER`,
|
||||
extracts `sourceService` labels from the first array argument, extracts `destService` labels from the second array argument, extracts layer from `Layer` argument.
|
||||
- `processRelation(detect_point_label, [service_label1...], [instance_label1...], source_process_id_label, dest_process_id_label, component_label)` extracts `DetectPoint` labels from first argument, the label value should be `client` or `server`.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.meter.analyzer.dsl.EntityDescription;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.apache.skywalking.oap.server.core.analysis.meter.ScopeType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
@ToString
|
||||
public class ProcessEntityDescription implements EntityDescription {
|
||||
private final ScopeType scopeType = ScopeType.PROCESS;
|
||||
private final List<String> serviceKeys;
|
||||
private final List<String> serviceInstanceKeys;
|
||||
private final List<String> processKeys;
|
||||
private final String layerKey;
|
||||
private final String delimiter;
|
||||
|
||||
@Override
|
||||
public List<String> getLabelKeys() {
|
||||
return ImmutableList.<String>builder()
|
||||
.addAll(serviceKeys)
|
||||
.addAll(serviceInstanceKeys)
|
||||
.addAll(processKeys)
|
||||
.add(layerKey)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.EndpointEntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.EntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.InstanceEntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ProcessEntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ProcessRelationEntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ServiceEntityDescription;
|
||||
import org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ServiceRelationEntityDescription;
|
||||
|
|
@ -477,6 +478,23 @@ public class SampleFamily {
|
|||
return createMeterSamples(new EndpointEntityDescription(serviceKeys, endpointKeys, layer, Const.POINT));
|
||||
}
|
||||
|
||||
public SampleFamily process(List<String> serviceKeys, List<String> serviceInstanceKeys, List<String> processKeys, String layerKey) {
|
||||
Preconditions.checkArgument(serviceKeys.size() > 0);
|
||||
Preconditions.checkArgument(serviceInstanceKeys.size() > 0);
|
||||
Preconditions.checkArgument(processKeys.size() > 0);
|
||||
ExpressionParsingContext.get().ifPresent(ctx -> {
|
||||
ctx.scopeType = ScopeType.PROCESS;
|
||||
ctx.scopeLabels.addAll(serviceKeys);
|
||||
ctx.scopeLabels.addAll(serviceInstanceKeys);
|
||||
ctx.scopeLabels.addAll(processKeys);
|
||||
ctx.scopeLabels.add(layerKey);
|
||||
});
|
||||
if (this == EMPTY) {
|
||||
return EMPTY;
|
||||
}
|
||||
return createMeterSamples(new ProcessEntityDescription(serviceKeys, serviceInstanceKeys, processKeys, layerKey, Const.POINT));
|
||||
}
|
||||
|
||||
public SampleFamily serviceRelation(DetectPoint detectPoint, List<String> sourceServiceKeys, List<String> destServiceKeys, Layer layer) {
|
||||
Preconditions.checkArgument(sourceServiceKeys.size() > 0);
|
||||
Preconditions.checkArgument(destServiceKeys.size() > 0);
|
||||
|
|
@ -668,6 +686,14 @@ public class SampleFamily {
|
|||
InternalOps.dim(samples, endpointEntityDescription.getEndpointKeys(), endpointEntityDescription.getDelimiter()),
|
||||
endpointEntityDescription.getLayer()
|
||||
);
|
||||
case PROCESS:
|
||||
final ProcessEntityDescription processEntityDescription = (ProcessEntityDescription) entityDescription;
|
||||
return MeterEntity.newProcess(
|
||||
InternalOps.dim(samples, processEntityDescription.getServiceKeys(), processEntityDescription.getDelimiter()),
|
||||
InternalOps.dim(samples, processEntityDescription.getServiceInstanceKeys(), processEntityDescription.getDelimiter()),
|
||||
InternalOps.dim(samples, processEntityDescription.getProcessKeys(), processEntityDescription.getDelimiter()),
|
||||
InternalOps.dim(samples, List.of(processEntityDescription.getLayerKey()), processEntityDescription.getDelimiter())
|
||||
);
|
||||
case SERVICE_RELATION:
|
||||
ServiceRelationEntityDescription serviceRelationEntityDescription = (ServiceRelationEntityDescription) entityDescription;
|
||||
return MeterEntity.newServiceRelation(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package org.apache.skywalking.oap.server.exporter.provider;
|
|||
|
||||
import lombok.Setter;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsEntityMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
|
||||
|
|
@ -76,9 +75,6 @@ public class MetricFormatter {
|
|||
endpointRelationDefine.getDestServiceId());
|
||||
return endpointRelationDefine.getSource() + " in " + sourceService.getName()
|
||||
+ " to " + endpointRelationDefine.getDest() + " in " + destService.getName();
|
||||
} else if (DefaultScopeDefine.inProcessCatalog(scope)) {
|
||||
final MetricsEntityMetaInfo entity = meta.getEntity();
|
||||
return entity.getProcessName() + " in " + entity.getInstanceName() + " of " + entity.getServiceName();
|
||||
} else if (scope == DefaultScopeDefine.ALL) {
|
||||
return "";
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.oap.server.core.alarm.AlarmCallback;
|
||||
import org.apache.skywalking.oap.server.core.alarm.EndpointRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ProcessMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceInstanceRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.EndpointMetaInAlarm;
|
||||
|
|
@ -42,7 +41,6 @@ import org.apache.skywalking.oap.server.core.alarm.provider.wechat.WechatHookCal
|
|||
import org.apache.skywalking.oap.server.core.alarm.provider.welink.WeLinkHookCallback;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsEntityMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
|
|
@ -68,8 +66,7 @@ public class NotifyHandler implements MetricsNotify {
|
|||
|
||||
if (!DefaultScopeDefine.inServiceCatalog(scope) && !DefaultScopeDefine.inServiceInstanceCatalog(scope)
|
||||
&& !DefaultScopeDefine.inEndpointCatalog(scope) && !DefaultScopeDefine.inServiceRelationCatalog(scope)
|
||||
&& !DefaultScopeDefine.inServiceInstanceRelationCatalog(scope) && !DefaultScopeDefine.inEndpointRelationCatalog(scope)
|
||||
&& !DefaultScopeDefine.inProcessCatalog(scope)) {
|
||||
&& !DefaultScopeDefine.inServiceInstanceRelationCatalog(scope) && !DefaultScopeDefine.inEndpointRelationCatalog(scope)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -155,16 +152,6 @@ public class NotifyHandler implements MetricsNotify {
|
|||
endpointRelationMetaInAlarm.setName(endpointRelationDefine.getSource() + " in " + sourceService.getName()
|
||||
+ " to " + endpointRelationDefine.getDest() + " in " + destService.getName());
|
||||
metaInAlarm = endpointRelationMetaInAlarm;
|
||||
} else if (DefaultScopeDefine.inProcessCatalog(scope)) {
|
||||
final String processId = meta.getId();
|
||||
final MetricsEntityMetaInfo entity = meta.getEntity();
|
||||
|
||||
ProcessMetaInAlarm processMetaInAlarm = new ProcessMetaInAlarm();
|
||||
processMetaInAlarm.setMetricsName(meta.getMetricsName());
|
||||
processMetaInAlarm.setId(processId);
|
||||
processMetaInAlarm.setName(entity.getProcessName() + " in " + entity.getInstanceName()
|
||||
+ " of " + entity.getServiceName());
|
||||
metaInAlarm = processMetaInAlarm;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,12 @@ import org.apache.skywalking.oap.server.core.alarm.AlarmMessage;
|
|||
import org.apache.skywalking.oap.server.core.alarm.EndpointMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.EndpointRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.MetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ProcessMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceInstanceMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceInstanceRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.alarm.ServiceRelationMetaInAlarm;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsEntityMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
|
|
@ -248,37 +246,6 @@ public class NotifyHandlerTest {
|
|||
assertEquals(DefaultScopeDefine.ENDPOINT_RELATION, metaInAlarm.getScopeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyWithProcessCatalog() {
|
||||
String metricsName = "process-metrics";
|
||||
String serviceName = "test-service";
|
||||
String instanceName = "test-instance";
|
||||
String processName = "test-process";
|
||||
when(metadata.getMetricsName()).thenReturn(metricsName);
|
||||
when(DefaultScopeDefine.inProcessCatalog(0)).thenReturn(true);
|
||||
final String processId = IDManager.ProcessID.buildId(
|
||||
IDManager.ServiceInstanceID.buildId(IDManager.ServiceID.buildId(serviceName, true), instanceName),
|
||||
processName
|
||||
);
|
||||
when(metadata.getId()).thenReturn(processId);
|
||||
when(metadata.getEntity()).thenReturn(MetricsEntityMetaInfo.buildProcess(serviceName, instanceName, processName));
|
||||
|
||||
ArgumentCaptor<MetaInAlarm> metaCaptor = ArgumentCaptor.forClass(MetaInAlarm.class);
|
||||
|
||||
notifyHandler.notify(metrics);
|
||||
verify(rule).in(metaCaptor.capture(), any());
|
||||
|
||||
MetaInAlarm metaInAlarm = metaCaptor.getValue();
|
||||
|
||||
assertTrue(metaInAlarm instanceof ProcessMetaInAlarm);
|
||||
assertEquals(metricsName, metaInAlarm.getMetricsName());
|
||||
assertEquals("cf4be92893026c77c539266f47f2aa22f1e53ff64fc64803f5814293ff10a56f", metaInAlarm.getId0());
|
||||
assertEquals("", metaInAlarm.getId1());
|
||||
assertEquals(DefaultScopeDefine.PROCESS_CATALOG_NAME, metaInAlarm.getScope());
|
||||
assertEquals("test-process in test-instance of test-service", metaInAlarm.getName());
|
||||
assertEquals(DefaultScopeDefine.PROCESS, metaInAlarm.getScopeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dontNotify() {
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogServ
|
|||
import org.apache.skywalking.oap.server.core.config.NamingControl;
|
||||
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingMutationService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.EBPFProfilingMutationService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.EBPFProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileTaskMutationService;
|
||||
|
|
@ -102,6 +104,8 @@ public class CoreModule extends ModuleDefine {
|
|||
private void addEBPFProfilingService(List<Class> classes) {
|
||||
classes.add(EBPFProfilingMutationService.class);
|
||||
classes.add(EBPFProfilingQueryService.class);
|
||||
classes.add(ContinuousProfilingMutationService.class);
|
||||
classes.add(ContinuousProfilingQueryService.class);
|
||||
}
|
||||
|
||||
private void addManagementService(List<Class> classes) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateIn
|
|||
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.DisableOALDefine;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingMutationService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.EBPFProfilingMutationService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.EBPFProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.trace.ProfileTaskMutationService;
|
||||
|
|
@ -296,6 +298,10 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
EBPFProfilingQueryService.class,
|
||||
new EBPFProfilingQueryService(getManager(), moduleConfig, this.storageModels)
|
||||
);
|
||||
this.registerServiceImplementation(
|
||||
ContinuousProfilingMutationService.class, new ContinuousProfilingMutationService(getManager()));
|
||||
this.registerServiceImplementation(
|
||||
ContinuousProfilingQueryService.class, new ContinuousProfilingQueryService(getManager()));
|
||||
|
||||
this.registerServiceImplementation(CommandService.class, new CommandService(getManager()));
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public class MeterEntity {
|
|||
private String instanceName;
|
||||
private Map<String, String> instanceProperties;
|
||||
private String endpointName;
|
||||
private String processName;
|
||||
private String sourceServiceName;
|
||||
private String destServiceName;
|
||||
private String sourceProcessId;
|
||||
|
|
@ -64,6 +65,8 @@ public class MeterEntity {
|
|||
IDManager.ServiceID.buildId(serviceName, true), instanceName);
|
||||
case ENDPOINT:
|
||||
return IDManager.EndpointID.buildId(IDManager.ServiceID.buildId(serviceName, true), endpointName);
|
||||
case PROCESS:
|
||||
return IDManager.ProcessID.buildId(IDManager.ServiceInstanceID.buildId(IDManager.ServiceID.buildId(serviceName, true), instanceName), processName);
|
||||
case SERVICE_RELATION:
|
||||
return IDManager.ServiceID.buildRelationId(new IDManager.ServiceID.ServiceRelationDefine(
|
||||
sourceServiceId(),
|
||||
|
|
@ -139,6 +142,16 @@ public class MeterEntity {
|
|||
return meterEntity;
|
||||
}
|
||||
|
||||
public static MeterEntity newProcess(String serviceName, String instanceName, String processName, String layerName) {
|
||||
final MeterEntity meterEntity = new MeterEntity();
|
||||
meterEntity.scopeType = ScopeType.PROCESS;
|
||||
meterEntity.serviceName = NAMING_CONTROL.formatServiceName(serviceName);
|
||||
meterEntity.instanceName = NAMING_CONTROL.formatInstanceName(instanceName);
|
||||
meterEntity.processName = processName;
|
||||
meterEntity.layer = Layer.nameOf(layerName);
|
||||
return meterEntity;
|
||||
}
|
||||
|
||||
public static MeterEntity newServiceRelation(String sourceServiceName,
|
||||
String destServiceName,
|
||||
DetectPoint detectPoint, Layer layer) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public enum ScopeType {
|
|||
SERVICE(DefaultScopeDefine.SERVICE),
|
||||
SERVICE_INSTANCE(DefaultScopeDefine.SERVICE_INSTANCE),
|
||||
ENDPOINT(DefaultScopeDefine.ENDPOINT),
|
||||
PROCESS(DefaultScopeDefine.PROCESS),
|
||||
SERVICE_RELATION(DefaultScopeDefine.SERVICE_RELATION),
|
||||
PROCESS_RELATION(DefaultScopeDefine.PROCESS_RELATION);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,18 @@ import java.util.Objects;
|
|||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicyConfiguration;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingReportCommand;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicyCommand;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.EBPFProfilingTaskCommand;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.EBPFProfilingTaskExtensionConfig;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.ProfileTaskCommand;
|
||||
|
|
@ -38,6 +46,7 @@ import org.apache.skywalking.oap.server.library.module.Service;
|
|||
* CommandService represents the command creation factory. All commands for downstream agents should be created here.
|
||||
*/
|
||||
public class CommandService implements Service {
|
||||
private static final Gson GSON = new Gson();
|
||||
private final ModuleManager moduleManager;
|
||||
|
||||
public CommandService(final ModuleManager moduleManager) {
|
||||
|
|
@ -54,20 +63,55 @@ public class CommandService implements Service {
|
|||
/**
|
||||
* Used to notify the eBPF Profiling task to the eBPF agent side
|
||||
*/
|
||||
public EBPFProfilingTaskCommand newEBPFProfilingTaskCommand(EBPFProfilingTask task, List<String> processId) {
|
||||
public EBPFProfilingTaskCommand newEBPFProfilingTaskCommand(EBPFProfilingTaskRecord task, List<String> processId) {
|
||||
final String serialNumber = UUID.randomUUID().toString();
|
||||
EBPFProfilingTaskCommand.FixedTrigger fixedTrigger = null;
|
||||
if (Objects.equals(task.getTriggerType(), EBPFProfilingTriggerType.FIXED_TIME)) {
|
||||
if (Objects.equals(task.getTriggerType(), EBPFProfilingTriggerType.FIXED_TIME.value())) {
|
||||
fixedTrigger = new EBPFProfilingTaskCommand.FixedTrigger(task.getFixedTriggerDuration());
|
||||
}
|
||||
return new EBPFProfilingTaskCommand(serialNumber, task.getTaskId(), processId, task.getTaskStartTime(),
|
||||
task.getLastUpdateTime(), task.getTriggerType().name(), fixedTrigger, task.getTargetType().name(),
|
||||
convertExtension(task));
|
||||
return new EBPFProfilingTaskCommand(serialNumber, task.getLogicalId(), processId, task.getStartTime(),
|
||||
task.getLastUpdateTime(), EBPFProfilingTriggerType.valueOf(task.getTriggerType()).name(), fixedTrigger,
|
||||
EBPFProfilingTargetType.valueOf(task.getTargetType()).name(),
|
||||
convertExtension(task));
|
||||
}
|
||||
|
||||
private EBPFProfilingTaskExtensionConfig convertExtension(EBPFProfilingTask task) {
|
||||
EBPFProfilingTaskExtension extensionConfig = task.getExtensionConfig();
|
||||
if (extensionConfig == null || CollectionUtils.isEmpty(extensionConfig.getNetworkSamplings())) {
|
||||
public ContinuousProfilingPolicyCommand newContinuousProfilingServicePolicyCommand(List<ContinuousProfilingPolicy> policy) {
|
||||
return new ContinuousProfilingPolicyCommand(UUID.randomUUID().toString(),
|
||||
policy.stream().map(this::convertContinuesProfilingPolicy).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public ContinuousProfilingReportCommand newContinuousProfilingReportCommand(String taskId) {
|
||||
return new ContinuousProfilingReportCommand(UUID.randomUUID().toString(), taskId);
|
||||
}
|
||||
|
||||
private org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicy convertContinuesProfilingPolicy(ContinuousProfilingPolicy policy) {
|
||||
final org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicy result = new org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicy();
|
||||
result.setServiceName(IDManager.ServiceID.analysisId(policy.getServiceId()).getName());
|
||||
result.setUuid(policy.getUuid());
|
||||
if (StringUtil.isNotEmpty(policy.getConfigurationJson())) {
|
||||
final ContinuousProfilingPolicyConfiguration configuration = ContinuousProfilingPolicyConfiguration.parseFromJSON(policy.getConfigurationJson());
|
||||
result.setProfiling(configuration.getTargetCheckers().entrySet().stream().collect(Collectors.toMap(
|
||||
c -> c.getKey().name(),
|
||||
c -> c.getValue().entrySet().stream().collect(Collectors.toMap(i -> i.getKey().name(), i -> {
|
||||
final org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicy.Item item = new org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicy.Item();
|
||||
item.setThreshold(i.getValue().getThreshold());
|
||||
item.setPeriod(i.getValue().getPeriod());
|
||||
item.setCount(i.getValue().getCount());
|
||||
item.setUriList(i.getValue().getUriList());
|
||||
item.setUriRegex(i.getValue().getUriRegex());
|
||||
return item;
|
||||
}
|
||||
)))));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private EBPFProfilingTaskExtensionConfig convertExtension(EBPFProfilingTaskRecord task) {
|
||||
if (StringUtil.isEmpty(task.getExtensionConfigJson())) {
|
||||
return null;
|
||||
}
|
||||
EBPFProfilingTaskExtension extensionConfig = GSON.fromJson(task.getExtensionConfigJson(), EBPFProfilingTaskExtension.class);
|
||||
if (CollectionUtils.isEmpty(extensionConfig.getNetworkSamplings())) {
|
||||
return null;
|
||||
}
|
||||
EBPFProfilingTaskExtensionConfig config = new EBPFProfilingTaskExtensionConfig();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicyConfiguration;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyItemCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyTargetCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingSetResult;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
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;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ContinuousProfilingMutationService implements Service {
|
||||
private static final Gson GSON = new Gson();
|
||||
private final ModuleManager moduleManager;
|
||||
|
||||
private IContinuousProfilingPolicyDAO policyDAO;
|
||||
|
||||
public IContinuousProfilingPolicyDAO getPolicyDAO() {
|
||||
if (policyDAO == null) {
|
||||
this.policyDAO = moduleManager.find(StorageModule.NAME)
|
||||
.provider().getService(IContinuousProfilingPolicyDAO.class);
|
||||
}
|
||||
return policyDAO;
|
||||
}
|
||||
|
||||
public ContinuousProfilingSetResult setContinuousProfilingPolicy(ContinuousProfilingPolicyCreation request) throws IOException {
|
||||
// validate the service id
|
||||
if (StringUtil.isEmpty(request.getServiceId())) {
|
||||
return buildError("the service id cannot be empty");
|
||||
}
|
||||
|
||||
// validate the targets
|
||||
if (CollectionUtils.isNotEmpty(request.getTargets())) {
|
||||
String validateTarget = validateTargets(request.getTargets());
|
||||
if (StringUtil.isNotEmpty(validateTarget)) {
|
||||
return buildError(validateTarget);
|
||||
}
|
||||
}
|
||||
|
||||
// build and save the management data
|
||||
final ContinuousProfilingPolicyConfiguration configuration = ContinuousProfilingPolicyConfiguration.buildFromRequest(request);
|
||||
final String configurationJSON = GSON.toJson(configuration);
|
||||
final ContinuousProfilingPolicy policy = new ContinuousProfilingPolicy();
|
||||
policy.setServiceId(request.getServiceId());
|
||||
policy.setUuid(Hashing.sha512().hashString(configurationJSON, StandardCharsets.UTF_8).toString());
|
||||
policy.setConfigurationJson(configurationJSON);
|
||||
getPolicyDAO().savePolicy(policy);
|
||||
|
||||
return buildSaveSuccess();
|
||||
}
|
||||
|
||||
private String validateTargets(List<ContinuousProfilingPolicyTargetCreation> targets) {
|
||||
final HashSet<ContinuousProfilingTargetType> targetCache = new HashSet<>();
|
||||
for (ContinuousProfilingPolicyTargetCreation target : targets) {
|
||||
// same target type cannot have multiple
|
||||
final ContinuousProfilingTargetType targetType = target.getTargetType();
|
||||
if (targetCache.contains(targetType)) {
|
||||
return "contains multiple same target type: " + targetType;
|
||||
}
|
||||
targetCache.add(targetType);
|
||||
|
||||
final HashSet<ContinuousProfilingMonitorType> monitorTypeCache = new HashSet<>();
|
||||
for (ContinuousProfilingPolicyItemCreation item : target.getCheckItems()) {
|
||||
// save check type cannot have multiple in each target
|
||||
if (monitorTypeCache.contains(item.getType())) {
|
||||
return "contains multiple same monitor type " + item.getType() + " in " + targetType;
|
||||
}
|
||||
monitorTypeCache.add(item.getType());
|
||||
// validate each item
|
||||
String itemCheck = validatePolicyItem(item);
|
||||
if (StringUtil.isNotEmpty(itemCheck)) {
|
||||
return "check " + item.getType() + " in " + targetType + " error: " + itemCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String validatePolicyItem(ContinuousProfilingPolicyItemCreation item) {
|
||||
String timeWindowsValidate = validatePolicyItemWindows(item);
|
||||
if (StringUtil.isNotEmpty(timeWindowsValidate)) {
|
||||
return timeWindowsValidate;
|
||||
}
|
||||
try {
|
||||
switch (item.getType()) {
|
||||
case PROCESS_CPU:
|
||||
final int cpuPercent = Integer.parseInt(item.getThreshold());
|
||||
if (cpuPercent < 0 || cpuPercent > 100) {
|
||||
return "the process CPU percent should in [0-100]";
|
||||
}
|
||||
break;
|
||||
case PROCESS_THREAD_COUNT:
|
||||
final int threadCount = Integer.parseInt(item.getThreshold());
|
||||
if (threadCount < 0) {
|
||||
return "the process thread count must bigger than zero";
|
||||
}
|
||||
break;
|
||||
case SYSTEM_LOAD:
|
||||
final int systemLoad = Integer.parseInt(item.getThreshold());
|
||||
if (systemLoad < 0) {
|
||||
return "the system load must bigger than zero";
|
||||
}
|
||||
break;
|
||||
case HTTP_ERROR_RATE:
|
||||
final int httpErrorRate = Integer.parseInt(item.getThreshold());
|
||||
if (httpErrorRate < 0 || httpErrorRate > 100) {
|
||||
return "the HTTP error rate should in [0-100]";
|
||||
}
|
||||
break;
|
||||
case HTTP_AVG_RESPONSE_TIME:
|
||||
final int httpAvgResponseTime = Integer.parseInt(item.getThreshold());
|
||||
if (httpAvgResponseTime < 0) {
|
||||
return "the HTTP average response time must bigger than zero";
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return "parsing threshold error";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String validatePolicyItemWindows(ContinuousProfilingPolicyItemCreation item) {
|
||||
if (item.getPeriod() <= 0) {
|
||||
return "period must bigger than zero";
|
||||
}
|
||||
if (item.getCount() < 0) {
|
||||
return "count must bigger than zero";
|
||||
}
|
||||
if (item.getCount() > item.getPeriod()) {
|
||||
return "count must be small than period";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ContinuousProfilingSetResult buildError(String message) {
|
||||
return ContinuousProfilingSetResult.builder().status(false).errorReason(message).build();
|
||||
}
|
||||
|
||||
private ContinuousProfilingSetResult buildSaveSuccess() {
|
||||
return ContinuousProfilingSetResult.builder().status(true).build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicyConfiguration;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingPolicyItem;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingPolicyTarget;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ContinuousProfilingQueryService implements Service {
|
||||
private final ModuleManager moduleManager;
|
||||
|
||||
private IContinuousProfilingPolicyDAO policyDAO;
|
||||
|
||||
public IContinuousProfilingPolicyDAO getPolicyDAO() {
|
||||
if (policyDAO == null) {
|
||||
this.policyDAO = moduleManager.find(StorageModule.NAME)
|
||||
.provider().getService(IContinuousProfilingPolicyDAO.class);
|
||||
}
|
||||
return policyDAO;
|
||||
}
|
||||
|
||||
public List<ContinuousProfilingPolicyTarget> queryContinuousProfilingServiceTargets(String serviceId) throws IOException {
|
||||
final List<ContinuousProfilingPolicy> policies = getPolicyDAO().queryPolicies(Arrays.asList(serviceId));
|
||||
if (CollectionUtils.isEmpty(policies)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final ContinuousProfilingPolicy policy = policies.get(0);
|
||||
final ContinuousProfilingPolicyConfiguration configuration =
|
||||
ContinuousProfilingPolicyConfiguration.parseFromJSON(policy.getConfigurationJson());
|
||||
|
||||
return configuration.getTargetCheckers().entrySet().stream().map(targetEntry -> {
|
||||
final ContinuousProfilingTargetType type = targetEntry.getKey();
|
||||
final List<ContinuousProfilingPolicyItem> items = targetEntry.getValue().entrySet().stream().map(checker -> {
|
||||
final ContinuousProfilingPolicyItem result = new ContinuousProfilingPolicyItem();
|
||||
final ContinuousProfilingPolicyConfiguration.CheckItem item = checker.getValue();
|
||||
result.setType(checker.getKey());
|
||||
result.setThreshold(item.getThreshold());
|
||||
result.setPeriod(item.getPeriod());
|
||||
result.setCount(item.getCount());
|
||||
result.setUriList(item.getUriList());
|
||||
result.setUriRegex(item.getUriRegex());
|
||||
return result;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return ContinuousProfilingPolicyTarget.builder()
|
||||
.type(type)
|
||||
.checkItems(items)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous.storage;
|
||||
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingTriggeredMonitorType;
|
||||
import org.apache.skywalking.oap.server.core.UnexpectedException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum ContinuousProfilingMonitorType {
|
||||
|
||||
UNKNOWN(0, null),
|
||||
PROCESS_CPU(1, ContinuousProfilingTriggeredMonitorType.ProcessCPU),
|
||||
PROCESS_THREAD_COUNT(2, ContinuousProfilingTriggeredMonitorType.ProcessThreadCount),
|
||||
SYSTEM_LOAD(3, ContinuousProfilingTriggeredMonitorType.SystemLoad),
|
||||
HTTP_ERROR_RATE(4, ContinuousProfilingTriggeredMonitorType.HTTPErrorRate),
|
||||
HTTP_AVG_RESPONSE_TIME(5, ContinuousProfilingTriggeredMonitorType.HTTPAvgResponseTime);
|
||||
|
||||
private final int value;
|
||||
private final ContinuousProfilingTriggeredMonitorType causeType;
|
||||
private static final Map<Integer, ContinuousProfilingMonitorType> DICTIONARY = new HashMap<>();
|
||||
private static final Map<ContinuousProfilingTriggeredMonitorType, ContinuousProfilingMonitorType> CAUSE_DICTIONARY = new HashMap<>();
|
||||
|
||||
static {
|
||||
DICTIONARY.putAll(Arrays.stream(ContinuousProfilingMonitorType.values()).collect(Collectors.toMap(ContinuousProfilingMonitorType::value, Function.identity())));
|
||||
CAUSE_DICTIONARY.putAll(Arrays.stream(ContinuousProfilingMonitorType.values()).filter(s -> Objects.nonNull(s.causeType))
|
||||
.collect(Collectors.toMap(s -> s.causeType, Function.identity())));
|
||||
}
|
||||
|
||||
ContinuousProfilingMonitorType(int value, ContinuousProfilingTriggeredMonitorType causeType) {
|
||||
this.value = value;
|
||||
this.causeType = causeType;
|
||||
}
|
||||
|
||||
public static ContinuousProfilingMonitorType valueOf(int value) {
|
||||
ContinuousProfilingMonitorType type = DICTIONARY.get(value);
|
||||
if (type == null) {
|
||||
throw new UnexpectedException("Unknown ContinuousProfilingTargetType value");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static ContinuousProfilingMonitorType valueOf(ContinuousProfilingTriggeredMonitorType causeType) {
|
||||
ContinuousProfilingMonitorType type = CAUSE_DICTIONARY.get(causeType);
|
||||
if (type == null) {
|
||||
throw new UnexpectedException("Unknown ContinuousProfilingTargetType value");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous.storage;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Stream;
|
||||
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.ManagementStreamProcessor;
|
||||
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageID;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
|
||||
|
||||
import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.CONTINUOUS_PROFILING_POLICY;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ScopeDeclaration(id = CONTINUOUS_PROFILING_POLICY, name = "ContinuousProfilingPolicy")
|
||||
@Stream(name = ContinuousProfilingPolicy.INDEX_NAME, scopeId = CONTINUOUS_PROFILING_POLICY,
|
||||
builder = ContinuousProfilingPolicy.Builder.class, processor = ManagementStreamProcessor.class)
|
||||
@EqualsAndHashCode(of = {
|
||||
"serviceId"
|
||||
}, callSuper = false)
|
||||
public class ContinuousProfilingPolicy extends ManagementData {
|
||||
public static final String INDEX_NAME = "continuous_profiling_policy";
|
||||
public static final String SERVICE_ID = "service_id";
|
||||
public static final String UUID = "uuid";
|
||||
public static final String CONFIGURATION_JSON = "configuration_json";
|
||||
|
||||
@Column(name = SERVICE_ID)
|
||||
private String serviceId;
|
||||
@Column(name = CONFIGURATION_JSON, storageOnly = true, length = 5000)
|
||||
private String configurationJson;
|
||||
@Column(name = UUID)
|
||||
private String uuid;
|
||||
|
||||
@Override
|
||||
public StorageID id() {
|
||||
return new StorageID().append(SERVICE_ID, serviceId);
|
||||
}
|
||||
|
||||
public static class Builder implements StorageBuilder<ContinuousProfilingPolicy> {
|
||||
|
||||
@Override
|
||||
public ContinuousProfilingPolicy storage2Entity(Convert2Entity converter) {
|
||||
final ContinuousProfilingPolicy policy = new ContinuousProfilingPolicy();
|
||||
policy.setServiceId((String) converter.get(SERVICE_ID));
|
||||
policy.setUuid((String) converter.get(UUID));
|
||||
policy.setConfigurationJson((String) converter.get(CONFIGURATION_JSON));
|
||||
return policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entity2Storage(ContinuousProfilingPolicy entity, Convert2Storage converter) {
|
||||
converter.accept(SERVICE_ID, entity.getServiceId());
|
||||
converter.accept(UUID, entity.getUuid());
|
||||
converter.accept(CONFIGURATION_JSON, entity.getConfigurationJson());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous.storage;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyItemCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyTargetCreation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class ContinuousProfilingPolicyConfiguration {
|
||||
private static Gson GSON = new Gson();
|
||||
|
||||
// one target have multiple checkers
|
||||
private Map<ContinuousProfilingTargetType, Map<ContinuousProfilingMonitorType, CheckItem>> targetCheckers;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class CheckItem {
|
||||
private String threshold;
|
||||
private int period;
|
||||
private int count;
|
||||
private List<String> uriList;
|
||||
private String uriRegex;
|
||||
}
|
||||
|
||||
public String toJSON() {
|
||||
return GSON.toJson(this);
|
||||
}
|
||||
|
||||
public static ContinuousProfilingPolicyConfiguration buildFromRequest(ContinuousProfilingPolicyCreation request) {
|
||||
final ContinuousProfilingPolicyConfiguration data = new ContinuousProfilingPolicyConfiguration();
|
||||
for (ContinuousProfilingPolicyTargetCreation target : request.getTargets()) {
|
||||
final ContinuousProfilingTargetType targetType = target.getTargetType();
|
||||
Map<ContinuousProfilingMonitorType, CheckItem> items = data.targetCheckers.computeIfAbsent(targetType, k -> new HashMap<>());
|
||||
|
||||
for (ContinuousProfilingPolicyItemCreation itemRequest : target.getCheckItems()) {
|
||||
final CheckItem item = new CheckItem();
|
||||
item.setThreshold(itemRequest.getThreshold());
|
||||
item.setPeriod(itemRequest.getPeriod());
|
||||
item.setCount(itemRequest.getCount());
|
||||
item.setUriList(itemRequest.getUriList());
|
||||
item.setUriRegex(itemRequest.getUriRegex());
|
||||
items.put(itemRequest.getType(), item);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static ContinuousProfilingPolicyConfiguration parseFromJSON(String json) {
|
||||
return GSON.fromJson(json, ContinuousProfilingPolicyConfiguration.class);
|
||||
}
|
||||
|
||||
public ContinuousProfilingPolicyConfiguration() {
|
||||
this.targetCheckers = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.profiling.continuous.storage;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.UnexpectedException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum ContinuousProfilingTargetType {
|
||||
|
||||
UNKNOWN(0),
|
||||
ON_CPU(1),
|
||||
OFF_CPU(2),
|
||||
NETWORK(3);
|
||||
|
||||
private final int value;
|
||||
private static final Map<Integer, ContinuousProfilingTargetType> DICTIONARY = new HashMap<>();
|
||||
|
||||
static {
|
||||
DICTIONARY.putAll(Arrays.stream(ContinuousProfilingTargetType.values()).collect(Collectors.toMap(ContinuousProfilingTargetType::value, type -> type)));
|
||||
}
|
||||
|
||||
ContinuousProfilingTargetType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ContinuousProfilingTargetType valueOf(int value) {
|
||||
ContinuousProfilingTargetType type = DICTIONARY.get(value);
|
||||
if (type == null) {
|
||||
throw new UnexpectedException("Unknown ContinuousProfilingTargetType value");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,6 @@ import org.apache.skywalking.oap.server.core.query.input.EBPFNetworkSamplingRule
|
|||
import org.apache.skywalking.oap.server.core.query.input.EBPFProfilingNetworkTaskRequest;
|
||||
import org.apache.skywalking.oap.server.core.query.input.EBPFProfilingTaskFixedTimeCreationRequest;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFNetworkKeepProfilingResult;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskCreationResult;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||
|
|
@ -165,18 +164,23 @@ public class EBPFProfilingMutationService implements Service {
|
|||
}
|
||||
|
||||
public EBPFNetworkKeepProfilingResult keepEBPFNetworkProfiling(String taskId) throws IOException {
|
||||
final EBPFProfilingTask task = getProcessProfilingTaskDAO().queryById(taskId);
|
||||
final List<EBPFProfilingTaskRecord> tasks = getProcessProfilingTaskDAO().getTaskRecord(taskId);
|
||||
// task not exists
|
||||
if (task == null) {
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return buildKeepProfilingError("profiling task not exists");
|
||||
}
|
||||
// combine all tasks
|
||||
final EBPFProfilingTaskRecord task = tasks.get(0);
|
||||
for (int i = 1; i < tasks.size(); i++) {
|
||||
task.combine(tasks.get(i));
|
||||
}
|
||||
// target type not "NETWORK"
|
||||
if (!Objects.equals(task.getTargetType(), EBPFProfilingTargetType.NETWORK)) {
|
||||
return buildKeepProfilingError("current task is not a \"NETWORK\" task");
|
||||
}
|
||||
// task already finished
|
||||
final Calendar taskTime = Calendar.getInstance();
|
||||
taskTime.setTimeInMillis(task.getTaskStartTime());
|
||||
taskTime.setTimeInMillis(task.getStartTime());
|
||||
taskTime.add(Calendar.SECOND, (int) task.getFixedTriggerDuration());
|
||||
final Calendar now = Calendar.getInstance();
|
||||
final long sec = TimeUnit.MILLISECONDS.toSeconds(taskTime.getTimeInMillis() - now.getTimeInMillis());
|
||||
|
|
@ -189,12 +193,12 @@ public class EBPFProfilingMutationService implements Service {
|
|||
|
||||
// copy the task and extend the task time
|
||||
final EBPFProfilingTaskRecord record = new EBPFProfilingTaskRecord();
|
||||
record.setLogicalId(task.getTaskId());
|
||||
record.setLogicalId(task.getLogicalId());
|
||||
record.setServiceId(task.getServiceId());
|
||||
record.setProcessLabelsJson(Const.EMPTY_STRING);
|
||||
record.setInstanceId(task.getServiceInstanceId());
|
||||
record.setStartTime(task.getTaskStartTime());
|
||||
record.setTriggerType(task.getTriggerType().value());
|
||||
record.setInstanceId(task.getInstanceId());
|
||||
record.setStartTime(task.getStartTime());
|
||||
record.setTriggerType(task.getTriggerType());
|
||||
record.setFixedTriggerDuration(task.getFixedTriggerDuration() + NETWORK_PROFILING_DURATION);
|
||||
record.setTargetType(EBPFProfilingTargetType.NETWORK.value());
|
||||
record.setCreateTime(now.getTimeInMillis());
|
||||
|
|
@ -256,12 +260,12 @@ public class EBPFProfilingMutationService implements Service {
|
|||
}
|
||||
|
||||
// query exist processes
|
||||
final List<EBPFProfilingTask> tasks = getProcessProfilingTaskDAO().queryTasksByTargets(
|
||||
request.getServiceId(), null, Arrays.asList(request.getTargetType()), request.getStartTime(), 0);
|
||||
final List<EBPFProfilingTaskRecord> tasks = getProcessProfilingTaskDAO().queryTasksByTargets(
|
||||
request.getServiceId(), null, Arrays.asList(request.getTargetType()), EBPFProfilingTriggerType.FIXED_TIME, request.getStartTime(), 0);
|
||||
if (CollectionUtils.isNotEmpty(tasks)) {
|
||||
final EBPFProfilingTask mostRecentTask = tasks.stream()
|
||||
.min(Comparator.comparingLong(EBPFProfilingTask::getTaskStartTime)).get();
|
||||
if (mostRecentTask.getTaskStartTime() < calculateStartTime(request)) {
|
||||
final EBPFProfilingTaskRecord mostRecentTask = tasks.stream()
|
||||
.min(Comparator.comparingLong(EBPFProfilingTaskRecord::getStartTime)).get();
|
||||
if (mostRecentTask.getStartTime() < calculateStartTime(request)) {
|
||||
return "Task's time range overlaps with other tasks";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import org.apache.skywalking.oap.server.core.analysis.manual.process.ProcessTraf
|
|||
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.analyze.EBPFProfilingAnalyzer;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.enumeration.ProfilingSupportStatus;
|
||||
import org.apache.skywalking.oap.server.core.query.type.Attribute;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzation;
|
||||
|
|
@ -37,6 +39,8 @@ import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzeAggr
|
|||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzeTimeRange;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingSchedule;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskContinuousProfiling;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskPrepare;
|
||||
import org.apache.skywalking.oap.server.core.query.type.Process;
|
||||
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
|
||||
|
|
@ -57,11 +61,11 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -173,22 +177,46 @@ public class EBPFProfilingQueryService implements Service {
|
|||
return prepare;
|
||||
}
|
||||
|
||||
public List<EBPFProfilingTask> queryEBPFProfilingTasks(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targets) throws IOException {
|
||||
public List<EBPFProfilingTask> queryEBPFProfilingTasks(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targets, EBPFProfilingTriggerType triggerType) throws IOException {
|
||||
if (CollectionUtils.isEmpty(targets)) {
|
||||
targets = Arrays.asList(EBPFProfilingTargetType.values());
|
||||
}
|
||||
final List<EBPFProfilingTask> tasks = getTaskDAO().queryTasksByTargets(serviceId, serviceInstanceId, targets, 0, 0);
|
||||
final List<EBPFProfilingTaskRecord> tasks = getTaskDAO().queryTasksByTargets(serviceId, serviceInstanceId, targets, triggerType, 0, 0);
|
||||
// combine same id tasks
|
||||
final LinkedHashMap<String, EBPFProfilingTask> tmpMap = new LinkedHashMap<>();
|
||||
for (EBPFProfilingTask task : tasks) {
|
||||
final EBPFProfilingTask p = tmpMap.get(task.getTaskId());
|
||||
if (p == null) {
|
||||
tmpMap.put(task.getTaskId(), task);
|
||||
continue;
|
||||
}
|
||||
p.combine(task);
|
||||
final Map<String, EBPFProfilingTaskRecord> records = tasks.stream().collect(Collectors.toMap(EBPFProfilingTaskRecord::getLogicalId, Function.identity(), EBPFProfilingTaskRecord::combine));
|
||||
return records.values().stream().map(this::parseTask).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private EBPFProfilingTask parseTask(EBPFProfilingTaskRecord record) {
|
||||
final EBPFProfilingTask result = new EBPFProfilingTask();
|
||||
result.setTaskId(record.getLogicalId());
|
||||
result.setServiceId(record.getServiceId());
|
||||
result.setServiceName(IDManager.ServiceID.analysisId(record.getServiceId()).getName());
|
||||
if (StringUtil.isNotEmpty(record.getProcessLabelsJson())) {
|
||||
result.setProcessLabels(GSON.<List<String>>fromJson(record.getProcessLabelsJson(), ArrayList.class));
|
||||
} else {
|
||||
result.setProcessLabels(Collections.emptyList());
|
||||
}
|
||||
return new ArrayList<>(tmpMap.values());
|
||||
if (StringUtil.isNotEmpty(record.getInstanceId())) {
|
||||
result.setServiceInstanceId(record.getInstanceId());
|
||||
result.setServiceInstanceName(IDManager.ServiceInstanceID.analysisId(record.getInstanceId()).getName());
|
||||
}
|
||||
result.setTaskStartTime(record.getStartTime());
|
||||
result.setTriggerType(EBPFProfilingTriggerType.valueOf(record.getTriggerType()));
|
||||
result.setFixedTriggerDuration(record.getFixedTriggerDuration());
|
||||
result.setTargetType(EBPFProfilingTargetType.valueOf(record.getTargetType()));
|
||||
result.setCreateTime(record.getCreateTime());
|
||||
result.setLastUpdateTime(record.getLastUpdateTime());
|
||||
if (StringUtil.isNotEmpty(record.getExtensionConfigJson())) {
|
||||
result.setExtensionConfig(GSON.fromJson(record.getExtensionConfigJson(), EBPFProfilingTaskExtension.class));
|
||||
}
|
||||
if (StringUtil.isNotEmpty(record.getContinuousProfilingJson())) {
|
||||
final EBPFProfilingTaskContinuousProfiling continuousProfiling = GSON.fromJson(record.getContinuousProfilingJson(), EBPFProfilingTaskContinuousProfiling.class);
|
||||
result.setProcessId(continuousProfiling.getProcessId());
|
||||
result.setProcessName(continuousProfiling.getProcessName());
|
||||
result.setContinuousProfilingCauses(continuousProfiling.getCauses());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<EBPFProfilingSchedule> queryEBPFProfilingSchedules(String taskId) throws Exception {
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
package org.apache.skywalking.oap.server.core.profiling.ebpf.storage;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.UnexpectedException;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -30,29 +32,38 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
public enum EBPFProfilingTargetType {
|
||||
|
||||
UNKNOWN(0),
|
||||
UNKNOWN(0, null),
|
||||
|
||||
ON_CPU(1),
|
||||
ON_CPU(1, ContinuousProfilingTargetType.ON_CPU),
|
||||
|
||||
OFF_CPU(2),
|
||||
OFF_CPU(2, ContinuousProfilingTargetType.OFF_CPU),
|
||||
|
||||
NETWORK(3),
|
||||
NETWORK(3, ContinuousProfilingTargetType.NETWORK),
|
||||
;
|
||||
private final int value;
|
||||
private final ContinuousProfilingTargetType continuousProfilingTargetType;
|
||||
private static final Map<Integer, EBPFProfilingTargetType> DICTIONARY = new HashMap<>();
|
||||
private static final Map<ContinuousProfilingTargetType, EBPFProfilingTargetType> CONTINUOUS_PROFILING_TARGET_DICTIONARY = new HashMap<>();
|
||||
|
||||
static {
|
||||
Arrays.stream(EBPFProfilingTargetType.values()).collect(Collectors.toMap(EBPFProfilingTargetType::value, type -> type)).forEach(DICTIONARY::put);
|
||||
Arrays.stream(EBPFProfilingTargetType.values()).filter(s -> Objects.nonNull(s.getContinuousProfilingTargetType()))
|
||||
.collect(Collectors.toMap(EBPFProfilingTargetType::getContinuousProfilingTargetType, type -> type)).forEach(CONTINUOUS_PROFILING_TARGET_DICTIONARY::put);
|
||||
}
|
||||
|
||||
EBPFProfilingTargetType(int value) {
|
||||
EBPFProfilingTargetType(int value, ContinuousProfilingTargetType continuousProfilingTargetType) {
|
||||
this.value = value;
|
||||
this.continuousProfilingTargetType = continuousProfilingTargetType;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public ContinuousProfilingTargetType getContinuousProfilingTargetType() {
|
||||
return continuousProfilingTargetType;
|
||||
}
|
||||
|
||||
public static EBPFProfilingTargetType valueOf(int value) {
|
||||
EBPFProfilingTargetType type = DICTIONARY.get(value);
|
||||
if (type == null) {
|
||||
|
|
@ -60,4 +71,12 @@ public enum EBPFProfilingTargetType {
|
|||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static EBPFProfilingTargetType valueOf(ContinuousProfilingTargetType value) {
|
||||
EBPFProfilingTargetType type = CONTINUOUS_PROFILING_TARGET_DICTIONARY.get(value);
|
||||
if (type == null) {
|
||||
throw new UnexpectedException("Unknown ContinuousProfilingTargetType value: " + value);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
@ -55,9 +55,11 @@ public class EBPFProfilingTaskRecord extends NoneStream {
|
|||
public static final String CREATE_TIME = "create_time";
|
||||
public static final String LAST_UPDATE_TIME = "last_update_time";
|
||||
public static final String EXTENSION_CONFIG_JSON = "extension_config_json";
|
||||
public static final String CONTINUOUS_PROFILING_JSON = "continuous_profiling_json";
|
||||
|
||||
public static final int PROCESS_LABELS_JSON_MAX_LENGTH = 1000;
|
||||
public static final int EXTENSION_CONFIG_JSON_MAX_LENGTH = 1000;
|
||||
public static final int CONTINOUS_PROFILING_JSON_MAX_LENGTH = 1000;
|
||||
|
||||
@Column(name = LOGICAL_ID)
|
||||
private String logicalId;
|
||||
|
|
@ -82,6 +84,8 @@ public class EBPFProfilingTaskRecord extends NoneStream {
|
|||
private long lastUpdateTime;
|
||||
@Column(name = EXTENSION_CONFIG_JSON, length = EXTENSION_CONFIG_JSON_MAX_LENGTH, storageOnly = true)
|
||||
private String extensionConfigJson;
|
||||
@Column(name = CONTINUOUS_PROFILING_JSON, length = CONTINOUS_PROFILING_JSON_MAX_LENGTH, storageOnly = true)
|
||||
private String continuousProfilingJson;
|
||||
|
||||
@Override
|
||||
public StorageID id() {
|
||||
|
|
@ -108,6 +112,20 @@ public class EBPFProfilingTaskRecord extends NoneStream {
|
|||
.hash().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* combine the same task
|
||||
* @param task have same {@link #logicalId}
|
||||
*/
|
||||
public EBPFProfilingTaskRecord combine(EBPFProfilingTaskRecord task) {
|
||||
if (task.getFixedTriggerDuration() > this.getFixedTriggerDuration()) {
|
||||
this.setFixedTriggerDuration(task.getFixedTriggerDuration());
|
||||
}
|
||||
if (task.getLastUpdateTime() > this.getLastUpdateTime()) {
|
||||
this.setLastUpdateTime(task.getLastUpdateTime());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder implements StorageBuilder<EBPFProfilingTaskRecord> {
|
||||
|
||||
@Override
|
||||
|
|
@ -125,6 +143,7 @@ public class EBPFProfilingTaskRecord extends NoneStream {
|
|||
record.setLastUpdateTime(((Number) converter.get(LAST_UPDATE_TIME)).longValue());
|
||||
record.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
|
||||
record.setExtensionConfigJson((String) converter.get(EXTENSION_CONFIG_JSON));
|
||||
record.setContinuousProfilingJson((String) converter.get(CONTINUOUS_PROFILING_JSON));
|
||||
return record;
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +161,7 @@ public class EBPFProfilingTaskRecord extends NoneStream {
|
|||
converter.accept(LAST_UPDATE_TIME, storageData.getLastUpdateTime());
|
||||
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
|
||||
converter.accept(EXTENSION_CONFIG_JSON, storageData.getExtensionConfigJson());
|
||||
converter.accept(CONTINUOUS_PROFILING_JSON, storageData.getContinuousProfilingJson());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ public enum EBPFProfilingTriggerType {
|
|||
* Appoint the task start time
|
||||
*/
|
||||
FIXED_TIME(1),
|
||||
|
||||
/**
|
||||
* Trigger by the reach the continuous profiling policy
|
||||
*/
|
||||
CONTINUOUS_PROFILING(2)
|
||||
;
|
||||
private final int value;
|
||||
private static final Map<Integer, EBPFProfilingTriggerType> DICTIONARY = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.query.input;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ContinuousProfilingPolicyCreation {
|
||||
// service of the policy
|
||||
private String serviceId;
|
||||
// target of the policy
|
||||
private List<ContinuousProfilingPolicyTargetCreation> targets;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.input;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ContinuousProfilingPolicyItemCreation {
|
||||
// define the monitor type to collect metrics
|
||||
private ContinuousProfilingMonitorType type;
|
||||
// threshold of policy, which decide by the monitor type
|
||||
private String threshold;
|
||||
// the length of time to evaluate the metrics
|
||||
private int period;
|
||||
// how many times after the metrics match the threshold, will trigger profiling
|
||||
private int count;
|
||||
// the URI path/regex filter when monitor the HTTP related types
|
||||
private List<String> uriList;
|
||||
private String uriRegex;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.input;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ContinuousProfilingPolicyTargetCreation {
|
||||
// policy profiling target
|
||||
private ContinuousProfilingTargetType targetType;
|
||||
// target check thresholds
|
||||
private List<ContinuousProfilingPolicyItemCreation> checkItems;
|
||||
}
|
||||
|
|
@ -87,6 +87,8 @@ public class Entity {
|
|||
return Objects.nonNull(serviceName) && Objects.nonNull(serviceInstanceName) && Objects.nonNull(normal);
|
||||
case Endpoint:
|
||||
return Objects.nonNull(serviceName) && Objects.nonNull(endpointName) && Objects.nonNull(normal);
|
||||
case Process:
|
||||
return Objects.nonNull(serviceName) && Objects.nonNull(serviceInstanceName) && Objects.nonNull(processName) && Objects.nonNull(normal);
|
||||
case ServiceRelation:
|
||||
return Objects.nonNull(serviceName) && Objects.nonNull(destServiceName)
|
||||
&& Objects.nonNull(normal) && Objects.nonNull(destNormal);
|
||||
|
|
@ -123,6 +125,8 @@ public class Entity {
|
|||
IDManager.ServiceID.buildId(serviceName, normal), serviceInstanceName);
|
||||
case Endpoint:
|
||||
return IDManager.EndpointID.buildId(IDManager.ServiceID.buildId(serviceName, normal), endpointName);
|
||||
case Process:
|
||||
return IDManager.ProcessID.buildId(IDManager.ServiceInstanceID.buildId(IDManager.ServiceID.buildId(serviceName, normal), serviceInstanceName), processName);
|
||||
case ServiceRelation:
|
||||
return IDManager.ServiceID.buildRelationId(
|
||||
new IDManager.ServiceID.ServiceRelationDefine(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Continuous profiling policy threshold item
|
||||
*/
|
||||
@Data
|
||||
public class ContinuousProfilingPolicyItem {
|
||||
private ContinuousProfilingMonitorType type;
|
||||
private String threshold;
|
||||
private Integer period;
|
||||
private Integer count;
|
||||
private List<String> uriList;
|
||||
private String uriRegex;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ContinuousProfilingPolicyTarget {
|
||||
private ContinuousProfilingTargetType type;
|
||||
private List<ContinuousProfilingPolicyItem> checkItems;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ContinuousProfilingSetResult {
|
||||
private boolean status;
|
||||
private String errorReason;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Continuous profiling single value based cause
|
||||
*/
|
||||
@Data
|
||||
public class ContinuousProfilingSingleValueCause {
|
||||
private long threshold;
|
||||
private long current;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
|
||||
|
||||
/**
|
||||
* Continuous profiling task single trigger casus
|
||||
*/
|
||||
@Data
|
||||
public class ContinuousProfilingTriggeredCause {
|
||||
private ContinuousProfilingMonitorType type;
|
||||
private ContinuousProfilingSingleValueCause singleValue;
|
||||
private ContinuousProfilingURICause uri;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Continuous profiling task URI-based cause
|
||||
*/
|
||||
@Data
|
||||
public class ContinuousProfilingURICause {
|
||||
private String uriRegex;
|
||||
private String uriPath;
|
||||
private long threshold;
|
||||
private long current;
|
||||
}
|
||||
|
|
@ -33,6 +33,8 @@ public class EBPFProfilingTask {
|
|||
private String serviceInstanceId;
|
||||
private String serviceInstanceName;
|
||||
private List<String> processLabels;
|
||||
private String processId;
|
||||
private String processName;
|
||||
private long taskStartTime;
|
||||
private EBPFProfilingTriggerType triggerType;
|
||||
private long fixedTriggerDuration;
|
||||
|
|
@ -40,18 +42,6 @@ public class EBPFProfilingTask {
|
|||
private long createTime;
|
||||
private long lastUpdateTime;
|
||||
private EBPFProfilingTaskExtension extensionConfig;
|
||||
private List<ContinuousProfilingTriggeredCause> continuousProfilingCauses;
|
||||
|
||||
/**
|
||||
* combine the same task
|
||||
* @param task have same {@link #taskId}
|
||||
*/
|
||||
public EBPFProfilingTask combine(EBPFProfilingTask task) {
|
||||
if (task.getFixedTriggerDuration() > this.getFixedTriggerDuration()) {
|
||||
this.setFixedTriggerDuration(task.getFixedTriggerDuration());
|
||||
}
|
||||
if (task.getLastUpdateTime() > this.getLastUpdateTime()) {
|
||||
this.setLastUpdateTime(task.getLastUpdateTime());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Continuous profiling task configuration
|
||||
*/
|
||||
@Data
|
||||
public class EBPFProfilingTaskContinuousProfiling {
|
||||
private String processId;
|
||||
private String processName;
|
||||
|
||||
private List<ContinuousProfilingTriggeredCause> causes;
|
||||
|
||||
public EBPFProfilingTaskContinuousProfiling() {
|
||||
this.causes = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
|
@ -123,6 +123,8 @@ public class DefaultScopeDefine {
|
|||
public static final int SAMPLED_STATUS_4XX_TRACE = 66;
|
||||
public static final int SAMPLED_STATUS_5XX_TRACE = 67;
|
||||
|
||||
public static final int CONTINUOUS_PROFILING_POLICY = 68;
|
||||
|
||||
/**
|
||||
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@ import org.apache.skywalking.oap.server.core.query.enumeration.ProfilingSupportS
|
|||
import java.util.List;
|
||||
|
||||
import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.PROCESS;
|
||||
import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.PROCESS_CATALOG_NAME;
|
||||
|
||||
@ScopeDeclaration(id = PROCESS, name = "Process")
|
||||
@ScopeDeclaration(id = PROCESS, name = "Process", catalog = PROCESS_CATALOG_NAME)
|
||||
@ScopeDefaultColumn.VirtualColumnDefinition(fieldName = "entityId", columnName = "entity_id", isID = true, type = String.class)
|
||||
public class Process extends Source {
|
||||
private volatile String entityId;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.core.storage;
|
|||
|
||||
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IServiceLabelDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.trace.IProfileTaskQueryDAO;
|
||||
|
|
@ -79,6 +80,7 @@ public class StorageModule extends ModuleDefine {
|
|||
IEBPFProfilingTaskDAO.class,
|
||||
IEBPFProfilingScheduleDAO.class,
|
||||
IEBPFProfilingDataDAO.class,
|
||||
IContinuousProfilingPolicyDAO.class,
|
||||
IServiceLabelDAO.class,
|
||||
ITagAutoCompleteQueryDAO.class,
|
||||
IZipkinQueryDAO.class,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.profiling.continuous;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.storage.DAO;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface IContinuousProfilingPolicyDAO extends DAO {
|
||||
|
||||
/**
|
||||
* save the policy, insert if not absent
|
||||
*/
|
||||
void savePolicy(ContinuousProfilingPolicy policy) throws IOException;
|
||||
|
||||
/**
|
||||
* query policies from services
|
||||
*/
|
||||
List<ContinuousProfilingPolicy> queryPolicies(List<String> serviceIdList) throws IOException;
|
||||
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ package org.apache.skywalking.oap.server.core.storage.profiling.ebpf;
|
|||
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.storage.DAO;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -35,21 +35,21 @@ public interface IEBPFProfilingTaskDAO extends DAO {
|
|||
* Query profiling task through service id list
|
||||
* @param serviceIdList cannot be empty
|
||||
*/
|
||||
List<EBPFProfilingTask> queryTasksByServices(List<String> serviceIdList,
|
||||
List<EBPFProfilingTaskRecord> queryTasksByServices(List<String> serviceIdList, EBPFProfilingTriggerType triggerType,
|
||||
long taskStartTime, long latestUpdateTime) throws IOException;
|
||||
|
||||
/**
|
||||
* Query profiling task through target types
|
||||
* @param targetTypes cannot be empty
|
||||
*/
|
||||
List<EBPFProfilingTask> queryTasksByTargets(String serviceId, String serviceInstanceId,
|
||||
List<EBPFProfilingTaskRecord> queryTasksByTargets(String serviceId, String serviceInstanceId,
|
||||
List<EBPFProfilingTargetType> targetTypes,
|
||||
EBPFProfilingTriggerType triggerType,
|
||||
long taskStartTime, long latestUpdateTime) throws IOException;
|
||||
|
||||
/**
|
||||
* Query profiling task
|
||||
* Query profiling task by logical ID
|
||||
* @param id {@link EBPFProfilingTaskRecord#getLogicalId()}
|
||||
* @return use {@link EBPFProfilingTask#combine(EBPFProfilingTask)} to combine all task result
|
||||
*/
|
||||
EBPFProfilingTask queryById(String id) throws IOException;
|
||||
List<EBPFProfilingTaskRecord> getTaskRecord(String id) throws IOException;
|
||||
}
|
||||
|
|
@ -26,6 +26,6 @@ public class CoreModuleTest {
|
|||
public void testOpenServiceList() {
|
||||
CoreModule coreModule = new CoreModule();
|
||||
|
||||
Assertions.assertEquals(38, coreModule.services().length);
|
||||
Assertions.assertEquals(40, coreModule.services().length);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import java.util.Collections;
|
|||
import org.apache.skywalking.oap.query.graphql.resolver.AggregationQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.AlarmQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.BrowserLogQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.ContinuousProfilingMutation;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.ContinuousProfilingQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.EBPFProcessProfilingMutation;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.EBPFProcessProfilingQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.EventQuery;
|
||||
|
|
@ -132,6 +134,8 @@ public class GraphQLQueryProvider extends ModuleProvider {
|
|||
.resolvers(metadataQueryV2)
|
||||
.file("query-protocol/ebpf-profiling.graphqls")
|
||||
.resolvers(new EBPFProcessProfilingQuery(getManager()), new EBPFProcessProfilingMutation(getManager()))
|
||||
.file("query-protocol/continuous-profiling.graphqls")
|
||||
.resolvers(new ContinuousProfilingQuery(getManager()), new ContinuousProfilingMutation(getManager()))
|
||||
.file("query-protocol/record.graphqls")
|
||||
.resolvers(new RecordsQuery(getManager()));
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.query.graphql.resolver;
|
||||
|
||||
import graphql.kickstart.tools.GraphQLMutationResolver;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingMutationService;
|
||||
import org.apache.skywalking.oap.server.core.query.input.ContinuousProfilingPolicyCreation;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingSetResult;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ContinuousProfilingMutation implements GraphQLMutationResolver {
|
||||
|
||||
private final ModuleManager moduleManager;
|
||||
private ContinuousProfilingMutationService mutationService;
|
||||
|
||||
public ContinuousProfilingMutation(ModuleManager moduleManager) {
|
||||
this.moduleManager = moduleManager;
|
||||
}
|
||||
|
||||
private ContinuousProfilingMutationService getMutationService() {
|
||||
if (mutationService == null) {
|
||||
this.mutationService = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(ContinuousProfilingMutationService.class);
|
||||
}
|
||||
return mutationService;
|
||||
}
|
||||
|
||||
public ContinuousProfilingSetResult setContinuousProfilingPolicy(ContinuousProfilingPolicyCreation request) throws IOException {
|
||||
return getMutationService().setContinuousProfilingPolicy(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.query.graphql.resolver;
|
||||
|
||||
import graphql.kickstart.tools.GraphQLQueryResolver;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.ContinuousProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingPolicyTarget;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class ContinuousProfilingQuery implements GraphQLQueryResolver {
|
||||
|
||||
private final ModuleManager moduleManager;
|
||||
private ContinuousProfilingQueryService queryService;
|
||||
|
||||
public ContinuousProfilingQuery(ModuleManager moduleManager) {
|
||||
this.moduleManager = moduleManager;
|
||||
}
|
||||
|
||||
private ContinuousProfilingQueryService getQueryService() {
|
||||
if (queryService == null) {
|
||||
queryService = this.moduleManager.find(CoreModule.NAME)
|
||||
.provider().getService(ContinuousProfilingQueryService.class);
|
||||
}
|
||||
return queryService;
|
||||
}
|
||||
|
||||
public List<ContinuousProfilingPolicyTarget> queryContinuousProfilingServiceTargets(String serviceId) throws IOException {
|
||||
return getQueryService().queryContinuousProfilingServiceTargets(serviceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import graphql.kickstart.tools.GraphQLQueryResolver;
|
|||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.EBPFProfilingQueryService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzation;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzeAggregateType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingAnalyzeTimeRange;
|
||||
|
|
@ -59,11 +60,14 @@ public class EBPFProcessProfilingQuery implements GraphQLQueryResolver {
|
|||
return getQueryService().queryPrepareCreateEBPFProfilingTaskData(serviceId);
|
||||
}
|
||||
|
||||
public List<EBPFProfilingTask> queryEBPFProfilingTasks(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targets) throws IOException {
|
||||
public List<EBPFProfilingTask> queryEBPFProfilingTasks(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targets, EBPFProfilingTriggerType triggerType) throws IOException {
|
||||
if (StringUtil.isEmpty(serviceId) && StringUtil.isEmpty(serviceInstanceId)) {
|
||||
throw new IllegalArgumentException("please provide the service id or instance id");
|
||||
}
|
||||
return getQueryService().queryEBPFProfilingTasks(serviceId, serviceInstanceId, targets);
|
||||
if (triggerType == null) {
|
||||
triggerType = EBPFProfilingTriggerType.FIXED_TIME;
|
||||
}
|
||||
return getQueryService().queryEBPFProfilingTasks(serviceId, serviceInstanceId, targets, triggerType);
|
||||
}
|
||||
|
||||
public List<EBPFProfilingSchedule> queryEBPFProfilingSchedules(String taskId) throws Exception {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 450328c6445d4dc50a868a0b797a14755f1d82cc
|
||||
Subproject commit 4749946962b9c685111876d1abe8c745d3cf3253
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.receiver.ebpf.provider;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||
|
||||
@Getter
|
||||
public class EBPFReceiverModuleConfig extends ModuleConfig {
|
||||
|
||||
/**
|
||||
* The continuous profiling policy cache time, Unit is second. Default value is 60 seconds.
|
||||
*/
|
||||
@Setter
|
||||
private int continuousPolicyCacheTimeout = 60;
|
||||
}
|
||||
|
|
@ -25,12 +25,15 @@ import org.apache.skywalking.oap.server.library.module.ModuleProvider;
|
|||
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
|
||||
import org.apache.skywalking.oap.server.receiver.ebpf.module.EBPFReceiverModule;
|
||||
import org.apache.skywalking.oap.server.receiver.ebpf.provider.handler.ContinuousProfilingServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.ebpf.provider.handler.EBPFProcessServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.ebpf.provider.handler.EBPFProfilingServiceHandler;
|
||||
import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule;
|
||||
|
||||
public class EBPFReceiverProvider extends ModuleProvider {
|
||||
|
||||
private EBPFReceiverModuleConfig config;
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "default";
|
||||
|
|
@ -42,8 +45,18 @@ public class EBPFReceiverProvider extends ModuleProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ConfigCreator newConfigCreator() {
|
||||
return null;
|
||||
public ConfigCreator<EBPFReceiverModuleConfig> newConfigCreator() {
|
||||
return new ConfigCreator<EBPFReceiverModuleConfig>() {
|
||||
@Override
|
||||
public Class<EBPFReceiverModuleConfig> type() {
|
||||
return EBPFReceiverModuleConfig.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialized(EBPFReceiverModuleConfig initialized) {
|
||||
config = initialized;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -57,6 +70,7 @@ public class EBPFReceiverProvider extends ModuleProvider {
|
|||
.getService(GRPCHandlerRegister.class);
|
||||
grpcHandlerRegister.addHandler(new EBPFProcessServiceHandler(getManager()));
|
||||
grpcHandlerRegister.addHandler(new EBPFProfilingServiceHandler(getManager()));
|
||||
grpcHandlerRegister.addHandler(new ContinuousProfilingServiceHandler(getManager(), this.config));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* 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.receiver.ebpf.provider.handler;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.gson.Gson;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.apm.network.common.v3.Commands;
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingCause;
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingPolicyQuery;
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingReport;
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingServiceGrpc;
|
||||
import org.apache.skywalking.apm.network.ebpf.profiling.v3.ContinuousProfilingServicePolicyQuery;
|
||||
import org.apache.skywalking.oap.server.core.Const;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
|
||||
import org.apache.skywalking.oap.server.core.command.CommandService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.input.EBPFNetworkDataCollectingSettings;
|
||||
import org.apache.skywalking.oap.server.core.query.input.EBPFNetworkSamplingRule;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingSingleValueCause;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingTriggeredCause;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ContinuousProfilingURICause;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskContinuousProfiling;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.ContinuousProfilingPolicyCommand;
|
||||
import org.apache.skywalking.oap.server.receiver.ebpf.provider.EBPFReceiverModuleConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class ContinuousProfilingServiceHandler extends ContinuousProfilingServiceGrpc.ContinuousProfilingServiceImplBase implements GRPCHandler {
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private IContinuousProfilingPolicyDAO policyDAO;
|
||||
private final CommandService commandService;
|
||||
private final Cache<String, PolicyWrapper> policyCache;
|
||||
|
||||
public ContinuousProfilingServiceHandler(ModuleManager moduleManager, EBPFReceiverModuleConfig config) {
|
||||
this.policyDAO = moduleManager.find(StorageModule.NAME).provider().getService(IContinuousProfilingPolicyDAO.class);
|
||||
this.commandService = moduleManager.find(CoreModule.NAME).provider().getService(CommandService.class);
|
||||
this.policyCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(config.getContinuousPolicyCacheTimeout(), TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPolicies(ContinuousProfilingPolicyQuery request, StreamObserver<Commands> responseObserver) {
|
||||
final Map<String, String> policiesQuery = request.getPoliciesList().stream()
|
||||
.collect(Collectors.toMap(s -> IDManager.ServiceID.buildId(s.getServiceName(), true), ContinuousProfilingServicePolicyQuery::getUuid, (s1, s2) -> s1));
|
||||
if (CollectionUtils.isEmpty(policiesQuery)) {
|
||||
responseObserver.onNext(Commands.newBuilder().build());
|
||||
responseObserver.onCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final List<String> serviceIdList = new ArrayList<>(policiesQuery.keySet());
|
||||
final HashMap<String, ContinuousProfilingPolicy> policiesInDB = new HashMap<>();
|
||||
|
||||
// query from the cache first
|
||||
for (ListIterator<String> serviceIdIt = serviceIdList.listIterator(); serviceIdIt.hasNext(); ) {
|
||||
final String serviceId = serviceIdIt.next();
|
||||
final PolicyWrapper wrapper = this.policyCache.getIfPresent(serviceId);
|
||||
if (wrapper == null) {
|
||||
continue;
|
||||
}
|
||||
serviceIdIt.remove();
|
||||
|
||||
if (wrapper.policy != null) {
|
||||
policiesInDB.put(serviceId, wrapper.policy);
|
||||
}
|
||||
}
|
||||
|
||||
// query the policies which not in the cache
|
||||
final List<ContinuousProfilingPolicy> queriedFromDB = policyDAO.queryPolicies(serviceIdList);
|
||||
for (ContinuousProfilingPolicy dbPolicy : queriedFromDB) {
|
||||
policiesInDB.put(dbPolicy.getServiceId(), dbPolicy);
|
||||
this.policyCache.put(dbPolicy.getServiceId(), new PolicyWrapper(dbPolicy));
|
||||
serviceIdList.remove(dbPolicy.getServiceId());
|
||||
}
|
||||
|
||||
// Also add the cache if the service haven't policy
|
||||
for (String serviceId : serviceIdList) {
|
||||
this.policyCache.put(serviceId, new PolicyWrapper(null));
|
||||
}
|
||||
|
||||
final ArrayList<ContinuousProfilingPolicy> updatePolicies = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : policiesQuery.entrySet()) {
|
||||
final String serviceId = entry.getKey();
|
||||
|
||||
final ContinuousProfilingPolicy policyInDB = policiesInDB.get(serviceId);
|
||||
// policy not exist in DB or uuid not same
|
||||
// needs to send commands to downstream
|
||||
if (policyInDB == null && StringUtil.isNotEmpty(entry.getValue())) {
|
||||
final ContinuousProfilingPolicy emptyPolicy = new ContinuousProfilingPolicy();
|
||||
emptyPolicy.setServiceId(entry.getKey());
|
||||
emptyPolicy.setUuid("");
|
||||
updatePolicies.add(emptyPolicy);
|
||||
} else if (policyInDB != null && !Objects.equals(policyInDB.getUuid(), entry.getValue())) {
|
||||
updatePolicies.add(policyInDB);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(updatePolicies)) {
|
||||
sendEmptyCommands(responseObserver);
|
||||
return;
|
||||
}
|
||||
|
||||
final ContinuousProfilingPolicyCommand command = commandService.newContinuousProfilingServicePolicyCommand(updatePolicies);
|
||||
final Commands.Builder builder = Commands.newBuilder();
|
||||
builder.addCommands(command.serialize());
|
||||
responseObserver.onNext(builder.build());
|
||||
responseObserver.onCompleted();
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
log.warn("query continuous profiling service policies failure", e);
|
||||
}
|
||||
sendEmptyCommands(responseObserver);
|
||||
}
|
||||
|
||||
private void sendEmptyCommands(StreamObserver<Commands> responseObserver) {
|
||||
responseObserver.onNext(Commands.newBuilder().build());
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportProfilingTask(ContinuousProfilingReport request, StreamObserver<Commands> responseObserver) {
|
||||
// set up the task record
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final EBPFProfilingTaskRecord task = new EBPFProfilingTaskRecord();
|
||||
final String serviceId = IDManager.ServiceID.buildId(request.getServiceName(), true);
|
||||
final String instanceId = IDManager.ServiceInstanceID.buildId(serviceId, request.getInstanceName());
|
||||
final String processId = IDManager.ProcessID.buildId(instanceId, request.getProcessName());
|
||||
|
||||
task.setServiceId(serviceId);
|
||||
task.setProcessLabelsJson(Const.EMPTY_STRING);
|
||||
task.setInstanceId(instanceId);
|
||||
task.setStartTime(currentTime);
|
||||
task.setTriggerType(EBPFProfilingTriggerType.CONTINUOUS_PROFILING.value());
|
||||
task.setFixedTriggerDuration(request.getDuration());
|
||||
task.setCreateTime(currentTime);
|
||||
task.setLastUpdateTime(currentTime);
|
||||
|
||||
final EBPFProfilingTaskContinuousProfiling continuousProfiling = new EBPFProfilingTaskContinuousProfiling();
|
||||
continuousProfiling.setProcessId(processId);
|
||||
continuousProfiling.setProcessName(request.getProcessName());
|
||||
continuousProfiling.setCauses(request.getCausesList().stream().map(this::parseTaskCause).collect(Collectors.toList()));
|
||||
settingTargetTask(request, task, continuousProfiling);
|
||||
task.setContinuousProfilingJson(GSON.toJson(continuousProfiling));
|
||||
task.generateLogicalId();
|
||||
|
||||
// save the profiling task
|
||||
NoneStreamProcessor.getInstance().in(task);
|
||||
|
||||
final Commands.Builder builder = Commands.newBuilder();
|
||||
builder.addCommands(commandService.newContinuousProfilingReportCommand(task.getLogicalId()).serialize());
|
||||
responseObserver.onNext(builder.build());
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
private void settingTargetTask(ContinuousProfilingReport request, EBPFProfilingTaskRecord task, EBPFProfilingTaskContinuousProfiling continuousProfiling) {
|
||||
switch (request.getTargetTaskCase()) {
|
||||
case ONCPU:
|
||||
task.setTargetType(EBPFProfilingTargetType.ON_CPU.value());
|
||||
break;
|
||||
case OFFCPU:
|
||||
task.setTargetType(EBPFProfilingTargetType.OFF_CPU.value());
|
||||
break;
|
||||
case NETWORK:
|
||||
task.setTargetType(EBPFProfilingTargetType.NETWORK.value());
|
||||
final EBPFProfilingTaskExtension networkExtension = new EBPFProfilingTaskExtension();
|
||||
networkExtension.setNetworkSamplings(request.getNetwork().getSamplingURIRegexesList().stream().map(uri -> {
|
||||
final EBPFNetworkSamplingRule rule = new EBPFNetworkSamplingRule();
|
||||
rule.setMinDuration(0);
|
||||
rule.setWhen4xx(true);
|
||||
rule.setWhen5xx(true);
|
||||
final EBPFNetworkDataCollectingSettings setting = new EBPFNetworkDataCollectingSettings();
|
||||
setting.setRequireCompleteRequest(true);
|
||||
setting.setRequireCompleteResponse(true);
|
||||
rule.setSettings(setting);
|
||||
return rule;
|
||||
}).collect(Collectors.toList()));
|
||||
task.setExtensionConfigJson(GSON.toJson(networkExtension));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("the continuous profiling task type cannot recognized");
|
||||
}
|
||||
}
|
||||
|
||||
private ContinuousProfilingTriggeredCause parseTaskCause(ContinuousProfilingCause cause) {
|
||||
final ContinuousProfilingTriggeredCause result = new ContinuousProfilingTriggeredCause();
|
||||
result.setType(ContinuousProfilingMonitorType.valueOf(cause.getType()));
|
||||
switch (cause.getCauseCase()) {
|
||||
case SINGLEVALUE:
|
||||
final ContinuousProfilingSingleValueCause singleValue = new ContinuousProfilingSingleValueCause();
|
||||
singleValue.setThreshold(thresholdToLong(cause.getSingleValue().getThreshold()));
|
||||
singleValue.setCurrent(thresholdToLong(cause.getSingleValue().getCurrent()));
|
||||
result.setSingleValue(singleValue);
|
||||
break;
|
||||
case URI:
|
||||
final ContinuousProfilingURICause uriCause = new ContinuousProfilingURICause();
|
||||
switch (cause.getUri().getUriCase()) {
|
||||
case PATH:
|
||||
uriCause.setUriPath(cause.getUri().getPath());
|
||||
break;
|
||||
case REGEX:
|
||||
uriCause.setUriRegex(cause.getUri().getRegex());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("the uri case not set");
|
||||
}
|
||||
uriCause.setThreshold(thresholdToLong(cause.getUri().getThreshold()));
|
||||
uriCause.setCurrent(thresholdToLong(cause.getUri().getCurrent()));
|
||||
result.setUri(uriCause);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private long thresholdToLong(double val) {
|
||||
return (long) (val * 100);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class PolicyWrapper {
|
||||
final ContinuousProfilingPolicy policy;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.skywalking.oap.server.receiver.ebpf.provider.handler;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.Gson;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import io.vavr.Tuple;
|
||||
|
|
@ -35,8 +36,9 @@ import org.apache.skywalking.oap.server.core.CoreModule;
|
|||
import org.apache.skywalking.oap.server.core.command.CommandService;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingStackType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.enumeration.ProfilingSupportStatus;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.Process;
|
||||
import org.apache.skywalking.oap.server.core.source.EBPFProfilingData;
|
||||
import org.apache.skywalking.oap.server.core.source.EBPFProcessProfilingSchedule;
|
||||
|
|
@ -47,6 +49,7 @@ import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
|
|||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
import org.apache.skywalking.oap.server.network.trace.component.command.EBPFProfilingTaskCommand;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -64,6 +67,7 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
@Slf4j
|
||||
public class EBPFProfilingServiceHandler extends EBPFProfilingServiceGrpc.EBPFProfilingServiceImplBase implements GRPCHandler {
|
||||
private static final Gson GSON = new Gson();
|
||||
public static final List<EBPFProfilingStackType> COMMON_STACK_TYPE_ORDER = Arrays.asList(
|
||||
EBPFProfilingStackType.KERNEL_SPACE, EBPFProfilingStackType.USER_SPACE);
|
||||
|
||||
|
|
@ -94,10 +98,10 @@ public class EBPFProfilingServiceHandler extends EBPFProfilingServiceGrpc.EBPFPr
|
|||
|
||||
// fetch tasks from process id list
|
||||
final List<String> serviceIdList = processes.stream().map(Process::getServiceId).distinct().collect(Collectors.toList());
|
||||
final List<EBPFProfilingTask> tasks = taskDAO.queryTasksByServices(serviceIdList, 0, latestUpdateTime);
|
||||
final List<EBPFProfilingTaskRecord> tasks = taskDAO.queryTasksByServices(serviceIdList, EBPFProfilingTriggerType.FIXED_TIME, 0, latestUpdateTime);
|
||||
|
||||
final Commands.Builder builder = Commands.newBuilder();
|
||||
tasks.stream().collect(Collectors.toMap(EBPFProfilingTask::getTaskId, Function.identity(), EBPFProfilingTask::combine))
|
||||
tasks.stream().collect(Collectors.toMap(EBPFProfilingTaskRecord::getLogicalId, Function.identity(), EBPFProfilingTaskRecord::combine))
|
||||
.values().stream().flatMap(t -> this.buildProfilingCommands(t, processes).stream())
|
||||
.map(EBPFProfilingTaskCommand::serialize).forEach(builder::addCommands);
|
||||
responseObserver.onNext(builder.build());
|
||||
|
|
@ -110,9 +114,9 @@ public class EBPFProfilingServiceHandler extends EBPFProfilingServiceGrpc.EBPFPr
|
|||
responseObserver.onCompleted();
|
||||
}
|
||||
|
||||
private List<EBPFProfilingTaskCommand> buildProfilingCommands(EBPFProfilingTask task, List<Process> processes) {
|
||||
if (EBPFProfilingTargetType.NETWORK.equals(task.getTargetType())) {
|
||||
final List<String> processIdList = processes.stream().filter(p -> Objects.equals(p.getInstanceId(), task.getServiceInstanceId())).map(Process::getId).collect(Collectors.toList());
|
||||
private List<EBPFProfilingTaskCommand> buildProfilingCommands(EBPFProfilingTaskRecord task, List<Process> processes) {
|
||||
if (EBPFProfilingTargetType.NETWORK.value() == task.getTargetType()) {
|
||||
final List<String> processIdList = processes.stream().filter(p -> Objects.equals(p.getInstanceId(), task.getInstanceId())).map(Process::getId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(processIdList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -127,8 +131,12 @@ public class EBPFProfilingServiceHandler extends EBPFProfilingServiceGrpc.EBPFPr
|
|||
}
|
||||
|
||||
// If the task doesn't require a label or the process match all labels in task
|
||||
if (CollectionUtils.isEmpty(task.getProcessLabels())
|
||||
|| process.getLabels().containsAll(task.getProcessLabels())) {
|
||||
List<String> processLabels = Collections.emptyList();
|
||||
if (StringUtil.isNotEmpty(task.getProcessLabelsJson())) {
|
||||
processLabels = GSON.<List<String>>fromJson(task.getProcessLabelsJson(), ArrayList.class);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(processLabels)
|
||||
|| process.getLabels().containsAll(processLabels)) {
|
||||
commands.add(commandService.newEBPFProfilingTaskCommand(task, Collections.singletonList(process.getId())));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ agent-analyzer:
|
|||
# Nginx and Envoy agents can't get the real remote address.
|
||||
# Exit spans with the component in the list would not generate the client-side instance relation metrics.
|
||||
noUpstreamRealAddressAgents: ${SW_NO_UPSTREAM_REAL_ADDRESS:6000,9000}
|
||||
meterAnalyzerActiveFiles: ${SW_METER_ANALYZER_ACTIVE_FILES:datasource,threadpool,satellite,go-runtime,python-runtime} # Which files could be meter analyzed, files split by ","
|
||||
meterAnalyzerActiveFiles: ${SW_METER_ANALYZER_ACTIVE_FILES:datasource,threadpool,satellite,go-runtime,python-runtime,continuous-profiling} # Which files could be meter analyzed, files split by ","
|
||||
slowCacheReadThreshold: ${SW_SLOW_CACHE_SLOW_READ_THRESHOLD:default:20,redis:10} # The slow cache write operation thresholds. Unit ms.
|
||||
slowCacheWriteThreshold: ${SW_SLOW_CACHE_SLOW_WRITE_THRESHOLD:default:20,redis:10} # The slow cache write operation thresholds. Unit ms.
|
||||
|
||||
|
|
@ -527,6 +527,8 @@ receiver-event:
|
|||
receiver-ebpf:
|
||||
selector: ${SW_RECEIVER_EBPF:default}
|
||||
default:
|
||||
# The continuous profiling policy cache time, Unit is second.
|
||||
continuousPolicyCacheTimeout: ${SW_CONTINUOUS_POLICY_CACHE_TIMEOUT:60}
|
||||
|
||||
receiver-telegraf:
|
||||
selector: ${SW_RECEIVER_TELEGRAF:default}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
# 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.
|
||||
|
||||
expSuffix: process(['service'], ['instance'], ['process_name'], 'layer')
|
||||
metricPrefix: continuous_profiling
|
||||
metricsRules:
|
||||
- name: process_cpu
|
||||
exp: rover_con_p_process_cpu.avg(["service", "instance", "process_name", "layer"]).multiply(10000)
|
||||
- name: process_thread_count
|
||||
exp: rover_con_p_process_thread_count.avg(["service", "instance", "process_name", "layer"])
|
||||
- name: system_load
|
||||
exp: rover_con_p_system_load.avg(["service", "instance", "process_name", "layer"]).multiply(100)
|
||||
- name: http_error_rate
|
||||
exp: rover_con_p_http_error_rate.avg(["service", "instance", "process_name", "layer", "uri"]).multiply(100)
|
||||
- name: http_avg_response_time
|
||||
exp: rover_con_p_http_avg_response_time.avg(["service", "instance", "process_name", "layer", "uri"])
|
||||
|
|
@ -30,6 +30,7 @@ import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasD
|
|||
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
|
||||
import org.apache.skywalking.oap.server.core.storage.model.ModelInstaller;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingDataDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
|
|
@ -64,6 +65,7 @@ import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDB
|
|||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBTopologyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBAlarmQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBBrowserLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBEBPFProfilingDataDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.BanyanDBHistoryDeleteDAO;
|
||||
|
|
@ -149,6 +151,7 @@ public class BanyanDBStorageProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(IEBPFProfilingDataDAO.class, new BanyanDBEBPFProfilingDataDAO(client));
|
||||
this.registerServiceImplementation(
|
||||
IEBPFProfilingScheduleDAO.class, new BanyanDBEBPFProfilingScheduleQueryDAO(client));
|
||||
this.registerServiceImplementation(IContinuousProfilingPolicyDAO.class, new BanyanDBContinuousProfilingPolicyDAO(client));
|
||||
|
||||
this.registerServiceImplementation(IServiceLabelDAO.class, new BanyanDBServiceLabelDAO(client));
|
||||
this.registerServiceImplementation(ITagAutoCompleteQueryDAO.class, new BanyanDBTagAutocompleteQueryDAO(client));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.banyandb.stream;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.banyandb.v1.client.TagAndValue;
|
||||
import org.apache.skywalking.banyandb.v1.client.metadata.Property;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBStorageClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class BanyanDBContinuousProfilingPolicyDAO extends AbstractBanyanDBDAO implements IContinuousProfilingPolicyDAO {
|
||||
private static final String GROUP = "sw";
|
||||
|
||||
public BanyanDBContinuousProfilingPolicyDAO(BanyanDBStorageClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePolicy(ContinuousProfilingPolicy policy) throws IOException {
|
||||
try {
|
||||
this.getClient().define(applyAll(policy));
|
||||
} catch (IOException e) {
|
||||
log.error("fail to save policy", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Property applyAll(ContinuousProfilingPolicy policy) {
|
||||
return Property.create(GROUP, ContinuousProfilingPolicy.INDEX_NAME, policy.id().build())
|
||||
.addTag(TagAndValue.newStringTag(ContinuousProfilingPolicy.UUID, policy.getUuid()))
|
||||
.addTag(TagAndValue.newStringTag(ContinuousProfilingPolicy.CONFIGURATION_JSON, policy.getConfigurationJson()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinuousProfilingPolicy> queryPolicies(List<String> serviceIdList) throws IOException {
|
||||
return serviceIdList.stream().map(s -> {
|
||||
try {
|
||||
return getClient().queryProperty(GROUP, ContinuousProfilingPolicy.INDEX_NAME, s);
|
||||
} catch (IOException e) {
|
||||
log.warn("query policy error", e);
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull).map(properties -> {
|
||||
final ContinuousProfilingPolicy policy = new ContinuousProfilingPolicy();
|
||||
policy.setServiceId(properties.id());
|
||||
for (TagAndValue<?> tag : properties.tags()) {
|
||||
if (tag.getTagName().equals(ContinuousProfilingPolicy.CONFIGURATION_JSON)) {
|
||||
policy.setConfigurationJson((String) tag.getValue());
|
||||
} else if (tag.getTagName().equals(ContinuousProfilingPolicy.UUID)) {
|
||||
policy.setUuid((String) tag.getValue());
|
||||
}
|
||||
}
|
||||
return policy;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,17 +19,13 @@
|
|||
package org.apache.skywalking.oap.server.storage.plugin.banyandb.stream;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.skywalking.banyandb.v1.client.AbstractQuery;
|
||||
import org.apache.skywalking.banyandb.v1.client.RowEntity;
|
||||
import org.apache.skywalking.banyandb.v1.client.StreamQuery;
|
||||
import org.apache.skywalking.banyandb.v1.client.StreamQueryResponse;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
|
|
@ -38,7 +34,6 @@ import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBStorageC
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -55,17 +50,17 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
EBPFProfilingTaskRecord.TARGET_TYPE,
|
||||
EBPFProfilingTaskRecord.CREATE_TIME,
|
||||
EBPFProfilingTaskRecord.LAST_UPDATE_TIME,
|
||||
EBPFProfilingTaskRecord.EXTENSION_CONFIG_JSON);
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
EBPFProfilingTaskRecord.EXTENSION_CONFIG_JSON,
|
||||
EBPFProfilingTaskRecord.CONTINUOUS_PROFILING_JSON);
|
||||
|
||||
public BanyanDBEBPFProfilingTaskDAO(BanyanDBStorageClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EBPFProfilingTask> queryTasksByServices(List<String> serviceIdList, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
List<EBPFProfilingTask> tasks = new ArrayList<>();
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByServices(List<String> serviceIdList, EBPFProfilingTriggerType triggerType,
|
||||
long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
List<EBPFProfilingTaskRecord> tasks = new ArrayList<>();
|
||||
for (final String serviceId : serviceIdList) {
|
||||
StreamQueryResponse resp = query(EBPFProfilingTaskRecord.INDEX_NAME, TAGS,
|
||||
new QueryBuilder<StreamQuery>() {
|
||||
|
|
@ -73,6 +68,9 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
protected void apply(StreamQuery query) {
|
||||
query.and(eq(EBPFProfilingTaskRecord.SERVICE_ID, serviceId));
|
||||
appendTimeQuery(this, query, taskStartTime, latestUpdateTime);
|
||||
if (triggerType != null) {
|
||||
query.and(eq(EBPFProfilingTaskRecord.TRIGGER_TYPE, triggerType.value()));
|
||||
}
|
||||
query.setOrderBy(new AbstractQuery.OrderBy(EBPFProfilingTaskRecord.CREATE_TIME, AbstractQuery.Sort.DESC));
|
||||
}
|
||||
});
|
||||
|
|
@ -83,8 +81,9 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<EBPFProfilingTask> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
List<EBPFProfilingTask> tasks = new ArrayList<>();
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes,
|
||||
EBPFProfilingTriggerType triggerType, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
List<EBPFProfilingTaskRecord> tasks = new ArrayList<>();
|
||||
for (final EBPFProfilingTargetType targetType : targetTypes) {
|
||||
StreamQueryResponse resp = query(EBPFProfilingTaskRecord.INDEX_NAME, TAGS,
|
||||
new QueryBuilder<StreamQuery>() {
|
||||
|
|
@ -96,6 +95,9 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
if (StringUtil.isNotEmpty(serviceInstanceId)) {
|
||||
query.and(eq(EBPFProfilingTaskRecord.INSTANCE_ID, serviceInstanceId));
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(targetTypes)) {
|
||||
query.and(eq(EBPFProfilingTaskRecord.TRIGGER_TYPE, triggerType.value()));
|
||||
}
|
||||
query.and(eq(EBPFProfilingTaskRecord.TARGET_TYPE, targetType.value()));
|
||||
appendTimeQuery(this, query, taskStartTime, latestUpdateTime);
|
||||
query.setOrderBy(new AbstractQuery.OrderBy(EBPFProfilingTaskRecord.CREATE_TIME, AbstractQuery.Sort.DESC));
|
||||
|
|
@ -108,7 +110,7 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public EBPFProfilingTask queryById(String id) throws IOException {
|
||||
public List<EBPFProfilingTaskRecord> getTaskRecord(String id) throws IOException {
|
||||
StreamQueryResponse resp = query(EBPFProfilingTaskRecord.INDEX_NAME, TAGS,
|
||||
new QueryBuilder<StreamQuery>() {
|
||||
@Override
|
||||
|
|
@ -116,16 +118,7 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
query.and(eq(EBPFProfilingTaskRecord.LOGICAL_ID, id));
|
||||
}
|
||||
});
|
||||
final List<EBPFProfilingTask> tasks = resp.getElements().stream().map(this::buildTask).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EBPFProfilingTask result = tasks.get(0);
|
||||
for (int i = 1; i < tasks.size(); i++) {
|
||||
result = result.combine(tasks.get(i));
|
||||
}
|
||||
return result;
|
||||
return resp.getElements().stream().map(this::buildTask).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void appendTimeQuery(QueryBuilder<StreamQuery> builder, StreamQuery query, long taskStartTime, long latestUpdateTime) {
|
||||
|
|
@ -137,34 +130,10 @@ public class BanyanDBEBPFProfilingTaskDAO extends AbstractBanyanDBDAO implements
|
|||
}
|
||||
}
|
||||
|
||||
private EBPFProfilingTask buildTask(final RowEntity rowEntity) {
|
||||
private EBPFProfilingTaskRecord buildTask(final RowEntity rowEntity) {
|
||||
final EBPFProfilingTaskRecord.Builder builder = new EBPFProfilingTaskRecord.Builder();
|
||||
final EBPFProfilingTaskRecord record = builder.storage2Entity(new BanyanDBConverter.StorageToStream(
|
||||
return builder.storage2Entity(new BanyanDBConverter.StorageToStream(
|
||||
EBPFProfilingTaskRecord.INDEX_NAME,
|
||||
rowEntity));
|
||||
|
||||
final EBPFProfilingTask task = new EBPFProfilingTask();
|
||||
task.setTaskId(record.getLogicalId());
|
||||
task.setServiceId(record.getServiceId());
|
||||
task.setServiceName(IDManager.ServiceID.analysisId(record.getServiceId()).getName());
|
||||
if (StringUtil.isNotEmpty(record.getProcessLabelsJson())) {
|
||||
task.setProcessLabels(GSON.<List<String>>fromJson(record.getProcessLabelsJson(), ArrayList.class));
|
||||
} else {
|
||||
task.setProcessLabels(Collections.emptyList());
|
||||
}
|
||||
if (StringUtil.isNotEmpty(record.getInstanceId())) {
|
||||
task.setServiceInstanceId(record.getInstanceId());
|
||||
task.setServiceInstanceName(IDManager.ServiceInstanceID.analysisId(record.getInstanceId()).getName());
|
||||
}
|
||||
task.setTaskStartTime(record.getStartTime());
|
||||
task.setTriggerType(EBPFProfilingTriggerType.valueOf(record.getTriggerType()));
|
||||
task.setFixedTriggerDuration(record.getFixedTriggerDuration());
|
||||
task.setTargetType(EBPFProfilingTargetType.valueOf(record.getTargetType()));
|
||||
task.setCreateTime(record.getCreateTime());
|
||||
task.setLastUpdateTime(record.getLastUpdateTime());
|
||||
if (StringUtil.isNotEmpty(record.getExtensionConfigJson())) {
|
||||
task.setExtensionConfig(GSON.fromJson(record.getExtensionConfigJson(), EBPFProfilingTaskExtension.class));
|
||||
}
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
|||
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingDataDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
|
|
@ -69,6 +70,7 @@ import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.cache.Netwo
|
|||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.AggregationQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.AlarmQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.BrowserLogQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.ContinuousProfilingPolicyEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFProfilingDataEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFProfilingScheduleEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFProfilingTaskEsDAO;
|
||||
|
|
@ -229,6 +231,10 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
|
|||
IEBPFProfilingDataDAO.class,
|
||||
new EBPFProfilingDataEsDAO(elasticSearchClient, config)
|
||||
);
|
||||
this.registerServiceImplementation(
|
||||
IContinuousProfilingPolicyDAO.class,
|
||||
new ContinuousProfilingPolicyEsDAO(elasticSearchClient)
|
||||
);
|
||||
this.registerServiceImplementation(
|
||||
IServiceLabelDAO.class,
|
||||
new ServiceLabelEsDAO(elasticSearchClient, config)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.library.elasticsearch.requests.search.Query;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.Search;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.SearchBuilder;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchHit;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchResponse;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.ElasticSearchConverter;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.IndexController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContinuousProfilingPolicyEsDAO extends EsDAO implements IContinuousProfilingPolicyDAO {
|
||||
public ContinuousProfilingPolicyEsDAO(ElasticSearchClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePolicy(ContinuousProfilingPolicy policy) throws IOException {
|
||||
final ContinuousProfilingPolicy.Builder builder = new ContinuousProfilingPolicy.Builder();
|
||||
final ElasticSearchConverter.ToStorage toStorage = new ElasticSearchConverter.ToStorage(ContinuousProfilingPolicy.INDEX_NAME);
|
||||
builder.entity2Storage(policy, toStorage);
|
||||
|
||||
final boolean exist = getClient().existDoc(ContinuousProfilingPolicy.INDEX_NAME, policy.id().build());
|
||||
if (exist) {
|
||||
getClient().forceUpdate(ContinuousProfilingPolicy.INDEX_NAME, policy.id().build(), toStorage.obtain());
|
||||
} else {
|
||||
getClient().forceInsert(ContinuousProfilingPolicy.INDEX_NAME, policy.id().build(), toStorage.obtain());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinuousProfilingPolicy> queryPolicies(List<String> serviceIdList) throws IOException {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(ContinuousProfilingPolicy.INDEX_NAME);
|
||||
final SearchBuilder search = Search.builder()
|
||||
.query(Query.terms(ContinuousProfilingPolicy.SERVICE_ID, serviceIdList))
|
||||
.size(serviceIdList.size());
|
||||
|
||||
return buildPolicies(getClient().search(index, search.build()));
|
||||
}
|
||||
|
||||
private List<ContinuousProfilingPolicy> buildPolicies(SearchResponse response) {
|
||||
List<ContinuousProfilingPolicy> policies = new ArrayList<>();
|
||||
for (SearchHit hit : response.getHits()) {
|
||||
final Map<String, Object> sourceAsMap = hit.getSource();
|
||||
final ContinuousProfilingPolicy.Builder builder = new ContinuousProfilingPolicy.Builder();
|
||||
policies.add(builder.storage2Entity(new ElasticSearchConverter.ToEntity(ContinuousProfilingPolicy.INDEX_NAME, sourceAsMap)));
|
||||
}
|
||||
return policies;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.BoolQueryBuilder;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.Query;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.Search;
|
||||
|
|
@ -26,12 +25,9 @@ import org.apache.skywalking.library.elasticsearch.requests.search.SearchBuilder
|
|||
import org.apache.skywalking.library.elasticsearch.requests.search.Sort;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchHit;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchResponse;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
|
|
@ -42,15 +38,11 @@ import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
|
|||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.IndexController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskDAO {
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private final int taskMaxSize;
|
||||
|
||||
public EBPFProfilingTaskEsDAO(ElasticSearchClient client, StorageModuleElasticsearchConfig config) {
|
||||
|
|
@ -59,7 +51,7 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<EBPFProfilingTask> queryTasksByServices(List<String> serviceIdList, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByServices(List<String> serviceIdList, EBPFProfilingTriggerType triggerType, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
final BoolQueryBuilder query = Query.bool();
|
||||
|
|
@ -76,6 +68,9 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
if (latestUpdateTime > 0) {
|
||||
query.must(Query.range(EBPFProfilingTaskRecord.LAST_UPDATE_TIME).gt(latestUpdateTime));
|
||||
}
|
||||
if (triggerType != null) {
|
||||
query.must(Query.term(EBPFProfilingTaskRecord.TRIGGER_TYPE, triggerType.value()));
|
||||
}
|
||||
|
||||
final SearchBuilder search = Search.builder().query(query)
|
||||
.sort(EBPFProfilingTaskRecord.CREATE_TIME, Sort.Order.DESC)
|
||||
|
|
@ -86,7 +81,8 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<EBPFProfilingTask> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes,
|
||||
EBPFProfilingTriggerType triggerType, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
final BoolQueryBuilder query = Query.bool();
|
||||
|
|
@ -101,6 +97,9 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
query.must(Query.terms(EBPFProfilingTaskRecord.TARGET_TYPE, targetTypes.stream()
|
||||
.map(EBPFProfilingTargetType::value).collect(Collectors.toList())));
|
||||
}
|
||||
if (triggerType != null) {
|
||||
query.must(Query.term(EBPFProfilingTaskRecord.TRIGGER_TYPE, triggerType.value()));
|
||||
}
|
||||
if (taskStartTime > 0) {
|
||||
query.must(Query.range(EBPFProfilingTaskRecord.START_TIME).gte(taskStartTime));
|
||||
}
|
||||
|
|
@ -117,7 +116,7 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
}
|
||||
|
||||
@Override
|
||||
public EBPFProfilingTask queryById(String id) throws IOException {
|
||||
public List<EBPFProfilingTaskRecord> getTaskRecord(String id) throws IOException {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
final BoolQueryBuilder query = Query.bool().must(Query.term(EBPFProfilingTaskRecord.LOGICAL_ID, id));
|
||||
|
|
@ -125,44 +124,12 @@ public class EBPFProfilingTaskEsDAO extends EsDAO implements IEBPFProfilingTaskD
|
|||
final SearchBuilder search = Search.builder().query(query).size(taskMaxSize);
|
||||
|
||||
final SearchResponse response = getClient().search(index, search.build());
|
||||
final List<EBPFProfilingTask> tasks = response.getHits().getHits().stream().map(this::parseTask).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return null;
|
||||
}
|
||||
EBPFProfilingTask result = tasks.get(0);
|
||||
for (int i = 1; i < tasks.size(); i++) {
|
||||
result = result.combine(tasks.get(i));
|
||||
}
|
||||
return result;
|
||||
return response.getHits().getHits().stream().map(this::parseTask).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private EBPFProfilingTask parseTask(final SearchHit hit) {
|
||||
private EBPFProfilingTaskRecord parseTask(final SearchHit hit) {
|
||||
final Map<String, Object> sourceAsMap = hit.getSource();
|
||||
final EBPFProfilingTaskRecord.Builder builder = new EBPFProfilingTaskRecord.Builder();
|
||||
final EBPFProfilingTaskRecord record = builder.storage2Entity(new ElasticSearchConverter.ToEntity(EBPFProfilingTaskRecord.INDEX_NAME, sourceAsMap));
|
||||
|
||||
final EBPFProfilingTask task = new EBPFProfilingTask();
|
||||
task.setTaskId(record.getLogicalId());
|
||||
task.setServiceId(record.getServiceId());
|
||||
task.setServiceName(IDManager.ServiceID.analysisId(record.getServiceId()).getName());
|
||||
if (StringUtil.isNotEmpty(record.getProcessLabelsJson())) {
|
||||
task.setProcessLabels(GSON.<List<String>>fromJson(record.getProcessLabelsJson(), ArrayList.class));
|
||||
} else {
|
||||
task.setProcessLabels(Collections.emptyList());
|
||||
}
|
||||
if (StringUtil.isNotEmpty(record.getInstanceId())) {
|
||||
task.setServiceInstanceId(record.getInstanceId());
|
||||
task.setServiceInstanceName(IDManager.ServiceInstanceID.analysisId(record.getInstanceId()).getName());
|
||||
}
|
||||
task.setTaskStartTime(record.getStartTime());
|
||||
task.setTriggerType(EBPFProfilingTriggerType.valueOf(record.getTriggerType()));
|
||||
task.setFixedTriggerDuration(record.getFixedTriggerDuration());
|
||||
task.setTargetType(EBPFProfilingTargetType.valueOf(record.getTargetType()));
|
||||
task.setCreateTime(record.getCreateTime());
|
||||
task.setLastUpdateTime(record.getLastUpdateTime());
|
||||
if (StringUtil.isNotEmpty(record.getExtensionConfigJson())) {
|
||||
task.setExtensionConfig(GSON.fromJson(record.getExtensionConfigJson(), EBPFProfilingTaskExtension.class));
|
||||
}
|
||||
return task;
|
||||
return builder.storage2Entity(new ElasticSearchConverter.ToEntity(EBPFProfilingTaskRecord.INDEX_NAME, sourceAsMap));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasD
|
|||
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
|
||||
import org.apache.skywalking.oap.server.core.storage.model.ModelInstaller;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingDataDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
|
|
@ -58,6 +59,7 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCAggre
|
|||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCAlarmQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCBatchDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCBrowserLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFProfilingDataDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFProfilingTaskDAO;
|
||||
|
|
@ -199,6 +201,9 @@ public abstract class JDBCStorageProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(
|
||||
IEBPFProfilingDataDAO.class,
|
||||
new JDBCEBPFProfilingDataDAO(jdbcClient, tableHelper));
|
||||
this.registerServiceImplementation(
|
||||
IContinuousProfilingPolicyDAO.class,
|
||||
new JDBCContinuousProfilingPolicyDAO(jdbcClient, tableHelper));
|
||||
this.registerServiceImplementation(
|
||||
IServiceLabelDAO.class,
|
||||
new JDBCServiceLabelQueryDAO(jdbcClient, tableHelper));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.common.dao;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.continuous.IContinuousProfilingPolicyDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.HashMapConverter;
|
||||
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
|
||||
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLExecutor;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.TableMetaInfo;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class JDBCContinuousProfilingPolicyDAO extends JDBCSQLExecutor implements IContinuousProfilingPolicyDAO {
|
||||
private final JDBCClient jdbcClient;
|
||||
private final TableHelper tableHelper;
|
||||
|
||||
@Override
|
||||
public void savePolicy(ContinuousProfilingPolicy policy) throws IOException {
|
||||
final List<ContinuousProfilingPolicy> existingPolicy = queryPolicies(Arrays.asList(policy.getServiceId()));
|
||||
SQLExecutor sqlExecutor;
|
||||
final var model = TableMetaInfo.get(ContinuousProfilingPolicy.INDEX_NAME);
|
||||
if (CollectionUtils.isNotEmpty(existingPolicy)) {
|
||||
sqlExecutor = getUpdateExecutor(model, policy, 0, new ContinuousProfilingPolicy.Builder(), null);
|
||||
} else {
|
||||
sqlExecutor = getInsertExecutor(model, policy, 0,
|
||||
new ContinuousProfilingPolicy.Builder(), new HashMapConverter.ToStorage(), null);
|
||||
}
|
||||
|
||||
try (Connection connection = jdbcClient.getConnection()) {
|
||||
sqlExecutor.invoke(connection);
|
||||
} catch (SQLException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<ContinuousProfilingPolicy> queryPolicies(List<String> serviceIdList) throws IOException {
|
||||
final var tables = tableHelper.getTablesWithinTTL(ContinuousProfilingPolicy.INDEX_NAME);
|
||||
List<Object> condition = new ArrayList<>();
|
||||
condition.add(ContinuousProfilingPolicy.INDEX_NAME);
|
||||
condition.addAll(serviceIdList);
|
||||
|
||||
StringBuilder whereQuery = new StringBuilder()
|
||||
.append(" where ")
|
||||
.append(JDBCTableInstaller.TABLE_COLUMN).append(" = ?")
|
||||
.append(" and ").append(ContinuousProfilingPolicy.SERVICE_ID)
|
||||
.append(" in ").append(serviceIdList.stream().map(s -> "?").collect(Collectors.joining(",", "(", ")")));
|
||||
final var results = new ArrayList<ContinuousProfilingPolicy>();
|
||||
for (String table : tables) {
|
||||
results.addAll(jdbcClient.executeQuery("select * from " + table + whereQuery, this::buildPolicies, condition.toArray(new Object[0])));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<ContinuousProfilingPolicy> buildPolicies(ResultSet resultSet) throws SQLException {
|
||||
List<ContinuousProfilingPolicy> policies = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
final ContinuousProfilingPolicy policy = new ContinuousProfilingPolicy();
|
||||
policy.setServiceId(resultSet.getString(ContinuousProfilingPolicy.SERVICE_ID));
|
||||
policy.setUuid(resultSet.getString(ContinuousProfilingPolicy.UUID));
|
||||
policy.setConfigurationJson(resultSet.getString(ContinuousProfilingPolicy.CONFIGURATION_JSON));
|
||||
|
||||
policies.add(policy);
|
||||
}
|
||||
return policies;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,15 +18,12 @@
|
|||
|
||||
package org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTargetType;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTaskRecord;
|
||||
import org.apache.skywalking.oap.server.core.profiling.ebpf.storage.EBPFProfilingTriggerType;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTask;
|
||||
import org.apache.skywalking.oap.server.core.query.type.EBPFProfilingTaskExtension;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageData;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
|
||||
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||
|
|
@ -34,40 +31,21 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInst
|
|||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.SQLAndParameters;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
||||
private static final Gson GSON = new Gson();
|
||||
public class JDBCEBPFProfilingTaskDAO extends JDBCSQLExecutor implements IEBPFProfilingTaskDAO {
|
||||
private final JDBCClient jdbcClient;
|
||||
private final TableHelper tableHelper;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public List<EBPFProfilingTask> queryTasksByServices(List<String> serviceIdList, long taskStartTime, long latestUpdateTime) {
|
||||
final var tables = tableHelper.getTablesWithinTTL(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
final var results = new ArrayList<EBPFProfilingTask>();
|
||||
|
||||
for (final var table : tables) {
|
||||
final var sqlAndParameters = buildSQLForQueryTasksByServices(serviceIdList, taskStartTime, latestUpdateTime, table);
|
||||
results.addAll(
|
||||
jdbcClient.executeQuery(
|
||||
sqlAndParameters.sql(),
|
||||
this::buildTasks,
|
||||
sqlAndParameters.parameters()
|
||||
)
|
||||
);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
protected SQLAndParameters buildSQLForQueryTasksByServices(
|
||||
final List<String> serviceIdList,
|
||||
EBPFProfilingTriggerType triggerType,
|
||||
final long taskStartTime,
|
||||
final long latestUpdateTime,
|
||||
final String table) {
|
||||
|
|
@ -88,6 +66,10 @@ public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
|||
appendCondition(conditionSql, parameters,
|
||||
EBPFProfilingTaskRecord.LAST_UPDATE_TIME, ">", latestUpdateTime);
|
||||
}
|
||||
if (triggerType != null) {
|
||||
appendCondition(conditionSql, parameters,
|
||||
EBPFProfilingTaskRecord.TRIGGER_TYPE, "=", triggerType.value());
|
||||
}
|
||||
|
||||
if (conditionSql.length() > 0) {
|
||||
sql.append(" where ").append(conditionSql);
|
||||
|
|
@ -95,15 +77,36 @@ public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
|||
return new SQLAndParameters(sql.toString(), parameters);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByServices(List<String> serviceIdList, EBPFProfilingTriggerType triggerType, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
final var tables = tableHelper.getTablesWithinTTL(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
final var results = new ArrayList<EBPFProfilingTaskRecord>();
|
||||
|
||||
for (final var table : tables) {
|
||||
final var sqlAndParameters = buildSQLForQueryTasksByServices(serviceIdList, triggerType, taskStartTime, latestUpdateTime, table);
|
||||
results.addAll(
|
||||
jdbcClient.executeQuery(
|
||||
sqlAndParameters.sql(),
|
||||
this::buildTasks,
|
||||
sqlAndParameters.parameters()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public List<EBPFProfilingTask> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes, long taskStartTime, long latestUpdateTime) {
|
||||
final var results = new ArrayList<EBPFProfilingTask>();
|
||||
public List<EBPFProfilingTaskRecord> queryTasksByTargets(String serviceId, String serviceInstanceId, List<EBPFProfilingTargetType> targetTypes,
|
||||
EBPFProfilingTriggerType triggerType, long taskStartTime, long latestUpdateTime) throws IOException {
|
||||
final var results = new ArrayList<EBPFProfilingTaskRecord>();
|
||||
final var tables = tableHelper.getTablesWithinTTL(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
|
||||
for (final var table : tables) {
|
||||
final var sqlAndParameters = buildSQLForQueryTasksByTargets(
|
||||
serviceId, serviceInstanceId, targetTypes, taskStartTime, latestUpdateTime, table
|
||||
serviceId, serviceInstanceId, targetTypes, triggerType, taskStartTime, latestUpdateTime, table
|
||||
);
|
||||
results.addAll(
|
||||
jdbcClient.executeQuery(
|
||||
|
|
@ -116,10 +119,30 @@ public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
|||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public List<EBPFProfilingTaskRecord> getTaskRecord(String id) throws IOException {
|
||||
final List<EBPFProfilingTaskRecord> results = new ArrayList<>();
|
||||
final var tables = tableHelper.getTablesWithinTTL(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
for (final var table : tables) {
|
||||
String sql = "select * from " + table +
|
||||
" where " + JDBCTableInstaller.TABLE_COLUMN + " = ?" +
|
||||
EBPFProfilingTaskRecord.LOGICAL_ID + " = ?";
|
||||
|
||||
results.addAll(jdbcClient.executeQuery(
|
||||
sql,
|
||||
this::buildTasks,
|
||||
EBPFProfilingTaskRecord.INDEX_NAME, id
|
||||
));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
protected SQLAndParameters buildSQLForQueryTasksByTargets(
|
||||
final String serviceId,
|
||||
final String serviceInstanceId,
|
||||
final List<EBPFProfilingTargetType> targetTypes,
|
||||
EBPFProfilingTriggerType triggerType,
|
||||
final long taskStartTime,
|
||||
final long latestUpdateTime,
|
||||
final String table) {
|
||||
|
|
@ -147,6 +170,10 @@ public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
|||
appendCondition(conditions, parameters,
|
||||
EBPFProfilingTaskRecord.LAST_UPDATE_TIME, ">", latestUpdateTime);
|
||||
}
|
||||
if (triggerType != null) {
|
||||
appendCondition(conditions, parameters,
|
||||
EBPFProfilingTaskRecord.TRIGGER_TYPE, "=", triggerType.value());
|
||||
}
|
||||
|
||||
if (conditions.length() > 0) {
|
||||
sql.append(" where ").append(conditions);
|
||||
|
|
@ -155,60 +182,11 @@ public class JDBCEBPFProfilingTaskDAO implements IEBPFProfilingTaskDAO {
|
|||
return new SQLAndParameters(sql.toString(), parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public EBPFProfilingTask queryById(String id) {
|
||||
final var tables = tableHelper.getTablesWithinTTL(EBPFProfilingTaskRecord.INDEX_NAME);
|
||||
for (final var table : tables) {
|
||||
final var sql = new StringBuilder();
|
||||
sql.append("select * from ").append(table)
|
||||
.append(" where ").append(JDBCTableInstaller.TABLE_COLUMN).append(" = ?")
|
||||
.append(EBPFProfilingTaskRecord.LOGICAL_ID).append(" = ?");
|
||||
|
||||
final var result = jdbcClient.executeQuery(
|
||||
sql.toString(),
|
||||
resultSet -> buildTasks(resultSet).stream().reduce(EBPFProfilingTask::combine).orElse(null),
|
||||
EBPFProfilingTaskRecord.INDEX_NAME, id
|
||||
);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<EBPFProfilingTask> buildTasks(ResultSet resultSet) throws SQLException {
|
||||
List<EBPFProfilingTask> tasks = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
EBPFProfilingTask task = new EBPFProfilingTask();
|
||||
task.setTaskId(resultSet.getString(EBPFProfilingTaskRecord.LOGICAL_ID));
|
||||
final String serviceId = resultSet.getString(EBPFProfilingTaskRecord.SERVICE_ID);
|
||||
task.setServiceId(serviceId);
|
||||
task.setServiceName(IDManager.ServiceID.analysisId(serviceId).getName());
|
||||
final String processLabelString = resultSet.getString(EBPFProfilingTaskRecord.PROCESS_LABELS_JSON);
|
||||
if (StringUtil.isNotEmpty(processLabelString)) {
|
||||
task.setProcessLabels(GSON.<List<String>>fromJson(processLabelString, ArrayList.class));
|
||||
} else {
|
||||
task.setProcessLabels(Collections.emptyList());
|
||||
}
|
||||
if (StringUtil.isNotEmpty(resultSet.getString(EBPFProfilingTaskRecord.INSTANCE_ID))) {
|
||||
task.setServiceInstanceId(resultSet.getString(EBPFProfilingTaskRecord.INSTANCE_ID));
|
||||
task.setServiceInstanceName(IDManager.ServiceInstanceID.analysisId(task.getServiceInstanceId()).getName());
|
||||
}
|
||||
task.setTaskStartTime(resultSet.getLong(EBPFProfilingTaskRecord.START_TIME));
|
||||
task.setTriggerType(EBPFProfilingTriggerType.valueOf(
|
||||
resultSet.getInt(EBPFProfilingTaskRecord.TRIGGER_TYPE)));
|
||||
task.setFixedTriggerDuration(resultSet.getInt(EBPFProfilingTaskRecord.FIXED_TRIGGER_DURATION));
|
||||
task.setTargetType(EBPFProfilingTargetType.valueOf(
|
||||
resultSet.getInt(EBPFProfilingTaskRecord.TARGET_TYPE)));
|
||||
task.setCreateTime(resultSet.getLong(EBPFProfilingTaskRecord.CREATE_TIME));
|
||||
task.setLastUpdateTime(resultSet.getLong(EBPFProfilingTaskRecord.LAST_UPDATE_TIME));
|
||||
String extensionConfigJson = resultSet.getString(EBPFProfilingTaskRecord.EXTENSION_CONFIG_JSON);
|
||||
if (StringUtil.isNotEmpty(extensionConfigJson)) {
|
||||
task.setExtensionConfig(GSON.fromJson(extensionConfigJson, EBPFProfilingTaskExtension.class));
|
||||
}
|
||||
|
||||
tasks.add(task);
|
||||
private List<EBPFProfilingTaskRecord> buildTasks(ResultSet resultSet) throws SQLException {
|
||||
List<EBPFProfilingTaskRecord> tasks = new ArrayList<>();
|
||||
StorageData data;
|
||||
while ((data = toStorageData(resultSet, EBPFProfilingTaskRecord.INDEX_NAME, new EBPFProfilingTaskRecord.Builder())) != null) {
|
||||
tasks.add((EBPFProfilingTaskRecord) data);
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
# 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 golang:1.17
|
||||
|
||||
WORKDIR /
|
||||
COPY sqrt.go /sqrt.go
|
||||
RUN go build -o sqrt sqrt.go
|
||||
|
||||
CMD ["/sqrt"]
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# 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:
|
||||
banyandb:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: banyandb
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: banyandb
|
||||
depends_on:
|
||||
banyandb:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# 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: ../../../../script/docker-compose/base-compose.yml
|
||||
service: oap
|
||||
|
||||
banyandb:
|
||||
extends:
|
||||
file: ../../../../script/docker-compose/base-compose.yml
|
||||
service: banyandb
|
||||
|
||||
sqrt:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
image: "ghcr.io/apache/skywalking-rover/skywalking-rover:${SW_ROVER_COMMIT}"
|
||||
networks:
|
||||
- e2e
|
||||
privileged: true
|
||||
pid: host
|
||||
environment:
|
||||
ROVER_LOGGER_LEVEL: DEBUG
|
||||
ROVER_HOST_MAPPING: /host
|
||||
ROVER_BACKEND_ADDR: oap:11800
|
||||
ROVER_PROCESS_DISCOVERY_HEARTBEAT_PERIOD: 2s
|
||||
ROVER_PROCESS_DISCOVERY_VM_ACTIVE: "true"
|
||||
ROVER_PROCESS_DISCOVERY_SCAN_MODE: REGEX
|
||||
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_MATCH_CMD: sqrt
|
||||
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_LAYER: OS_LINUX
|
||||
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_SERVICE_NAME: sqrt
|
||||
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_INSTANCE_NAME: test-instance
|
||||
ROVER_PROCESS_DISCOVERY_REGEX_SCANNER_PROCESS_NAME: "{{.Process.ExeName}}"
|
||||
ROVER_PROFILING_ACTIVE: "true"
|
||||
ROVER_PROFILING_CHECK_INTERVAL: 2s
|
||||
ROVER_PROFILING_FLUSH_INTERVAL: 5s
|
||||
ROVER_PROFILING_TASK_ON_CPU_DUMP_PERIOD: 9ms
|
||||
volumes:
|
||||
- /:/host
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# 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:
|
||||
es:
|
||||
image: elastic/elasticsearch:7.15.0
|
||||
expose:
|
||||
- 9200
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- cluster.routing.allocation.disk.threshold_enabled=false
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9200" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: elasticsearch
|
||||
depends_on:
|
||||
es:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# 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:
|
||||
es:
|
||||
image: elastic/elasticsearch:7.15.0
|
||||
expose:
|
||||
- 9200
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- cluster.routing.allocation.disk.threshold_enabled=false
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9200" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: elasticsearch
|
||||
SW_STORAGE_ES_LOGIC_SHARDING: "true"
|
||||
depends_on:
|
||||
es:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- id: {{ b64enc "sqrt" }}.1_{{ b64enc "test-instance" }}
|
||||
name: test-instance
|
||||
attributes: []
|
||||
language: UNKNOWN
|
||||
instanceuuid: {{ notEmpty .instanceuuid }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- key: {{ notEmpty .key }}
|
||||
value: {{ ge .value 1 }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
status: true
|
||||
errorreason: null
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- id: {{ notEmpty .id }}
|
||||
name: sqrt
|
||||
serviceid: {{ b64enc "sqrt" }}.1
|
||||
servicename: sqrt
|
||||
instanceid: {{ b64enc "sqrt" }}.1_{{ b64enc "test-instance" }}
|
||||
instancename: test-instance
|
||||
agentid: {{ notEmpty .agentid }}
|
||||
detecttype: VM
|
||||
attributes:
|
||||
{{- contains .attributes }}
|
||||
- name: host_ip
|
||||
value: {{ notEmpty .value }}
|
||||
- name: pid
|
||||
value: {{ notEmpty .value }}
|
||||
- name: command_line
|
||||
value: /sqrt
|
||||
- name: support_ebpf_profiling
|
||||
value: "true"
|
||||
{{- end }}
|
||||
labels: []
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# 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.
|
||||
|
||||
tip: null
|
||||
trees:
|
||||
{{- contains .trees }}
|
||||
- elements:
|
||||
{{- contains .elements }}
|
||||
- id: "{{ notEmpty .id }}"
|
||||
parentid: "{{ notEmpty .parentid }}"
|
||||
symbol: "main.sqrtGolang"
|
||||
stacktype: USER_SPACE
|
||||
dumpcount: {{ gt .dumpcount 0 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- scheduleid: {{ notEmpty .scheduleid }}
|
||||
taskid: {{ notEmpty .taskid }}
|
||||
process:
|
||||
id: {{ notEmpty .process.id }}
|
||||
name: sqrt
|
||||
serviceid: {{ b64enc "sqrt" }}.1
|
||||
servicename: sqrt
|
||||
instanceid: {{ b64enc "sqrt" }}.1_{{ b64enc "test-instance" }}
|
||||
instancename: test-instance
|
||||
agentid: {{ notEmpty .process.agentid }}
|
||||
detecttype: VM
|
||||
attributes:
|
||||
{{- contains .process.attributes }}
|
||||
- name: host_ip
|
||||
value: {{ notEmpty .value }}
|
||||
- name: pid
|
||||
value: {{ notEmpty .value }}
|
||||
- name: command_line
|
||||
value: /sqrt
|
||||
{{- end }}
|
||||
labels: []
|
||||
starttime: {{ gt .starttime 0 }}
|
||||
endtime: {{ gt .endtime 0 }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# 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.
|
||||
|
||||
- type: ON_CPU
|
||||
checkitems:
|
||||
- type: PROCESS_CPU
|
||||
threshold: "10"
|
||||
period: 10
|
||||
count: 3
|
||||
urilist: []
|
||||
uriregex: null
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- id: {{ b64enc "sqrt" }}.1
|
||||
name: sqrt
|
||||
group: ""
|
||||
shortname: sqrt
|
||||
layers:
|
||||
- OS_LINUX
|
||||
normal: true
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# 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.
|
||||
|
||||
{{- contains . }}
|
||||
- taskid: {{ notEmpty .taskid }}
|
||||
serviceid: {{ b64enc "sqrt" }}.1
|
||||
servicename: sqrt
|
||||
serviceinstanceid: {{ b64enc "sqrt" }}.1_{{ b64enc "test-instance" }}
|
||||
serviceinstancename: test-instance
|
||||
processlabels: []
|
||||
processid: {{ notEmpty .processid }}
|
||||
processname: sqrt
|
||||
taskstarttime: {{ ge .taskstarttime 1 }}
|
||||
triggertype: CONTINUOUS_PROFILING
|
||||
fixedtriggerduration: 600
|
||||
continuousprofilingcauses:
|
||||
- type: PROCESS_CPU
|
||||
singlevalue:
|
||||
threshold: 1000
|
||||
current: {{ ge (index .continuousprofilingcauses 0).singlevalue.current 1 }}
|
||||
uri: null
|
||||
targettype: ON_CPU
|
||||
createtime: {{ ge .createtime 1 }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# 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:
|
||||
h2db:
|
||||
build:
|
||||
context: ""
|
||||
dockerfile: ../../../../../script/dockerfile/Dockerfile.h2
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 1521
|
||||
healthcheck:
|
||||
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/1521"]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: h2
|
||||
SW_STORAGE_H2_URL: jdbc:h2:tcp://h2db:1521/skywalking-oap-db;DATABASE_TO_UPPER=FALSE
|
||||
depends_on:
|
||||
h2db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# 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:
|
||||
mysql:
|
||||
image: mysql/mysql-server:8.0.13
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 3306
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=root@1234
|
||||
- MYSQL_DATABASE=swtest
|
||||
- MYSQL_ROOT_HOST=%
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: mysql
|
||||
entrypoint: ['sh', '-c', '/download-mysql.sh /skywalking/oap-libs && /skywalking/docker-entrypoint.sh']
|
||||
ports:
|
||||
- 12800
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
# 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:
|
||||
opensearch:
|
||||
image: opensearchproject/opensearch:${OPENSEARCH_VERSION}
|
||||
expose:
|
||||
- 9200
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- cluster.routing.allocation.disk.threshold_enabled=false
|
||||
- plugins.security.ssl.http.enabled=false
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9200" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: elasticsearch
|
||||
SW_STORAGE_ES_CLUSTER_NODES: opensearch:9200
|
||||
SW_ES_USER: admin
|
||||
SW_ES_PASSWORD: admin
|
||||
SW_STORAGE_ES_LOGIC_SHARDING: "true"
|
||||
depends_on:
|
||||
opensearch:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -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.
|
||||
|
||||
# Policy config
|
||||
# policy: the policy config list
|
||||
# - type: the profiling target type when reached the threshold, support: "ON_CPU", "OFF_CPU", "NETWORK"
|
||||
# checks: define the thresholds, when any configuration item reaches the threshold, it will trigger profiling task
|
||||
# - type: monitoring type, please see the below monitoring type with threshold description
|
||||
# threshold: monitor threshold, please see the below monitoring type with threshold description
|
||||
# period: the length of time to evaluate the metrics
|
||||
# count: how many times after the metrics match the threshold, will trigger profiling
|
||||
# uriList: the URI paths filter when monitor the HTTP related types
|
||||
# uriRegex: the URI regex filter when monitor the HTTP related types
|
||||
|
||||
# Monitoring type with threshold
|
||||
# PROCESS_CPU: Monitoring Process CPU percent, threshold value in [0-100]
|
||||
# PROCESS_THREAD_COUNT: Monitoring process thread count, threshold value must bigger than zero
|
||||
# SYSTEM_LOAD: Monitoring current system load, threshold value must bigger than zero
|
||||
# HTTP_ERROR_RATE: Monitoring the process HTTP response error(status>=500) percent, threshold value in [0-100]
|
||||
# HTTP_AVG_RESPONSE_TIME: Monitoring the process HTTP response duration(ms), threshold value must be bigger than zero
|
||||
|
||||
policy:
|
||||
- type: ON_CPU
|
||||
checkers:
|
||||
- type: PROCESS_CPU
|
||||
threshold: 10
|
||||
period: 10
|
||||
count: 3
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# 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:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 5432
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=123456
|
||||
- POSTGRES_DB=skywalking
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5432" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
oap:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: oap
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SW_STORAGE: postgresql
|
||||
SW_JDBC_URL: "jdbc:postgresql://postgres:5432/skywalking"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- 12800
|
||||
|
||||
sqrt:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: sqrt
|
||||
networks:
|
||||
- e2e
|
||||
|
||||
rover:
|
||||
extends:
|
||||
file: ../docker-compose.yml
|
||||
service: rover
|
||||
networks:
|
||||
- e2e
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
setup:
|
||||
env: compose
|
||||
file: docker-compose.yml
|
||||
timeout: 20m
|
||||
init-system-environment: ../../../../../script/env
|
||||
steps:
|
||||
- name: set PATH
|
||||
command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
|
||||
- name: install yq
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
|
||||
- name: install swctl
|
||||
command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
|
||||
|
||||
verify:
|
||||
retry:
|
||||
count: 20
|
||||
interval: 10s
|
||||
cases:
|
||||
- includes:
|
||||
- ../profiling-cases.yaml
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# 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.
|
||||
|
||||
# This file is used to show how to write configuration files and can be used to test.
|
||||
|
||||
cases:
|
||||
# metadata
|
||||
- query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml service ls
|
||||
expected: expected/service.yml
|
||||
- query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml instance ls --service-name sqrt
|
||||
expected: expected/instance.yml
|
||||
- query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml process ls --service-name sqrt --instance-name test-instance
|
||||
expected: expected/process.yml
|
||||
|
||||
# policy setting
|
||||
- query: |
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling continuous set --service-name sqrt --config test/e2e-v2/cases/profiling/ebpf/continuous/policy.yaml
|
||||
expected: expected/policy-set.yml
|
||||
- query: swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling continuous ls --service-name sqrt
|
||||
expected: expected/query-policy.yml
|
||||
|
||||
# check profiling metrics
|
||||
- query: |
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml metrics linear \
|
||||
--service-name sqrt --instance-name test-instance --process-name sqrt --name continuous_profiling_process_cpu |yq e 'to_entries' -
|
||||
expected: expected/metrics-has-value.yml
|
||||
|
||||
# check triggered profiling task
|
||||
- query: |
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf list --service-name sqrt --trigger CONTINUOUS_PROFILING
|
||||
expected: expected/trigger-task.yml
|
||||
- query: |
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf schedules --task-id=$( \
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf list --service-name sqrt --trigger CONTINUOUS_PROFILING|yq e '.[0].taskid' -
|
||||
)
|
||||
expected: expected/profiling-schedule-list.yml
|
||||
- query: |
|
||||
taskid=$(swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf list --service-name sqrt --trigger CONTINUOUS_PROFILING|yq e '.[0].taskid' -)
|
||||
scheduleid=$(swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf schedules --task-id=$taskid |yq e '.[0].scheduleid' -);
|
||||
start=$(swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf schedules --task-id=$taskid | yq e '.[0].starttime' -)
|
||||
end=$(swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf schedules --task-id=$taskid | yq e '.[0].endtime' -)
|
||||
swctl --base-url=http://${oap_host}:${oap_12800}/graphql --display yaml profiling ebpf analysis --schedule-id=$scheduleid --time-ranges=$start-$end
|
||||
expected: expected/profiling-analysis.yml
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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 main
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
//go:noinline
|
||||
func sqrtGolang() {
|
||||
for {
|
||||
math.Sqrt(10000)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
sqrtGolang()
|
||||
}
|
||||
|
|
@ -152,4 +152,17 @@ profiling:
|
|||
# The default body encoding when sampling the request
|
||||
default_request_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_REQUEST_ENCODING:UTF-8}
|
||||
# The default body encoding when sampling the response
|
||||
default_response_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_RESPONSE_ENCODING:UTF-8}
|
||||
default_response_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_RESPONSE_ENCODING:UTF-8}
|
||||
# continuous profiling config
|
||||
continuous:
|
||||
# continuous related meters prefix name
|
||||
meter_prefix: ${ROVER_PROFILING_CONTINUOUS_METER_PREFIX:rover_con_p}
|
||||
# The interval of fetch metrics from the system, such as Process CPU, System Load, etc.
|
||||
fetch_interval: ${ROVER_PROFILING_CONTINUOUS_FETCH_INTERVAL:1s}
|
||||
# The interval of check metrics is reach the thresholds
|
||||
check_interval: ${ROVER_PROFILING_CONTINUOUS_CHECK_INTERVAL:5s}
|
||||
trigger:
|
||||
# the duration of the profiling task
|
||||
execute_duration: ${ROVER_PROFILING_CONTINUOUS_TRIGGER_EXECUTE_DURATION:10m}
|
||||
# the minimal duration between the execution of the same profiling task
|
||||
silence_duration: ${ROVER_PROFILING_CONTINUOUS_TRIGGER_SILENCE_DURATION:20m}
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
servicename: file
|
||||
serviceinstanceid: null
|
||||
serviceinstancename: null
|
||||
processid: null
|
||||
processname: null
|
||||
processlabels:
|
||||
{{- contains .processlabels }}
|
||||
- e2e-label1
|
||||
|
|
@ -29,4 +31,5 @@
|
|||
fixedtriggerduration: 60
|
||||
targettype: OFF_CPU
|
||||
createtime: {{ gt .createtime 0 }}
|
||||
continuousprofilingcauses: []
|
||||
{{- end }}
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
servicename: sqrt
|
||||
serviceinstanceid: null
|
||||
serviceinstancename: null
|
||||
processid: null
|
||||
processname: null
|
||||
processlabels:
|
||||
{{- contains .processlabels }}
|
||||
- e2e-label1
|
||||
|
|
@ -29,4 +31,5 @@
|
|||
fixedtriggerduration: 60
|
||||
targettype: ON_CPU
|
||||
createtime: {{ gt .createtime 0 }}
|
||||
continuousprofilingcauses: []
|
||||
{{- end }}
|
||||
|
|
@ -22,7 +22,7 @@ SW_AGENT_PYTHON_COMMIT=c76a6ec51a478ac91abb20ec8f22a99b8d4d6a58
|
|||
SW_AGENT_CLIENT_JS_COMMIT=af0565a67d382b683c1dbd94c379b7080db61449
|
||||
SW_AGENT_CLIENT_JS_TEST_COMMIT=4f1eb1dcdbde3ec4a38534bf01dded4ab5d2f016
|
||||
SW_KUBERNETES_COMMIT_SHA=b670c41d94a82ddefcf466d54bab5c492d88d772
|
||||
SW_ROVER_COMMIT=8550199e98c9f5a4b2058878a0a899ffb73fe461
|
||||
SW_ROVER_COMMIT=fc8d074c6d34ecfee585a7097cbd5aef1ca680a5
|
||||
SW_BANYANDB_COMMIT=adbd3e87df7f84e5d1904fcf40476d2e81842058
|
||||
|
||||
SW_CTL_COMMIT=0883266bfaa36612927b69e35781b64ea181758d
|
||||
SW_CTL_COMMIT=838e222da5ab81b383c5bc8526e5d30002d836f9
|
||||
|
|
|
|||
Loading…
Reference in New Issue