You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/03/20 12:26:50 UTC

[skywalking] branch master updated: Support continuous profiling feature (#10473)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new 7dcdb279ef Support continuous profiling feature (#10473)
7dcdb279ef is described below

commit 7dcdb279ef6a93a47403054be9f414f1fec96451
Author: mrproliu <74...@qq.com>
AuthorDate: Mon Mar 20 20:26:42 2023 +0800

    Support continuous profiling feature (#10473)
---
 .github/workflows/skywalking.yaml                  |  22 ++
 .../command/ContinuousProfilingPolicy.java         |  49 ++++
 .../command/ContinuousProfilingPolicyCommand.java  |  45 ++++
 .../command/ContinuousProfilingReportCommand.java  |  26 +-
 apm-protocol/apm-network/src/main/proto            |   2 +-
 docs/en/changes/changes.md                         |   2 +
 docs/en/concepts-and-designs/mal.md                |   2 +
 .../ProcessEntityDescription.java                  |  49 ++++
 .../oap/meter/analyzer/dsl/SampleFamily.java       |  26 ++
 .../server/exporter/provider/MetricFormatter.java  |   4 -
 .../server/core/alarm/provider/NotifyHandler.java  |  15 +-
 .../core/alarm/provider/NotifyHandlerTest.java     |  33 ---
 .../skywalking/oap/server/core/CoreModule.java     |   4 +
 .../oap/server/core/CoreModuleProvider.java        |   6 +
 .../server/core/analysis/meter/MeterEntity.java    |  13 +
 .../oap/server/core/analysis/meter/ScopeType.java  |   1 +
 .../oap/server/core/command/CommandService.java    |  62 ++++-
 .../ContinuousProfilingMutationService.java        | 176 ++++++++++++++
 .../ContinuousProfilingQueryService.java           |  85 +++++++
 .../storage/ContinuousProfilingMonitorType.java    |  75 ++++++
 .../storage/ContinuousProfilingPolicy.java         |  80 +++++++
 .../ContinuousProfilingPolicyConfiguration.java    |  83 +++++++
 .../storage/ContinuousProfilingTargetType.java}    |  32 +--
 .../ebpf/EBPFProfilingMutationService.java         |  30 ++-
 .../profiling/ebpf/EBPFProfilingQueryService.java  |  52 +++-
 .../ebpf/storage/EBPFProfilingTargetType.java      |  29 ++-
 .../ebpf/storage/EBPFProfilingTaskRecord.java      |  20 ++
 .../ebpf/storage/EBPFProfilingTriggerType.java     |   5 +
 .../input/ContinuousProfilingPolicyCreation.java}  |  20 +-
 .../ContinuousProfilingPolicyItemCreation.java}    |  26 +-
 .../ContinuousProfilingPolicyTargetCreation.java}  |  19 +-
 .../oap/server/core/query/input/Entity.java        |   4 +
 .../query/type/ContinuousProfilingPolicyItem.java} |  24 +-
 .../type/ContinuousProfilingPolicyTarget.java}     |  23 +-
 .../query/type/ContinuousProfilingSetResult.java}  |  22 +-
 .../type/ContinuousProfilingSingleValueCause.java} |  19 +-
 .../type/ContinuousProfilingTriggeredCause.java}   |  21 +-
 .../query/type/ContinuousProfilingURICause.java}   |  23 +-
 .../server/core/query/type/EBPFProfilingTask.java  |  16 +-
 .../EBPFProfilingTaskContinuousProfiling.java}     |  26 +-
 .../oap/server/core/source/DefaultScopeDefine.java |   2 +
 .../skywalking/oap/server/core/source/Process.java |   3 +-
 .../oap/server/core/storage/StorageModule.java     |   2 +
 .../continuous/IContinuousProfilingPolicyDAO.java} |  30 +--
 .../profiling/ebpf/IEBPFProfilingTaskDAO.java      |  12 +-
 .../skywalking/oap/server/core/CoreModuleTest.java |   2 +-
 .../oap/query/graphql/GraphQLQueryProvider.java    |   4 +
 .../resolver/ContinuousProfilingMutation.java      |  52 ++++
 .../graphql/resolver/ContinuousProfilingQuery.java |  51 ++++
 .../resolver/EBPFProcessProfilingQuery.java        |   8 +-
 .../src/main/resources/query-protocol              |   2 +-
 .../ebpf/provider/EBPFReceiverModuleConfig.java}   |  20 +-
 .../ebpf/provider/EBPFReceiverProvider.java        |  18 +-
 .../handler/ContinuousProfilingServiceHandler.java | 266 +++++++++++++++++++++
 .../handler/EBPFProfilingServiceHandler.java       |  24 +-
 .../src/main/resources/application.yml             |   4 +-
 .../continuous-profiling.yaml                      |  30 +--
 .../plugin/banyandb/BanyanDBStorageProvider.java   |   3 +
 .../BanyanDBContinuousProfilingPolicyDAO.java      |  80 +++++++
 .../stream/BanyanDBEBPFProfilingTaskDAO.java       |  67 ++----
 .../StorageModuleElasticsearchProvider.java        |   6 +
 .../query/ContinuousProfilingPolicyEsDAO.java      |  78 ++++++
 .../query/EBPFProfilingTaskEsDAO.java              |  59 +----
 .../plugin/jdbc/common/JDBCStorageProvider.java    |   5 +
 .../dao/JDBCContinuousProfilingPolicyDAO.java      |  98 ++++++++
 .../jdbc/common/dao/JDBCEBPFProfilingTaskDAO.java  | 144 +++++------
 .../profiling/ebpf/continuous/Dockerfile.sqrt      |  23 ++
 .../banyandb/docker-compose.yml}                   |  60 +++--
 .../banyandb/e2e.yaml}                             |  39 +--
 .../profiling/ebpf/continuous/docker-compose.yml   |  62 +++++
 .../ebpf/continuous/es/docker-compose.yml          |  66 +++++
 .../es/e2e.yaml}                                   |  39 +--
 .../continuous/es/es-sharding/docker-compose.yml   |  67 ++++++
 .../es/es-sharding/e2e.yaml}                       |  39 +--
 .../expected/instance.yml}                         |  22 +-
 .../expected/metrics-has-value.yml}                |  17 +-
 .../expected/policy-set.yml}                       |  19 +-
 .../expected/process.yml}                          |  31 ++-
 .../expected/profiling-analysis.yml}               |  27 +--
 .../expected/profiling-schedule-list.yml}          |  40 ++--
 .../expected/query-policy.yml}                     |  25 +-
 .../expected/service.yml}                          |  22 +-
 .../expected/trigger-task.yml}                     |  26 +-
 .../ebpf/continuous/h2/docker-compose.yml          |  66 +++++
 .../h2/e2e.yaml}                                   |  39 +--
 .../ebpf/continuous/mysql/docker-compose.yml       |  68 ++++++
 .../mysql/e2e.yaml}                                |  39 +--
 .../ebpf/continuous/opensearch/docker-compose.yml  |  71 ++++++
 .../opensearch/e2e.yaml}                           |  39 +--
 .../cases/profiling/ebpf/continuous/policy.yaml    |  41 ++++
 .../ebpf/continuous/postgres/docker-compose.yml    |  67 ++++++
 .../postgres/e2e.yaml}                             |  39 +--
 .../profiling/ebpf/continuous/profiling-cases.yaml |  55 +++++
 .../e2e-v2/cases/profiling/ebpf/continuous/sqrt.go |  32 +++
 .../profiling/ebpf/network/rover_configs.yaml      |  15 +-
 .../ebpf/offcpu/expected/profiling-task-list.yml   |   3 +
 .../ebpf/oncpu/expected/profiling-task-list.yml    |   3 +
 test/e2e-v2/script/env                             |   4 +-
 98 files changed, 2804 insertions(+), 742 deletions(-)

diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml
index f0bb2622bd..e74faf1cd0 100644
--- a/.github/workflows/skywalking.yaml
+++ b/.github/workflows/skywalking.yaml
@@ -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
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicy.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicy.java
new file mode 100644
index 0000000000..b80e97dab7
--- /dev/null
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicy.java
@@ -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;
+    }
+}
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicyCommand.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicyCommand.java
new file mode 100644
index 0000000000..c12140520f
--- /dev/null
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingPolicyCommand.java
@@ -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;
+    }
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingReportCommand.java
similarity index 50%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingReportCommand.java
index bc9fbe9240..19fe2ea24c 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/oap/server/network/trace/component/command/ContinuousProfilingReportCommand.java
@@ -16,16 +16,26 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.network.trace.component.command;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import org.apache.skywalking.apm.network.common.v3.Command;
+import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+public class ContinuousProfilingReportCommand extends BaseCommand implements Serializable {
+    public static final String NAME = "ContinuousProfilingReportTask";
 
-        Assertions.assertEquals(38, coreModule.services().length);
+    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;
     }
 }
diff --git a/apm-protocol/apm-network/src/main/proto b/apm-protocol/apm-network/src/main/proto
index 9c7a0bf8e0..0da9c8b3e1 160000
--- a/apm-protocol/apm-network/src/main/proto
+++ b/apm-protocol/apm-network/src/main/proto
@@ -1 +1 @@
-Subproject commit 9c7a0bf8e0c2195280adf65f50cbd3161dd588ff
+Subproject commit 0da9c8b3e111fb51c9f8854cae16d4519462ecfe
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index a2c8424448..1e8dc710c3 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -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
 
diff --git a/docs/en/concepts-and-designs/mal.md b/docs/en/concepts-and-designs/mal.md
index a1ba6726cd..b7d902403f 100644
--- a/docs/en/concepts-and-designs/mal.md
+++ b/docs/en/concepts-and-designs/mal.md
@@ -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`.
diff --git a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ProcessEntityDescription.java b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ProcessEntityDescription.java
new file mode 100644
index 0000000000..9759061eab
--- /dev/null
+++ b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ProcessEntityDescription.java
@@ -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();
+    }
+}
\ No newline at end of file
diff --git a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
index b30578782c..96326e3ecb 100644
--- a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
+++ b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
@@ -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(
diff --git a/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/MetricFormatter.java b/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/MetricFormatter.java
index 2319a8dbc0..bd281d9a5a 100644
--- a/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/MetricFormatter.java
+++ b/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/MetricFormatter.java
@@ -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 {
diff --git a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
index dffe827b85..ee14741476 100644
--- a/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
+++ b/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandler.java
@@ -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;
         }
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
index 5f887eb320..234c134de5 100644
--- a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
@@ -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() {
 
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
index 66d9934e97..d277e4ba7f 100755
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
@@ -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) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
index 91f411927e..a1a6780d64 100755
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
@@ -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()));
 
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
index 18feeddc65..03961eff3e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
@@ -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) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
index 4f89cc77c2..675ba23af4 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
@@ -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);
 
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/command/CommandService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/command/CommandService.java
index 48b826b909..5698cfbc16 100755
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/command/CommandService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/command/CommandService.java
@@ -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();
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingMutationService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingMutationService.java
new file mode 100644
index 0000000000..752ea3d140
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingMutationService.java
@@ -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();
+    }
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingQueryService.java
new file mode 100644
index 0000000000..d8765b4c40
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/ContinuousProfilingQueryService.java
@@ -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());
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingMonitorType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingMonitorType.java
new file mode 100644
index 0000000000..4486ae7389
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingMonitorType.java
@@ -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;
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicy.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicy.java
new file mode 100644
index 0000000000..195d03bf3a
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicy.java
@@ -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());
+        }
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicyConfiguration.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicyConfiguration.java
new file mode 100644
index 0000000000..4dd58693be
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingPolicyConfiguration.java
@@ -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<>();
+    }
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingTargetType.java
similarity index 63%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingTargetType.java
index 5b7a3ab428..a5fc41e750 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/continuous/storage/ContinuousProfilingTargetType.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core.profiling.ebpf.storage;
+package org.apache.skywalking.oap.server.core.profiling.continuous.storage;
 
 import org.apache.skywalking.oap.server.core.UnexpectedException;
 
@@ -25,39 +25,33 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-/**
- * eBPF type for profiling the process
- */
-public enum EBPFProfilingTargetType {
+public enum ContinuousProfilingTargetType {
 
     UNKNOWN(0),
-
     ON_CPU(1),
-
     OFF_CPU(2),
+    NETWORK(3);
 
-    NETWORK(3),
-    ;
     private final int value;
-    private static final Map<Integer, EBPFProfilingTargetType> DICTIONARY = new HashMap<>();
+    private static final Map<Integer, ContinuousProfilingTargetType> DICTIONARY = new HashMap<>();
 
     static {
-        Arrays.stream(EBPFProfilingTargetType.values()).collect(Collectors.toMap(EBPFProfilingTargetType::value, type -> type)).forEach(DICTIONARY::put);
+        DICTIONARY.putAll(Arrays.stream(ContinuousProfilingTargetType.values()).collect(Collectors.toMap(ContinuousProfilingTargetType::value, type -> type)));
     }
 
-    EBPFProfilingTargetType(int value) {
+    ContinuousProfilingTargetType(int value) {
         this.value = value;
     }
 
-    public int value() {
-        return value;
-    }
-
-    public static EBPFProfilingTargetType valueOf(int value) {
-        EBPFProfilingTargetType type = DICTIONARY.get(value);
+    public static ContinuousProfilingTargetType valueOf(int value) {
+        ContinuousProfilingTargetType type = DICTIONARY.get(value);
         if (type == null) {
-            throw new UnexpectedException("Unknown EBPFProfilingTargetType value");
+            throw new UnexpectedException("Unknown ContinuousProfilingTargetType value");
         }
         return type;
     }
+
+    public int value() {
+        return this.value;
+    }
 }
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingMutationService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingMutationService.java
index 63aa15905f..7ae11df534 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingMutationService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingMutationService.java
@@ -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";
             }
         }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingQueryService.java
index 066a65b4cd..41cba60b96 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/EBPFProfilingQueryService.java
@@ -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());
+        }
+        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 new ArrayList<>(tmpMap.values());
+        return result;
     }
 
     public List<EBPFProfilingSchedule> queryEBPFProfilingSchedules(String taskId) throws Exception {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java
index 5b7a3ab428..7d10afcd6b 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTargetType.java
@@ -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;
+    }
 }
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTaskRecord.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTaskRecord.java
index ca497ddd48..00d33db75a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTaskRecord.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTaskRecord.java
@@ -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());
         }
     }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTriggerType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTriggerType.java
index 08d29783de..f1df1729f9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTriggerType.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/ebpf/storage/EBPFProfilingTriggerType.java
@@ -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<>();
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyCreation.java
similarity index 71%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyCreation.java
index bc9fbe9240..e0e0ce7ab1 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyCreation.java
@@ -16,16 +16,16 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.input;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
-}
+@Data
+public class ContinuousProfilingPolicyCreation {
+    // service of the policy
+    private String serviceId;
+    // target of the policy
+    private List<ContinuousProfilingPolicyTargetCreation> targets;
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyItemCreation.java
similarity index 51%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyItemCreation.java
index bc9fbe9240..78f24a6c87 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyItemCreation.java
@@ -16,16 +16,24 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.input;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+@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;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyTargetCreation.java
similarity index 64%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyTargetCreation.java
index bc9fbe9240..48b4140d0d 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/ContinuousProfilingPolicyTargetCreation.java
@@ -16,16 +16,17 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.input;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+@Data
+public class ContinuousProfilingPolicyTargetCreation {
+    // policy profiling target
+    private ContinuousProfilingTargetType targetType;
+    // target check thresholds
+    private List<ContinuousProfilingPolicyItemCreation> checkItems;
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
index 1e615e27f8..d7864fedf2 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
@@ -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(
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyItem.java
similarity index 61%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyItem.java
index bc9fbe9240..76053c22bb 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyItem.java
@@ -16,16 +16,22 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+/**
+ * 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;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyTarget.java
similarity index 61%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyTarget.java
index bc9fbe9240..ca642a2c87 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingPolicyTarget.java
@@ -16,16 +16,21 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingTargetType;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ContinuousProfilingPolicyTarget {
+    private ContinuousProfilingTargetType type;
+    private List<ContinuousProfilingPolicyItem> checkItems;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSetResult.java
similarity index 71%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSetResult.java
index bc9fbe9240..948bc060a0 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSetResult.java
@@ -16,16 +16,18 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
-
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ContinuousProfilingSetResult {
+    private boolean status;
+    private String errorReason;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSingleValueCause.java
similarity index 71%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSingleValueCause.java
index bc9fbe9240..7326c125cd 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingSingleValueCause.java
@@ -16,16 +16,15 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
-
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+/**
+ * Continuous profiling single value based cause
+ */
+@Data
+public class ContinuousProfilingSingleValueCause {
+    private long threshold;
+    private long current;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingTriggeredCause.java
similarity index 64%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingTriggeredCause.java
index bc9fbe9240..1704d8e689 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingTriggeredCause.java
@@ -16,16 +16,17 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingMonitorType;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
-
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+/**
+ * Continuous profiling task single trigger casus
+ */
+@Data
+public class ContinuousProfilingTriggeredCause {
+    private ContinuousProfilingMonitorType type;
+    private ContinuousProfilingSingleValueCause singleValue;
+    private ContinuousProfilingURICause uri;
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingURICause.java
similarity index 71%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingURICause.java
index bc9fbe9240..6c857eabbd 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ContinuousProfilingURICause.java
@@ -16,16 +16,17 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
-
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
-}
+/**
+ * Continuous profiling task URI-based cause
+ */
+@Data
+public class ContinuousProfilingURICause {
+    private String uriRegex;
+    private String uriPath;
+    private long threshold;
+    private long current;
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTask.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTask.java
index 87b4706499..3b4fc9671c 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTask.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTask.java
@@ -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;
-    }
 }
\ No newline at end of file
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTaskContinuousProfiling.java
similarity index 64%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTaskContinuousProfiling.java
index bc9fbe9240..2909873ac6 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EBPFProfilingTaskContinuousProfiling.java
@@ -16,16 +16,24 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.query.type;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Data;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+import java.util.ArrayList;
+import java.util.List;
 
-        Assertions.assertEquals(38, coreModule.services().length);
+/**
+ * Continuous profiling task configuration
+ */
+@Data
+public class EBPFProfilingTaskContinuousProfiling {
+    private String processId;
+    private String processName;
+
+    private List<ContinuousProfilingTriggeredCause> causes;
+
+    public EBPFProfilingTaskContinuousProfiling() {
+        this.causes = new ArrayList<>();
     }
-}
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
index 17364211f3..df445c002b 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
@@ -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.
      */
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Process.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Process.java
index b7480741d8..4c2cdd1894 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Process.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Process.java
@@ -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;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
index d35c7b8099..c25ebdc61d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
@@ -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,
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/continuous/IContinuousProfilingPolicyDAO.java
similarity index 56%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/continuous/IContinuousProfilingPolicyDAO.java
index 4f89cc77c2..f63596d47a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/continuous/IContinuousProfilingPolicyDAO.java
@@ -16,22 +16,24 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core.analysis.meter;
+package org.apache.skywalking.oap.server.core.storage.profiling.continuous;
 
-import lombok.Getter;
-import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
+import org.apache.skywalking.oap.server.core.profiling.continuous.storage.ContinuousProfilingPolicy;
+import org.apache.skywalking.oap.server.core.storage.DAO;
 
-public enum ScopeType {
-    SERVICE(DefaultScopeDefine.SERVICE),
-    SERVICE_INSTANCE(DefaultScopeDefine.SERVICE_INSTANCE),
-    ENDPOINT(DefaultScopeDefine.ENDPOINT),
-    SERVICE_RELATION(DefaultScopeDefine.SERVICE_RELATION),
-    PROCESS_RELATION(DefaultScopeDefine.PROCESS_RELATION);
+import java.io.IOException;
+import java.util.List;
 
-    @Getter
-    private final int scopeId;
+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;
 
-    ScopeType(final int scopeId) {
-        this.scopeId = scopeId;
-    }
 }
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/ebpf/IEBPFProfilingTaskDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/ebpf/IEBPFProfilingTaskDAO.java
index c3d530daa2..58ef121dbd 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/ebpf/IEBPFProfilingTaskDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/profiling/ebpf/IEBPFProfilingTaskDAO.java
@@ -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;
 }
\ No newline at end of file
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
index bc9fbe9240..7e65b6dac0 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
@@ -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);
     }
 }
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryProvider.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryProvider.java
index 845105ee1b..47f040ac26 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryProvider.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/GraphQLQueryProvider.java
@@ -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()));
 
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingMutation.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingMutation.java
new file mode 100644
index 0000000000..eace363b70
--- /dev/null
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingMutation.java
@@ -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);
+    }
+
+}
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingQuery.java
new file mode 100644
index 0000000000..cdbf88a7b0
--- /dev/null
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/ContinuousProfilingQuery.java
@@ -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);
+    }
+
+}
\ No newline at end of file
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/EBPFProcessProfilingQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/EBPFProcessProfilingQuery.java
index f94f3b48f9..acd2d4979b 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/EBPFProcessProfilingQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/EBPFProcessProfilingQuery.java
@@ -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 {
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
index 450328c644..4749946962 160000
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
@@ -1 +1 @@
-Subproject commit 450328c6445d4dc50a868a0b797a14755f1d82cc
+Subproject commit 4749946962b9c685111876d1abe8c745d3cf3253
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverModuleConfig.java
similarity index 65%
copy from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
copy to oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverModuleConfig.java
index bc9fbe9240..0cfbadaadc 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/CoreModuleTest.java
+++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverModuleConfig.java
@@ -16,16 +16,18 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.receiver.ebpf.provider;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.library.module.ModuleConfig;
 
-public class CoreModuleTest {
-    @Test
-    public void testOpenServiceList() {
-        CoreModule coreModule = new CoreModule();
+@Getter
+public class EBPFReceiverModuleConfig extends ModuleConfig {
 
-        Assertions.assertEquals(38, coreModule.services().length);
-    }
+    /**
+     * The continuous profiling policy cache time, Unit is second. Default value is 60 seconds.
+     */
+    @Setter
+    private int continuousPolicyCacheTimeout = 60;
 }
diff --git a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverProvider.java b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverProvider.java
index 52ac5d6dbb..8b3c76c796 100644
--- a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverProvider.java
+++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/EBPFReceiverProvider.java
@@ -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
diff --git a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/ContinuousProfilingServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/ContinuousProfilingServiceHandler.java
new file mode 100644
index 0000000000..b818b54cdb
--- /dev/null
+++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/ContinuousProfilingServiceHandler.java
@@ -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;
+    }
+}
\ No newline at end of file
diff --git a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/EBPFProfilingServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/EBPFProfilingServiceHandler.java
index fe04fd91d4..e862b435d3 100644
--- a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/EBPFProfilingServiceHandler.java
+++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/EBPFProfilingServiceHandler.java
@@ -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())));
             }
         }
diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml
index 9ec171eeea..5b9a5d9bbb 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -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}
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/oap-server/server-starter/src/main/resources/meter-analyzer-config/continuous-profiling.yaml
similarity index 50%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to oap-server/server-starter/src/main/resources/meter-analyzer-config/continuous-profiling.yaml
index faa04bc518..a5c6bdddd7 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/oap-server/server-starter/src/main/resources/meter-analyzer-config/continuous-profiling.yaml
@@ -13,20 +13,16 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+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"])
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
index 882fffc376..ee01d0f94b 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
@@ -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));
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBContinuousProfilingPolicyDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBContinuousProfilingPolicyDAO.java
new file mode 100644
index 0000000000..c37160261d
--- /dev/null
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBContinuousProfilingPolicyDAO.java
@@ -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());
+    }
+
+}
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBEBPFProfilingTaskDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBEBPFProfilingTaskDAO.java
index 6825bc4296..422d9d9dbe 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBEBPFProfilingTaskDAO.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/stream/BanyanDBEBPFProfilingTaskDAO.java
@@ -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;
     }
 }
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
index 41faa852c5..c8e74d13cd 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
@@ -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)
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ContinuousProfilingPolicyEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ContinuousProfilingPolicyEsDAO.java
new file mode 100644
index 0000000000..72ef40fde4
--- /dev/null
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/ContinuousProfilingPolicyEsDAO.java
@@ -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;
+    }
+
+}
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/EBPFProfilingTaskEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/EBPFProfilingTaskEsDAO.java
index de23ed7a28..8a51f6fad0 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/EBPFProfilingTaskEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/EBPFProfilingTaskEsDAO.java
@@ -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));
     }
 }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
index 669b1a7075..6c000d8707 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
@@ -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));
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCContinuousProfilingPolicyDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCContinuousProfilingPolicyDAO.java
new file mode 100644
index 0000000000..00222e15dc
--- /dev/null
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCContinuousProfilingPolicyDAO.java
@@ -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;
+    }
+}
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCEBPFProfilingTaskDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCEBPFProfilingTaskDAO.java
index 33a7ec5ba9..ab6724480b 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCEBPFProfilingTaskDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCEBPFProfilingTaskDAO.java
@@ -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;
     }
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/Dockerfile.sqrt b/test/e2e-v2/cases/profiling/ebpf/continuous/Dockerfile.sqrt
new file mode 100644
index 0000000000..432e696187
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/Dockerfile.sqrt
@@ -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"]
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/docker-compose.yml
similarity index 54%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/docker-compose.yml
index faa04bc518..617c1a2032 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/docker-compose.yml
@@ -13,20 +13,46 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/banyandb/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/docker-compose.yml
new file mode 100644
index 0000000000..21427a5b1a
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/docker-compose.yml
@@ -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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/es/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/es/docker-compose.yml
new file mode 100644
index 0000000000..d9947efd9a
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/es/docker-compose.yml
@@ -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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/es/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/es/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/es/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/docker-compose.yml
new file mode 100644
index 0000000000..6fcf6b4f74
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/docker-compose.yml
@@ -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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/e2e.yaml
similarity index 55%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/e2e.yaml
index faa04bc518..36ed0ddd5b 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/es/es-sharding/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/instance.yml
similarity index 66%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/instance.yml
index faa04bc518..5f276502f7 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/instance.yml
@@ -14,19 +14,9 @@
 # limitations under the License.
 
 {{- contains . }}
-- taskid: {{ notEmpty .taskid }}
-  serviceid: {{ b64enc "sqrt" }}.1
-  servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+- id: {{ b64enc "sqrt" }}.1_{{ b64enc "test-instance" }}
+  name: test-instance
+  attributes: []
+  language: UNKNOWN
+  instanceuuid: {{ notEmpty .instanceuuid }}
+{{- end }}
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/metrics-has-value.yml
similarity index 66%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/metrics-has-value.yml
index faa04bc518..d9c49854c9 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/metrics-has-value.yml
@@ -14,19 +14,6 @@
 # limitations under the License.
 
 {{- contains . }}
-- taskid: {{ notEmpty .taskid }}
-  serviceid: {{ b64enc "sqrt" }}.1
-  servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
+- key: {{ notEmpty .key }}
+  value: {{ ge .value 1 }}
 {{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/policy-set.yml
similarity index 64%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/policy-set.yml
index faa04bc518..a51bce78cc 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/policy-set.yml
@@ -13,20 +13,5 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+status: true
+errorreason: null
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/process.yml
similarity index 65%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/process.yml
index faa04bc518..b865a5d775 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/process.yml
@@ -14,19 +14,24 @@
 # limitations under the License.
 
 {{- contains . }}
-- taskid: {{ notEmpty .taskid }}
+- id: {{ notEmpty .id }}
+  name: sqrt
   serviceid: {{ b64enc "sqrt" }}.1
   servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
+  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 }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+  labels: []
+{{- end }}
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-analysis.yml
similarity index 64%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-analysis.yml
index faa04bc518..c8fe9d3c15 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-analysis.yml
@@ -13,20 +13,15 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
+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 }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-schedule-list.yml
similarity index 53%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-schedule-list.yml
index faa04bc518..44f6a86e2e 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/profiling-schedule-list.yml
@@ -14,19 +14,27 @@
 # limitations under the License.
 
 {{- contains . }}
-- taskid: {{ notEmpty .taskid }}
-  serviceid: {{ b64enc "sqrt" }}.1
-  servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+- 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 }}
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/query-policy.yml
similarity index 64%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/query-policy.yml
index faa04bc518..8e8ed3946d 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/query-policy.yml
@@ -13,20 +13,11 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+- type: ON_CPU
+  checkitems:
+    - type: PROCESS_CPU
+      threshold: "10"
+      period: 10
+      count: 3
+      urilist: []
+      uriregex: null
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/service.yml
similarity index 66%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/service.yml
index faa04bc518..4c0ee2b0c0 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/service.yml
@@ -14,19 +14,11 @@
 # limitations under the License.
 
 {{- contains . }}
-- taskid: {{ notEmpty .taskid }}
-  serviceid: {{ b64enc "sqrt" }}.1
-  servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
+- id: {{ b64enc "sqrt" }}.1
+  name: sqrt
+  group: ""
+  shortname: sqrt
+  layers:
+    - OS_LINUX
+  normal: true
 {{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/trigger-task.yml
similarity index 62%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/expected/trigger-task.yml
index faa04bc518..0f7f395569 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/expected/trigger-task.yml
@@ -17,16 +17,20 @@
 - taskid: {{ notEmpty .taskid }}
   serviceid: {{ b64enc "sqrt" }}.1
   servicename: sqrt
-  serviceinstanceid: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
+  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: {{ gt .createtime 0 }}
+  createtime: {{ ge .createtime 1 }}
 {{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/h2/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/h2/docker-compose.yml
new file mode 100644
index 0000000000..392cadf080
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/h2/docker-compose.yml
@@ -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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/h2/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/h2/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/h2/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/mysql/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/mysql/docker-compose.yml
new file mode 100644
index 0000000000..45a5208ffc
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/mysql/docker-compose.yml
@@ -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:
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/mysql/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/mysql/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/mysql/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/docker-compose.yml
new file mode 100644
index 0000000000..f2408e2d5a
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/docker-compose.yml
@@ -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:
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/opensearch/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/policy.yaml b/test/e2e-v2/cases/profiling/ebpf/continuous/policy.yaml
new file mode 100644
index 0000000000..9cbafe249b
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/policy.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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/docker-compose.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/docker-compose.yml
new file mode 100644
index 0000000000..beb0d2ff7f
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/docker-compose.yml
@@ -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:
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml
similarity index 56%
copy from test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
copy to test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml
index faa04bc518..f8fdca0f49 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml
@@ -13,20 +13,25 @@
 # 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: null
-  serviceinstancename: null
-  processlabels:
-    {{- contains .processlabels }}
-    - e2e-label1
-    - e2e-label2
-    {{- end }}
-  taskstarttime: {{ gt .taskstarttime 0 }}
-  triggertype: FIXED_TIME
-  fixedtriggerduration: 60
-  targettype: ON_CPU
-  createtime: {{ gt .createtime 0 }}
-{{- end }}
\ No newline at end of file
+# 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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/profiling-cases.yaml b/test/e2e-v2/cases/profiling/ebpf/continuous/profiling-cases.yaml
new file mode 100644
index 0000000000..9ff5f22fad
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/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
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/sqrt.go b/test/e2e-v2/cases/profiling/ebpf/continuous/sqrt.go
new file mode 100644
index 0000000000..1fc3d01de2
--- /dev/null
+++ b/test/e2e-v2/cases/profiling/ebpf/continuous/sqrt.go
@@ -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()
+}
diff --git a/test/e2e-v2/cases/profiling/ebpf/network/rover_configs.yaml b/test/e2e-v2/cases/profiling/ebpf/network/rover_configs.yaml
index 4d94725350..4bbf8cb952 100644
--- a/test/e2e-v2/cases/profiling/ebpf/network/rover_configs.yaml
+++ b/test/e2e-v2/cases/profiling/ebpf/network/rover_configs.yaml
@@ -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}
\ No newline at end of file
+            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}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/offcpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/offcpu/expected/profiling-task-list.yml
index 50eeab15dd..97a97df48a 100644
--- a/test/e2e-v2/cases/profiling/ebpf/offcpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/offcpu/expected/profiling-task-list.yml
@@ -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 }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml b/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
index faa04bc518..f357fd6f08 100644
--- a/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
+++ b/test/e2e-v2/cases/profiling/ebpf/oncpu/expected/profiling-task-list.yml
@@ -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 }}
\ No newline at end of file
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/script/env
index 32eb1e5fa4..c019b39d73 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/script/env
@@ -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