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

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


The following commit(s) were added to refs/heads/master by this push:
     new f05e91247a [refactor] refactor auto discovery http sd (#3300)
f05e91247a is described below

commit f05e91247ae115742dfe681f4a7a870d606befe4
Author: tomsun28 <tomsu...@outlook.com>
AuthorDate: Sun May 4 00:07:06 2025 +0800

    [refactor] refactor auto discovery http sd (#3300)
    
    Signed-off-by: tomsun28 <tomsu...@outlook.com>
---
 .../collector/collect/sd/HttpSdCollectImpl.java    |   2 +-
 .../collector/dispatch/CommonDispatcher.java       |   3 +-
 .../collector/dispatch/DispatchConstants.java      |   2 +-
 .../common/constants/CommonConstants.java          | 111 +----
 .../hertzbeat/common/entity/job/Metrics.java       |   7 +-
 .../entity/job/protocol/CommonRequestProtocol.java |   3 +-
 .../protocol/HttpSdProtocol.java}                  |  14 +-
 .../hertzbeat/common/entity/manager/Monitor.java   |   4 +
 .../common/entity/manager/MonitorBind.java         |  15 +-
 .../common/entity/sd/ServiceDiscoveryProtocol.java |  67 ---
 .../common/support/valid/HostParamValidator.java   |   8 +-
 .../hertzbeat/common/util/SdMonitorOperator.java   | 151 -------
 .../support/vaild/HostParamValidatorTest.java      |   6 +-
 .../component/sd/ServiceDiscoveryWorker.java       | 118 +++---
 .../manager/controller/MonitorsController.java     |  12 -
 .../hertzbeat/manager/dao/MonitorBindDao.java      |  16 +-
 .../hertzbeat/manager/pojo/dto/MonitorDto.java     |   4 +-
 .../hertzbeat/manager/scheduler/SchedulerInit.java |  25 +-
 .../hertzbeat/manager/service/MonitorService.java  |  17 +-
 .../manager/service/impl/AppServiceImpl.java       |   4 -
 .../manager/service/impl/MonitorServiceImpl.java   | 455 ++++++---------------
 .../define/{app-push.yml => app-http_sd.yml}       |  74 ++--
 .../src/main/resources/define/app-push.yml         |   2 +-
 .../manager/controller/MonitorsControllerTest.java |  11 -
 .../manager/service/MonitorServiceTest.java        |   2 +-
 web-app/src/app/pojo/Monitor.ts                    |   1 +
 .../monitor-detail/monitor-detail.component.ts     |   3 +
 .../monitor-edit/monitor-edit.component.html       |   3 +
 .../monitor/monitor-edit/monitor-edit.component.ts | 129 +++++-
 .../monitor-form/monitor-form.component.html       |  41 ++
 .../monitor/monitor-form/monitor-form.component.ts |  39 +-
 .../monitor-list/monitor-list.component.html       |   5 +
 .../monitor/monitor-list/monitor-list.component.ts |  62 ++-
 .../monitor/monitor-new/monitor-new.component.html |   3 +
 .../monitor/monitor-new/monitor-new.component.ts   | 118 +++++-
 .../app/routes/setting/define/define.component.ts  |   3 +
 web-app/src/assets/i18n/en-US.json                 |   8 +-
 web-app/src/assets/i18n/ja-JP.json                 |   2 +
 web-app/src/assets/i18n/pt-BR.json                 |   2 +
 web-app/src/assets/i18n/zh-CN.json                 |   2 +
 web-app/src/assets/i18n/zh-TW.json                 |   2 +
 41 files changed, 642 insertions(+), 914 deletions(-)

diff --git 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/HttpSdCollectImpl.java
 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/HttpSdCollectImpl.java
index 0935b9fddc..0de9598c97 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/HttpSdCollectImpl.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/sd/HttpSdCollectImpl.java
@@ -52,7 +52,7 @@ public class HttpSdCollectImpl extends AbstractCollect {
     @Override
     public void collect(CollectRep.MetricsData.Builder builder, Metrics 
metrics) {
         List<ConnectionConfig> configList = Lists.newArrayList();
-        HttpUriRequest request = 
RequestBuilder.get().setUri(metrics.getSdProtocol().getSdSource()).build();
+        HttpUriRequest request = 
RequestBuilder.get().setUri(metrics.getHttp_sd().getUrl()).build();
 
         try (CloseableHttpResponse response = 
CommonHttpClient.getHttpClient().execute(request)) {
             int statusCode = response.getStatusLine().getStatusCode();
diff --git 
a/hertzbeat-collector/hertzbeat-collector-collector/src/main/java/org/apache/hertzbeat/collector/dispatch/CommonDispatcher.java
 
b/hertzbeat-collector/hertzbeat-collector-collector/src/main/java/org/apache/hertzbeat/collector/dispatch/CommonDispatcher.java
index b592ea0e1f..1262e57967 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-collector/src/main/java/org/apache/hertzbeat/collector/dispatch/CommonDispatcher.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-collector/src/main/java/org/apache/hertzbeat/collector/dispatch/CommonDispatcher.java
@@ -281,7 +281,8 @@ public class CommonDispatcher implements 
MetricsTaskDispatch, CollectDataDispatc
             }
             // If it is an asynchronous periodic cyclic task, directly 
response the collected data
             if (job.isSd()) {
-                commonDataQueue.sendServiceDiscoveryData(metricsData);
+                CollectRep.MetricsData sdMetricsData = 
CollectRep.MetricsData.newBuilder(metricsData).build();
+                commonDataQueue.sendServiceDiscoveryData(sdMetricsData);
             }
             commonDataQueue.sendMetricsData(metricsData);
         } else {
diff --git 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
index eea60acebf..b8ee6d11fc 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
@@ -126,7 +126,7 @@ public interface DispatchConstants {
     /**
      * protocol http sd
      */
-    String PROTOCOL_HTTP_SD = "httpsd";
+    String PROTOCOL_HTTP_SD = "http_sd";
     /**
      * protocol redfish
      */
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/CommonConstants.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/CommonConstants.java
index 24e1d15433..0e036d3010 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/CommonConstants.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/constants/CommonConstants.java
@@ -73,14 +73,14 @@ public interface CommonConstants {
     byte MONITOR_DOWN_CODE = 0x02;
 
     /**
-     * Monitor bind type, 0: monitor that auto-created by sd
+     * scrape type static
      */
-    byte MONITOR_BIND_TYPE_SD_SUB_MONITOR = 0x00;
+    String SCRAPE_STATIC = "static";
 
     /**
-     * Monitor bind type, 1: the main monitor of sd
+     * scrape type 
      */
-    byte MONITOR_BIND_TYPE_SD_MAIN_MONITOR = 0x01;
+    String SCRAPE_HTTP_SD = "http_sd";
 
     /**
      * label key: instance
@@ -192,11 +192,6 @@ public interface CommonConstants {
      */
     String PROM_VALUE = "value";
 
-    /**
-     * Monitor total availability metrics
-     */
-    String AVAILABILITY = "availability";
-
     /**
      * Parameter Type Number
      */
@@ -222,104 +217,6 @@ public interface CommonConstants {
      */
     byte PARAM_TYPE_ARRAY = 4;
 
-    /**
-     * Authentication type Account password
-     */
-    byte AUTH_TYPE_PASSWORD = 1;
-
-    /**
-     * Authentication type GitHub three-party login
-     */
-    byte AUTH_TYPE_GITHUB = 2;
-
-    /**
-     * Authentication type WeChat three-party login
-     */
-    byte AUTH_TYPE_WEIXIN = 3;
-
-    /**
-     * Authentication type GITEE three-party login
-     */
-    byte AUTH_TYPE_GITEE = 5;
-
-    /**
-     * inner default label key __instance__
-     */
-    String LABEL_INNER_KEY_INSTANCE = "__instance__";
-    
-    /**
-     * Inside the tag: monitorId Monitor task ID
-     */
-    String TAG_MONITOR_ID = "monitorId";
-
-    /**
-     * Inside the tag: monitorName Task name
-     */
-    String TAG_MONITOR_NAME = "monitorName";
-
-    /**
-     * Inside the tag: indicate that this monitor is auto-created by main 
monitor
-     */
-    String TAG_AUTO_CREATED = "autoCreated";
-
-    /**
-     * Inside the tag: indicate that this monitor is a main monitor which 
provides service discovery
-     */
-    String TAG_SD_MAIN_MONITOR = "sdMainMonitor";
-
-    /**
-     * Inside the tag: monitorHost Task host
-     */
-    String TAG_MONITOR_HOST = "monitorHost";
-
-    /**
-     * Inside the tag: policyId Alarm threshold rule ID
-     */
-    String TAG_THRESHOLD_ID = "thresholdId";
-
-    /**
-     * Inside the tag: app Type of monitoring
-     */
-    String TAG_MONITOR_APP = "app";
-
-    /**
-     * Inside the tag: metrics
-     */
-    String TAG_METRICS = "metrics";
-
-    /**
-     * Inside the tag: metric
-     */
-    String TAG_METRIC = "metric";
-
-    /**
-     * Inside the tag: code
-     */
-    String TAG_CODE = "code";
-
-    /**
-     * Tag Type: Auto-generated
-     */
-    byte TAG_TYPE_AUTO_GENERATE = 0;
-    /**
-     * Tag Type: User-generated
-     */
-    byte TAG_TYPE_USER_GENERATE = 1;
-    /**
-     * Tag Type: System preset
-     */
-    byte TAG_TYPE_SYSTEM_PRESET = 2;
-
-    /**
-     * notice_period type Type field, daily type
-     */
-    int NOTICE_PERIOD_DAILY = 0;
-
-    /**
-     * key is receiver.id, value is noticePeriod cache key prefix
-     */
-    String RECEIVER_NOTICE_PERIOD_CACHE_PREFIX = "receiver_notice_period:";
-
     /**
      * cache key notice_rule
      */
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
index e56bbf93b6..49eafe3ae4 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
@@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.entity.job.protocol.DnsProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.FtpProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
+import org.apache.hertzbeat.common.entity.job.protocol.HttpSdProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.ModbusProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.PlcProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
@@ -63,7 +64,6 @@ import 
org.apache.hertzbeat.common.entity.job.protocol.TelnetProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.UdpProtocol;
 import org.apache.hertzbeat.common.entity.job.protocol.WebsocketProtocol;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
-import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
 
 /**
  * Details of the monitoring metrics collected
@@ -74,6 +74,7 @@ import 
org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
 @NoArgsConstructor
 @Builder
 @Slf4j
+@SuppressWarnings("checkstyle:MemberName")
 public class Metrics {
 
     /**
@@ -260,9 +261,9 @@ public class Metrics {
      */
     private KafkaProtocol kclient;
     /**
-     * Collect sd data protocol
+     * http sd protocol
      */
-    private ServiceDiscoveryProtocol sdProtocol;
+    private HttpSdProtocol http_sd;
     /**
      * Monitoring configuration information using the public plc protocol
      */
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/CommonRequestProtocol.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/CommonRequestProtocol.java
index eb1c0d5c9e..b5e0edd6ef 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/CommonRequestProtocol.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/CommonRequestProtocol.java
@@ -21,7 +21,8 @@ package org.apache.hertzbeat.common.entity.job.protocol;
  * Define common field method for each protocol in {@link 
org.apache.hertzbeat.common.entity.job.Metrics}
  */
 public interface CommonRequestProtocol {
+    
     void setHost(String host);
 
     void setPort(String port);
-}
\ No newline at end of file
+}
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/SdMonitorParam.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpSdProtocol.java
similarity index 81%
rename from 
hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/SdMonitorParam.java
rename to 
hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpSdProtocol.java
index 33ceb7dbf5..67d50fa6e5 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/SdMonitorParam.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/HttpSdProtocol.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.hertzbeat.common.entity.manager;
+package org.apache.hertzbeat.common.entity.job.protocol;
 
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -23,15 +23,13 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * sd monitor param
+ * Dns protocol
  */
 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
-public class SdMonitorParam {
-    private String detectedHost;
-    private String detectedPort;
-    private Param sdParam;
-    private Long bizId;
-}
\ No newline at end of file
+public class HttpSdProtocol implements Protocol {
+    
+    private String url;
+}
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
index 7133f87d85..31cc545853 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
@@ -77,6 +77,10 @@ public class Monitor {
     @Size(max = 100)
     private String app;
     
+    @Schema(title = "Scrape type: static | http_sd", example = "static", 
accessMode = READ_WRITE)
+    @Size(max = 100)
+    private String scrape;
+    
     @Schema(title = "peer host: ipv4, ipv6, domain name", example = 
"192.167.25.11", accessMode = READ_WRITE)
     @Size(max = 100)
     @HostValid
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/MonitorBind.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/MonitorBind.java
index 38ea1d4833..9161447696 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/MonitorBind.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/manager/MonitorBind.java
@@ -17,7 +17,6 @@
 
 package org.apache.hertzbeat.common.entity.manager;
 
-import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
@@ -27,8 +26,6 @@ import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
 import jakarta.persistence.Index;
 import jakarta.persistence.Table;
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
 import java.time.LocalDateTime;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -60,18 +57,16 @@ public class MonitorBind {
     @Schema(title = "primary id", example = "23")
     private Long id;
 
-    @Schema(title = "collector name", example = "87432674384")
+    @Schema(title = "key string: ip:port")
+    private String keyStr;
+    
+    @Schema(title = "connect bind id", example = "87432674384")
     private Long bizId;
 
     @Schema(title = "monitor ID", example = "87432674336")
     @Column(name = "monitor_id")
     private Long monitorId;
 
-    @Schema(title = "Bind type 0: sd", accessMode = READ_WRITE)
-    @Min(0)
-    @Max(3)
-    private byte type;
-
     @Schema(title = "The creator of this record", example = "tom")
     @CreatedBy
     private String creator;
@@ -87,4 +82,4 @@ public class MonitorBind {
     @Schema(title = "Record the latest modification time (timestamp in 
milliseconds)")
     @LastModifiedDate
     private LocalDateTime gmtUpdate;
-}
\ No newline at end of file
+}
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/sd/ServiceDiscoveryProtocol.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/sd/ServiceDiscoveryProtocol.java
deleted file mode 100644
index 42ef97316c..0000000000
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/sd/ServiceDiscoveryProtocol.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.common.entity.sd;
-
-import java.util.Arrays;
-import java.util.List;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * service discovery common field
- */
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class ServiceDiscoveryProtocol {
-    private Long id;
-    private List<Long> jobIdList;
-    /**
-     * sd type
-     */
-    private Type type;
-    /**
-     * Target sd sources by which collector updates SDCache.
-     */
-    private String sdSource;
-
-    /**
-     * sd Type
-     */
-    public enum Type {
-        HTTP_SD("httpsd"),
-        ;
-
-        private final String protocolName;
-
-        Type(String protocolName) {
-            this.protocolName = protocolName;
-        }
-
-        public static Type getType(String str) {
-            return Arrays.stream(Type.values()).filter(t -> 
t.toString().equalsIgnoreCase(str)).findFirst().orElse(null);
-        }
-
-        public String getProtocolName() {
-            return protocolName;
-        }
-    }
-}
\ No newline at end of file
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/support/valid/HostParamValidator.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/support/valid/HostParamValidator.java
index a30e1c26a8..7462d8c85d 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/support/valid/HostParamValidator.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/support/valid/HostParamValidator.java
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.common.support.valid;
 import jakarta.validation.ConstraintValidator;
 import jakarta.validation.ConstraintValidatorContext;
 import org.apache.hertzbeat.common.util.IpDomainUtil;
+import org.springframework.util.StringUtils;
 
 /**
  * Host Param Validator
@@ -33,10 +34,13 @@ public class HostParamValidator implements 
ConstraintValidator<HostValid, String
 
     @Override
     public boolean isValid(String value, ConstraintValidatorContext context) {
-        if (value != null && value.toLowerCase().contains(HTTP)){
+        if (!StringUtils.hasText(value)) {
+            return true;
+        }
+        if (value.toLowerCase().contains(HTTP)){
             value = value.replaceFirst(PATTERN_HTTP, BLANK);
         }
-        if (value != null && value.toLowerCase().contains(HTTPS)){
+        if (value.toLowerCase().contains(HTTPS)){
             value = value.replaceFirst(PATTERN_HTTPS, BLANK);
         }
 
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/SdMonitorOperator.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/SdMonitorOperator.java
deleted file mode 100644
index ed528584b3..0000000000
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/SdMonitorOperator.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.common.util;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.hertzbeat.common.constants.CommonConstants;
-import org.apache.hertzbeat.common.entity.job.Configmap;
-import org.apache.hertzbeat.common.entity.job.Job;
-import org.apache.hertzbeat.common.entity.job.Metrics;
-import org.apache.hertzbeat.common.entity.manager.MonitorBind;
-import org.apache.hertzbeat.common.entity.manager.Param;
-import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
-import org.apache.hertzbeat.common.entity.manager.Label;
-import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
-
-/**
- * Operator for service discovery
- */
-public class SdMonitorOperator {
-    public static Optional<Param> getSdParam(List<Param> params) {
-        return params.stream()
-                .filter(param -> StringUtils.isNoneBlank(param.getField(), 
param.getParamValue()))
-                .filter(param -> 
Objects.nonNull(ServiceDiscoveryProtocol.Type.getType(param.getField())))
-                .findFirst();
-    }
-
-    public static List<Param> removeSdParam(List<Param> params) {
-        return params.stream()
-                .filter(param -> 
Objects.isNull(ServiceDiscoveryProtocol.Type.getType(param.getField())))
-                .collect(Collectors.toList());
-    }
-
-    public static List<Param> cloneParamList(List<Param> params) {
-        return params.stream()
-                .map(Param::clone)
-                .peek(param -> param.setId(null))
-                .collect(Collectors.toList());
-    }
-
-    public static MonitorBind buildSdSubMonitorBind(SdMonitorParam 
sdMonitorParam, long monitorId, Map<String, String> labels) {
-        if (Objects.isNull(sdMonitorParam.getBizId())) {
-            return null;
-        }
-        labels.put(CommonConstants.TAG_AUTO_CREATED, 
String.valueOf(sdMonitorParam.getBizId()));
-        return MonitorBind.builder()
-                .id(SnowFlakeIdGenerator.generateId())
-                .bizId(sdMonitorParam.getBizId())
-                .monitorId(monitorId)
-                .type(CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR)
-                .build();
-    }
-
-    public static MonitorBind buildSdMainMonitorBind(SdMonitorParam 
sdMonitorParam, long monitorId) {
-        if (Objects.isNull(sdMonitorParam.getSdParam())) {
-            return null;
-        }
-
-        return MonitorBind.builder()
-                .id(SnowFlakeIdGenerator.generateId())
-                .bizId(sdMonitorParam.getBizId())
-                .monitorId(monitorId)
-                .type(CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR)
-                .build();
-    }
-
-    public static Job constructSdJobAndTag(SdMonitorParam sdMonitorParam, 
Map<String, String> labels, Job appDefine) {
-        if (Objects.isNull(sdMonitorParam.getSdParam())) {
-            return appDefine;
-        }
-        labels.put(CommonConstants.TAG_SD_MAIN_MONITOR, 
ServiceDiscoveryProtocol.Type.getType(sdMonitorParam.getSdParam().getField()).name());
-        return constructSdJob(appDefine, sdMonitorParam.getSdParam());
-    }
-
-    public static Job constructSdJob(Job appDefine, Param sdParam) {
-        final Job sdJob = appDefine.clone();
-        final ServiceDiscoveryProtocol.Type sdType = 
ServiceDiscoveryProtocol.Type.getType(sdParam.getField());
-        List<Metrics> metricsList = Lists.newArrayList();
-        Map<String, String> i18n = Maps.newHashMap();
-        i18n.put("zh-CN", "监控目标");
-        i18n.put("en-US", "Monitor Target");
-        List<Metrics.Field> fields = Lists.newArrayList();
-        fields.add(Metrics.Field.builder()
-                .field("host")
-                .type(CommonConstants.TYPE_STRING)
-                .i18n(constructSdFieldI18n("主机", "host"))
-                .build());
-        fields.add(Metrics.Field.builder()
-                .field("port")
-                .type(CommonConstants.TYPE_STRING)
-                .i18n(constructSdFieldI18n("端口", "port"))
-                .build());
-        metricsList.add(Metrics.builder()
-                .name("target")
-                .fields(fields)
-                .i18n(i18n)
-                .protocol(sdType.getProtocolName())
-                .sdProtocol(ServiceDiscoveryProtocol.builder()
-                        .sdSource(sdParam.getParamValue())
-                        .type(sdType)
-                        .build())
-                .build());
-
-        sdJob.setSd(Boolean.TRUE);
-        sdJob.setMetrics(metricsList);
-        sdJob.setConfigmap(Lists.newArrayList(new 
Configmap(sdParam.getField(), sdParam.getParamValue(), sdParam.getType())));
-        return sdJob;
-    }
-
-    public static List<Label> addMainMonitorTag(List<Label> tagList, Param 
sdParam) {
-        tagList = tagList.stream()
-                .filter(tag -> !StringUtils.equals(tag.getName(), 
CommonConstants.TAG_SD_MAIN_MONITOR))
-                .filter(tag -> !StringUtils.equals(tag.getName(), 
CommonConstants.TAG_AUTO_CREATED))
-                .collect(Collectors.toList());
-
-        tagList.add(Label.builder().name(CommonConstants.TAG_SD_MAIN_MONITOR)
-                
.tagValue(ServiceDiscoveryProtocol.Type.getType(sdParam.getField()).name())
-                .type(CommonConstants.TAG_TYPE_AUTO_GENERATE)
-                .build());
-
-        return tagList;
-    }
-
-    private static Map<String, String> constructSdFieldI18n(String zh, String 
en) {
-        Map<String, String> i18n = Maps.newHashMap();
-        i18n.put("zh-CN", zh);
-        i18n.put("en-US", en);
-        return i18n;
-    }
-}
diff --git 
a/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/support/vaild/HostParamValidatorTest.java
 
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/support/vaild/HostParamValidatorTest.java
index 5b5669d986..b60f77a5b6 100644
--- 
a/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/support/vaild/HostParamValidatorTest.java
+++ 
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/support/vaild/HostParamValidatorTest.java
@@ -53,13 +53,13 @@ class HostParamValidatorTest {
     @Test
     public void testIsValid() {
         boolean result = hostParamValidator.isValid(null, context);
-        assertFalse(result);
+        assertTrue(result);
 
         result = hostParamValidator.isValid("", context);
-        assertFalse(result);
+        assertTrue(result);
 
         result = hostParamValidator.isValid("   ", context);
-        assertFalse(result);
+        assertTrue(result);
 
         result = hostParamValidator.isValid("192.168.1.1", context);
         assertTrue(result);
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/component/sd/ServiceDiscoveryWorker.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/component/sd/ServiceDiscoveryWorker.java
index 12c258d29f..f783d34b22 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/component/sd/ServiceDiscoveryWorker.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/component/sd/ServiceDiscoveryWorker.java
@@ -18,25 +18,22 @@
 package org.apache.hertzbeat.manager.component.sd;
 
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import java.util.HashSet;
+import java.time.LocalDateTime;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.hertzbeat.common.constants.CommonConstants;
 import org.apache.hertzbeat.common.entity.arrow.RowWrapper;
 import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
 import org.apache.hertzbeat.common.entity.manager.MonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Param;
-import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
 import org.apache.hertzbeat.common.queue.CommonDataQueue;
-import org.apache.hertzbeat.common.util.SdMonitorOperator;
 import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
 import org.apache.hertzbeat.manager.dao.MonitorBindDao;
 import org.apache.hertzbeat.manager.dao.MonitorDao;
@@ -45,7 +42,6 @@ import 
org.apache.hertzbeat.manager.scheduler.ManagerWorkerPool;
 import org.apache.hertzbeat.manager.service.MonitorService;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
 
 /**
  * Service Discovery Worker
@@ -53,6 +49,9 @@ import org.springframework.util.CollectionUtils;
 @Slf4j
 @Component
 public class ServiceDiscoveryWorker implements InitializingBean {
+    
+    private static final String FILED_HOST = "host";
+    private static final String FILED_PORT = "port";
     private final MonitorService monitorService;
     private final ParamDao paramDao;
     private final MonitorDao monitorDao;
@@ -83,74 +82,73 @@ public class ServiceDiscoveryWorker implements 
InitializingBean {
         public void run() {
             while (!Thread.currentThread().isInterrupted()) {
                 try (final CollectRep.MetricsData metricsData = 
dataQueue.pollServiceDiscoveryData()) {
-
                     Long monitorId = metricsData.getId();
-                    final Monitor mainMonitor = 
monitorDao.findMonitorsByIdIn(Sets.newHashSet(monitorId)).get(0);
-                    
mainMonitor.getLabels().remove(CommonConstants.TAG_SD_MAIN_MONITOR);
+                    final Monitor mainMonitor = 
monitorDao.findById(monitorId).orElse(null);
+                    if (mainMonitor == null) {
+                        log.warn("No monitor found for id {}", monitorId);
+                        continue;
+                    }
                     // collector
-                    final Optional<CollectorMonitorBind> collectorBind = 
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(mainMonitor.getId());
+                    final Optional<CollectorMonitorBind> collectorBind = 
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(monitorId);
                     String collector = 
collectorBind.map(CollectorMonitorBind::getCollector).orElse(null);
-                    // param
-                    List<Param> mainMonitorParamList = 
paramDao.findParamsByMonitorId(mainMonitor.getId());
-                    mainMonitorParamList = 
SdMonitorOperator.removeSdParam(mainMonitorParamList);
-
-                    final Set<Long> subMonitorIdSet = 
monitorBindDao.findMonitorBindByBizIdAndType(monitorId, 
CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR)
-                            .stream()
-                            .map(MonitorBind::getMonitorId)
-                            .collect(Collectors.toSet());
-                    final Map<String, List<Monitor>> hostMonitorMap = 
CollectionUtils.isEmpty(subMonitorIdSet)
-                            ? Maps.newHashMap()
-                            : 
monitorDao.findMonitorsByIdIn(subMonitorIdSet).stream().collect(Collectors.groupingBy(Monitor::getHost));
-
+                    // params
+                    List<Param> mainMonitorParams = 
paramDao.findParamsByMonitorId(monitorId);
+                    final Map<String, MonitorBind> subMonitorBindMap = 
monitorBindDao.findMonitorBindsByBizId(monitorId)
+                            
.stream().collect(Collectors.toMap(MonitorBind::getKeyStr, item -> item));
                     RowWrapper rowWrapper = metricsData.readRow();
-
+                    Map<String, String> fieldsValue = 
Maps.newHashMapWithExpectedSize(8);
                     while (rowWrapper.hasNextRow()) {
                         rowWrapper = rowWrapper.nextRow();
-
-
-                        final String host = rowWrapper.nextCell().getValue();
-                        final String port = rowWrapper.nextCell().getValue();
-                        final List<Monitor> monitorList = 
hostMonitorMap.get(host);
-                        if (CollectionUtils.isEmpty(monitorList)) {
-                            
monitorService.addAndSaveMonitorJob(mainMonitor.clone(), 
SdMonitorOperator.cloneParamList(mainMonitorParamList), collector,
-                                    SdMonitorParam.builder()
-                                            .detectedHost(host)
-                                            .detectedPort(port)
-                                            .bizId(mainMonitor.getId())
-                                            .build(), null);
-                            return;
+                        fieldsValue.clear();
+                        rowWrapper.cellStream().forEach(cell -> {
+                            String value = cell.getValue();
+                            fieldsValue.put(cell.getField().getName(), value);
+                        });
+                        final String host = fieldsValue.get(FILED_HOST);
+                        final String port = fieldsValue.get(FILED_PORT);
+                        final String keyStr = host + ":" + port;
+                        if (subMonitorBindMap.containsKey(keyStr)) {
+                            subMonitorBindMap.remove(keyStr);
+                            continue;
                         }
-
-                        for (Monitor monitor : monitorList) {
-                            // make sure monitor that has the same host and 
port is not existed.
-                            final Optional<Param> samePortParam = 
paramDao.findParamsByMonitorId(monitor.getId()).stream()
-                                    .filter(param -> 
StringUtils.equals(param.getField(), "port"))
-                                    .filter(param -> 
StringUtils.equals(param.getParamValue(), port))
-                                    .findFirst();
-                            if (samePortParam.isEmpty()) {
-                                
monitorService.addAndSaveMonitorJob(mainMonitor.clone(), 
SdMonitorOperator.cloneParamList(mainMonitorParamList), collector,
-                                        SdMonitorParam.builder()
-                                                .detectedHost(host)
-                                                .detectedPort(port)
-                                                .bizId(mainMonitor.getId())
-                                                .build(), null);
-                            } else {
-                                
monitorService.enableManageMonitors(Sets.newHashSet(monitor.getId()));
+                        Monitor newMonitor = mainMonitor.clone();
+                        newMonitor.setId(null);
+                        newMonitor.setHost(host);
+                        newMonitor.setName(newMonitor.getName() + "-" + host + 
":" + port);
+                        newMonitor.setScrape(CommonConstants.SCRAPE_STATIC);
+                        newMonitor.setGmtCreate(LocalDateTime.now());
+                        newMonitor.setGmtUpdate(LocalDateTime.now());
+                        // replace host port
+                        List<Param> newParams = new LinkedList<>();
+                        for (Param param : mainMonitorParams) {
+                            Param newParam = param.clone();
+                            newParam.setId(null);
+                            newParam.setGmtUpdate(null);
+                            newParam.setGmtCreate(null);
+                            if (FILED_HOST.equals(newParam.getField())) {
+                                newParam.setParamValue(host);
+                            } else if (FILED_PORT.equals(newParam.getField())) 
{
+                                newParam.setParamValue(port);
                             }
+                            newParams.add(newParam);
                         }
-
-                        // make sure hostMonitorMap contains monitors that 
have not judged yet.
-                        hostMonitorMap.remove(host);
+                        monitorService.addMonitor(newMonitor, newParams, 
collector, null);
+                        MonitorBind monitorBind = MonitorBind.builder()
+                                .bizId(monitorId)
+                                .monitorId(newMonitor.getId())
+                                .keyStr(keyStr)
+                                .build();
+                        monitorBindDao.save(monitorBind);
                     }
-
                     // hostMonitorMap only contains monitors which are already 
existed but not in service discovery data
                     // due to monitors that coincide with service discovery 
data are removed.
                     // Thus, all monitors still in hostMonitorMap need to be 
cancelled.
-                    final HashSet<Long> needCancelMonitorIdSet = 
Sets.newHashSet();
-                    hostMonitorMap.forEach((key, value) -> 
needCancelMonitorIdSet.addAll(value.stream()
-                            .map(Monitor::getId)
-                            .collect(Collectors.toSet())));
+                    final Set<Long> needCancelMonitorIdSet = 
subMonitorBindMap.values().stream()
+                            
.map(MonitorBind::getMonitorId).collect(Collectors.toSet());
                     
monitorService.cancelManageMonitors(needCancelMonitorIdSet);
+                    for (Long id : needCancelMonitorIdSet) {
+                        
monitorBindDao.deleteMonitorBindByBizIdAndMonitorId(monitorId, id);
+                    }
                 } catch (Exception exception) {
                     log.error(exception.getMessage(), exception);
                 }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorsController.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorsController.java
index 73e926c8a4..7ecf8354b2 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorsController.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorsController.java
@@ -127,16 +127,4 @@ public class MonitorsController {
         monitorService.importConfig(file);
         return ResponseEntity.ok(Message.success("Import success"));
     }
-
-
-    @PostMapping("/copy")
-    @Operation(summary = "copy monitors by ids", description = "copy monitors 
by ids")
-    public ResponseEntity<Message<Void>> duplicateMonitors(
-            @Parameter(description = "Monitor ID List", example = 
"6565463543") @RequestParam List<Long> ids
-    ) {
-        if (ids != null && !ids.isEmpty()) {
-            monitorService.copyMonitors(ids);
-        }
-        return ResponseEntity.ok(Message.success("copy success"));
-    }
 }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/dao/MonitorBindDao.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/dao/MonitorBindDao.java
index bc7d6d877d..82eb54d4ed 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/dao/MonitorBindDao.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/dao/MonitorBindDao.java
@@ -18,22 +18,20 @@
 package org.apache.hertzbeat.manager.dao;
 
 import java.util.List;
-import java.util.Set;
 import org.apache.hertzbeat.common.entity.manager.MonitorBind;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
 
 /**
- * AuthResources database operation
+ * MonitorBind database operation
  */
 public interface MonitorBindDao extends JpaRepository<MonitorBind, Long>, 
JpaSpecificationExecutor<MonitorBind> {
-    List<MonitorBind> findAllByBizIdInAndType(Set<Long> bizIdList, byte type);
 
-    List<MonitorBind> findMonitorBindByBizIdAndType(Long bizId, byte type);
-
-    MonitorBind findMonitorBindByBizIdAndMonitorIdAndType(Long bizId, Long 
monitorId, byte type);
-
-    List<MonitorBind> findAllByType(byte type);
+    List<MonitorBind> findMonitorBindsByBizId(Long bizId);
 
     void deleteByMonitorId(Long monitorId);
-}
\ No newline at end of file
+    
+    @Modifying
+    void deleteMonitorBindByBizIdAndMonitorId(Long bizId, Long monitorId);
+}
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
index fbae3f7bda..be292fb393 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
@@ -36,12 +36,12 @@ import org.apache.hertzbeat.common.entity.manager.Param;
 @Schema(description = "Monitoring information entities")
 public class MonitorDto {
     
-    @Schema(description = "Monitor Content", accessMode = READ_WRITE)
+    @Schema(description = "monitor content", accessMode = READ_WRITE)
     @NotNull
     @Valid
     private Monitor monitor;
     
-    @Schema(description = "Monitor Params", accessMode = READ_WRITE)
+    @Schema(description = "monitor params", accessMode = READ_WRITE)
     @NotEmpty
     @Valid
     private List<Param> params;
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
index 756b08fa0a..592d913f58 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/SchedulerInit.java
@@ -19,10 +19,8 @@ package org.apache.hertzbeat.manager.scheduler;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.hertzbeat.common.constants.CommonConstants;
 import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
 import org.apache.hertzbeat.common.entity.job.Configmap;
@@ -30,13 +28,10 @@ import org.apache.hertzbeat.common.entity.job.Job;
 import org.apache.hertzbeat.common.entity.manager.Collector;
 import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
-import org.apache.hertzbeat.common.entity.manager.MonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Param;
 import org.apache.hertzbeat.common.entity.manager.ParamDefine;
-import org.apache.hertzbeat.common.util.SdMonitorOperator;
 import org.apache.hertzbeat.manager.dao.CollectorDao;
 import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
-import org.apache.hertzbeat.manager.dao.MonitorBindDao;
 import org.apache.hertzbeat.manager.dao.MonitorDao;
 import org.apache.hertzbeat.manager.dao.ParamDao;
 import org.apache.hertzbeat.manager.service.AppService;
@@ -45,6 +40,7 @@ import org.springframework.boot.CommandLineRunner;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
+import org.springframework.util.StringUtils;
 
 /**
  * scheduler init
@@ -77,9 +73,6 @@ public class SchedulerInit implements CommandLineRunner {
     
     @Autowired
     private CollectorMonitorBindDao collectorMonitorBindDao;
-
-    @Autowired
-    private MonitorBindDao monitorBindDao;
     
     @Override
     public void run(String... args) throws Exception {
@@ -98,20 +91,18 @@ public class SchedulerInit implements CommandLineRunner {
         // init jobs
         List<Monitor> monitors = 
monitorDao.findMonitorsByStatusNotInAndJobIdNotNull(List.of(CommonConstants.MONITOR_PAUSED_CODE));
         List<CollectorMonitorBind> monitorBinds = 
collectorMonitorBindDao.findAll();
-        final Set<Long> sdMonitorIds = 
monitorBindDao.findAllByType(CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR).stream()
-                .map(MonitorBind::getBizId)
-                .collect(Collectors.toSet());
         Map<Long, String> monitorIdCollectorMap = 
monitorBinds.stream().collect(
                 Collectors.toMap(CollectorMonitorBind::getMonitorId, 
CollectorMonitorBind::getCollector));
         for (Monitor monitor : monitors) {
             try {
                 // build collect job entity
-                Job appDefine = appService.getAppDefine(monitor.getApp());
-                List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
-                if (sdMonitorIds.contains(monitor.getId())) {
-                    appDefine = SdMonitorOperator.constructSdJob(appDefine, 
SdMonitorOperator.getSdParam(params).get());
+                boolean isStatic = 
CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape());
+                String app = isStatic ? monitor.getApp() : monitor.getScrape();
+                Job appDefine = appService.getAppDefine(app);
+                if (!isStatic) {
+                    appDefine.setSd(true);
                 }
-
+                List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
                 if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
                     appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
                 }
@@ -129,7 +120,7 @@ public class SchedulerInit implements CommandLineRunner {
                         .map(param -> new Configmap(param.getField(), 
param.getParamValue(),
                                 param.getType())).collect(Collectors.toList());
                 List<ParamDefine> paramDefaultValue = 
appDefine.getParams().stream()
-                        .filter(item -> 
StringUtils.isNotBlank(item.getDefaultValue()))
+                        .filter(item -> 
StringUtils.hasText(item.getDefaultValue()))
                         .toList();
                 paramDefaultValue.forEach(defaultVar -> {
                     if (configmaps.stream().noneMatch(item -> 
item.getKey().equals(defaultVar.getField()))) {
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
index ff173393fa..dbc5307404 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
@@ -22,14 +22,12 @@ import 
org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
 import org.apache.hertzbeat.common.entity.job.Job;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
 import org.apache.hertzbeat.common.entity.manager.Param;
-import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
 import org.apache.hertzbeat.manager.pojo.dto.AppCount;
 import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
 import org.apache.hertzbeat.manager.support.exception.MonitorDetectException;
 import org.springframework.data.domain.Page;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -125,14 +123,14 @@ public interface MonitorService {
      *
      * @param ids Monitoring ID List
      */
-    void cancelManageMonitors(HashSet<Long> ids);
+    void cancelManageMonitors(Set<Long> ids);
 
     /**
      * Start the managed monitoring items in batches according to the 
monitoring ID list
      *
      * @param ids Monitoring ID List
      */
-    void enableManageMonitors(HashSet<Long> ids);
+    void enableManageMonitors(Set<Long> ids);
 
     /**
      * Query the monitoring category and its corresponding monitoring quantity
@@ -183,22 +181,13 @@ public interface MonitorService {
      */
     void importConfig(MultipartFile file) throws Exception;
 
-    /**
-     * Copy monitor in batches based on the id
-     *
-     * @param ids monitor id
-     */
-    void copyMonitors(List<Long> ids);
-
     /**
      * update app collect job by app
      *
      * @param job job content
      */
     void updateAppCollectJob(Job job);
-
-    void addAndSaveMonitorJob(Monitor monitor, List<Param> params, String 
collector, SdMonitorParam sdMonitorParam, GrafanaDashboard grafanaDashboard);
-
+    
     /**
      * Copy monitor by id
      *
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
index 5e0be4bc98..b8f62e4235 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AppServiceImpl.java
@@ -270,10 +270,6 @@ public class AppServiceImpl implements AppService, 
InitializingBean {
     public List<Hierarchy> getAllAppHierarchy(String lang) {
         LinkedList<Hierarchy> hierarchies = new LinkedList<>();
         for (var job : appDefines.values()) {
-            // TODO temporarily filter out push to solve the front-end 
problem, and open it after the subsequent design optimization
-            if 
(DispatchConstants.PROTOCOL_PUSH.equalsIgnoreCase(job.getApp())) {
-                continue;
-            }
             queryAppHierarchy(lang, hierarchies, job);
         }
         return hierarchies;
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
index a74b1af6ea..3e21dfaa4f 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
@@ -23,7 +23,6 @@ import jakarta.persistence.criteria.CriteriaBuilder;
 import jakarta.persistence.criteria.Predicate;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
 import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
 import org.apache.hertzbeat.common.constants.CommonConstants;
@@ -34,23 +33,19 @@ import 
org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
 import org.apache.hertzbeat.common.entity.job.Configmap;
 import org.apache.hertzbeat.common.entity.job.Job;
 import org.apache.hertzbeat.common.entity.job.Metrics;
-import org.apache.hertzbeat.common.entity.job.protocol.CommonRequestProtocol;
 import org.apache.hertzbeat.common.entity.manager.Collector;
 import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
-import org.apache.hertzbeat.common.entity.manager.MonitorBind;
 import org.apache.hertzbeat.common.entity.manager.Param;
 import org.apache.hertzbeat.common.entity.manager.ParamDefine;
-import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
-import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
 import org.apache.hertzbeat.common.support.event.MonitorDeletedEvent;
 import org.apache.hertzbeat.common.util.AesUtil;
+import org.apache.hertzbeat.common.util.CommonUtil;
 import org.apache.hertzbeat.common.util.FileUtil;
 import org.apache.hertzbeat.common.util.IntervalExpressionUtil;
 import org.apache.hertzbeat.common.util.IpDomainUtil;
 import org.apache.hertzbeat.common.util.JsonUtil;
-import org.apache.hertzbeat.common.util.SdMonitorOperator;
 import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
 import org.apache.hertzbeat.grafana.service.DashboardService;
 import org.apache.hertzbeat.manager.config.ManagerSseManager;
@@ -65,7 +60,6 @@ import 
org.apache.hertzbeat.manager.scheduler.CollectJobScheduling;
 import org.apache.hertzbeat.manager.service.AppService;
 import org.apache.hertzbeat.manager.service.ImExportService;
 import org.apache.hertzbeat.manager.service.MonitorService;
-import org.apache.hertzbeat.manager.service.LabelService;
 import org.apache.hertzbeat.manager.support.exception.MonitorDatabaseException;
 import org.apache.hertzbeat.manager.support.exception.MonitorDetectException;
 import org.apache.hertzbeat.warehouse.service.WarehouseService;
@@ -81,15 +75,14 @@ import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -109,15 +102,11 @@ public class MonitorServiceImpl implements MonitorService 
{
     private static final Long MONITOR_ID_TMP = 1000000000L;
     private static final byte ALL_MONITOR_STATUS = 9;
 
-    private static final int TAG_LENGTH = 2;
-
     private static final String CONTENT_VALUE = 
MediaType.APPLICATION_OCTET_STREAM_VALUE + SignConstants.SINGLE_MARK + 
"charset=" + StandardCharsets.UTF_8;
     private final Map<String, ImExportService> imExportServiceMap = new 
HashMap<>();
     @Autowired
     private AppService appService;
     @Autowired
-    private LabelService tagService;
-    @Autowired
     private CollectJobScheduling collectJobScheduling;
     @Autowired
     private MonitorDao monitorDao;
@@ -147,25 +136,74 @@ public class MonitorServiceImpl implements MonitorService 
{
     @Override
     @Transactional(readOnly = true)
     public void detectMonitor(Monitor monitor, List<Param> params, String 
collector) throws MonitorDetectException {
-        final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
-
-        if (sdParam.isPresent()) {
-            collectOneTimeSdData(monitor, collector, sdParam.get());
-        } else {
+        if (CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape())) {
             detectMonitorDirectly(monitor, params, collector);
+        } else {
+            detectSdMonitor(monitor, params, collector);
         }
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void addMonitor(Monitor monitor, List<Param> params, String 
collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
-        final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
-        if (sdParam.isPresent()) {
-            addAndSaveMonitorJob(monitor.clone(), params, collector, 
SdMonitorParam.builder().sdParam(sdParam.get()).build(), grafanaDashboard);
-            return;
+        // Apply for monitor id
+        long monitorId = SnowFlakeIdGenerator.generateId();
+        Map<String, String> labels = monitor.getLabels();
+        if (labels == null) {
+            labels = new HashMap<>(8);
+            monitor.setLabels(labels);
+        }
+        // Construct the collection task Job entity
+        boolean isStatic = 
CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape());
+        String app = isStatic ? monitor.getApp() : monitor.getScrape();
+        Job appDefine = appService.getAppDefine(app);
+        if (!isStatic) {
+            appDefine.setSd(true);
+        }
+        if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
+            appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
         }
+        appDefine.setMonitorId(monitorId);
+        appDefine.setDefaultInterval(monitor.getIntervals());
+        appDefine.setCyclic(true);
+        appDefine.setTimestamp(System.currentTimeMillis());
+        Map<String, String> metadata = 
Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
+                CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
+        appDefine.setMetadata(metadata);
+        appDefine.setLabels(monitor.getLabels());
+        appDefine.setAnnotations(monitor.getAnnotations());
+        List<Configmap> configmaps = params.stream().map(param -> {
+            param.setMonitorId(monitorId);
+            return new Configmap(param.getField(), param.getParamValue(), 
param.getType());
+        }).collect(Collectors.toList());
+        appDefine.setConfigmap(configmaps);
+        long jobId = collector == null ? 
collectJobScheduling.addAsyncCollectJob(appDefine, null) :
+                collectJobScheduling.addAsyncCollectJob(appDefine, collector);
+        try {
+            detectMonitor(monitor, params, collector);
+        } catch (Exception ignored) {}
 
-        addAndSaveMonitorJob(monitor, params, collector, null, 
grafanaDashboard);
+        try {
+            if (collector != null) {
+                CollectorMonitorBind collectorMonitorBind = 
CollectorMonitorBind.builder()
+                        .collector(collector)
+                        .monitorId(monitorId)
+                        .build();
+                collectorMonitorBindDao.save(collectorMonitorBind);
+            }
+            monitor.setId(monitorId);
+            monitor.setJobId(jobId);
+            // create grafana dashboard
+            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
grafanaDashboard != null && grafanaDashboard.isEnabled()) {
+                
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), 
monitorId);
+            }
+            monitorDao.save(monitor);
+            paramDao.saveAll(params);
+        } catch (Exception e) {
+            log.error("Error while adding monitor: {}", e.getMessage(), e);
+            collectJobScheduling.cancelAsyncCollectJob(jobId);
+            throw new MonitorDatabaseException(e.getMessage());
+        }
     }
 
     @Override
@@ -233,7 +271,7 @@ public class MonitorServiceImpl implements MonitorService {
             }
         }
         // the dispatch collector must exist if pin
-        if (StringUtils.isNotBlank(monitorDto.getCollector())) {
+        if (StringUtils.hasText(monitorDto.getCollector())) {
             Optional<Collector> optionalCollector = 
collectorDao.findCollectorByName(monitorDto.getCollector());
             if (optionalCollector.isEmpty()) {
                 throw new IllegalArgumentException("The pinned collector does 
not exist.");
@@ -250,7 +288,7 @@ public class MonitorServiceImpl implements MonitorService {
                 if (paramDefine.isRequired() && (param == null || 
param.getParamValue() == null)) {
                     throw new IllegalArgumentException("Params field " + field 
+ " is required.");
                 }
-                if (param != null && param.getParamValue() != null && 
StringUtils.isNotBlank(param.getParamValue())) {
+                if (param != null && 
StringUtils.hasText(param.getParamValue())) {
                     switch (paramDefine.getType()) {
                         case "number":
                             double doubleValue;
@@ -376,7 +414,6 @@ public class MonitorServiceImpl implements MonitorService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void modifyMonitor(Monitor monitor, List<Param> params, String 
collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
-        final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
         long monitorId = monitor.getId();
         // Check to determine whether the monitor corresponding to the monitor 
id exists
         Optional<Monitor> queryOption = monitorDao.findById(monitorId);
@@ -393,36 +430,14 @@ public class MonitorServiceImpl implements MonitorService 
{
             labels = new HashMap<>(8);
             monitor.setLabels(labels);
         }
-
+        boolean isStatic = 
CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape());
         if (preMonitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE) {
             // Construct the collection task Job entity
-            Job appDefine = appService.getAppDefine(monitor.getApp());
-            if (sdParam.isPresent()) {
-                // not allow to modify a sub monitor to main monitor
-                labels.entrySet()
-                        .stream()
-                        .filter(label -> 
org.apache.commons.lang3.StringUtils.equals(label.getKey(), 
CommonConstants.TAG_AUTO_CREATED))
-                        .findFirst()
-                        .ifPresent(label -> {
-                            final MonitorBind isSubMonitorBefore = 
monitorBindDao.findMonitorBindByBizIdAndMonitorIdAndType(Long.valueOf(label.getValue()),
-                                    monitorId, 
CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
-                            if (Objects.nonNull(isSubMonitorBefore)) {
-                                throw new UnsupportedOperationException("Can 
not change a auto-created monitor to sd! ");
-                            }
-                        });
-                // create main monitor bind
-                final List<MonitorBind> mainMonitorBind = 
monitorBindDao.findMonitorBindByBizIdAndType(monitorId, 
CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR);
-                if (CollectionUtils.isEmpty(mainMonitorBind)) {
-                    monitorBindDao.save(Objects.requireNonNull(
-                            SdMonitorOperator.buildSdMainMonitorBind(
-                                    
SdMonitorParam.builder().sdParam(sdParam.get()).build(), monitorId
-                            )));
-                }
-
-                appDefine = SdMonitorOperator.constructSdJob(appDefine, 
sdParam.get());
-                labels.put(CommonConstants.TAG_SD_MAIN_MONITOR, 
ServiceDiscoveryProtocol.Type.getType(sdParam.get().getField()).name());
+            String app = isStatic ? monitor.getApp() : monitor.getScrape();
+            Job appDefine = appService.getAppDefine(app);
+            if (!isStatic) {
+                appDefine.setSd(true);
             }
-
             if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
                 appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
             }
@@ -450,8 +465,7 @@ public class MonitorServiceImpl implements MonitorService {
             // execute only in non paused status
             try {
                 detectMonitor(monitor, params, collector);
-            } catch (Exception ignored) {
-            }
+            } catch (Exception ignored) {}
         }
 
         // After the update is successfully released, refresh the database
@@ -474,12 +488,6 @@ public class MonitorServiceImpl implements MonitorService {
                 }
             }
             monitorDao.save(monitor);
-
-            // delete all sub monitor if sd param is removed
-            final List<MonitorBind> subMonitorBindList = 
monitorBindDao.findMonitorBindByBizIdAndType(monitorId, 
CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
-            if (!CollectionUtils.isEmpty(subMonitorBindList) && 
sdParam.isEmpty()) {
-                
deleteMonitors(subMonitorBindList.stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet()));
-            }
             paramDao.saveAll(params);
         } catch (Exception e) {
             log.error(e.getMessage(), e);
@@ -501,12 +509,6 @@ public class MonitorServiceImpl implements MonitorService {
         if (CollectionUtils.isEmpty(ids)) {
             return;
         }
-
-        final List<MonitorBind> allSubMonitorBind = 
monitorBindDao.findAllByBizIdInAndType(ids, 
CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
-        if (!CollectionUtils.isEmpty(allSubMonitorBind)) {
-            
ids.addAll(allSubMonitorBind.stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet()));
-        }
-
         List<Monitor> monitors = monitorDao.findMonitorsByIdIn(ids);
         if (!monitors.isEmpty()) {
             monitorDao.deleteAll(monitors);
@@ -537,7 +539,9 @@ public class MonitorServiceImpl implements MonitorService {
                 monitorDto.setMetrics(metrics);
                 
monitorDto.setGrafanaDashboard(dashboardService.getDashboardByMonitorId(id));
             } else {
-                Job job = appService.getAppDefine(monitor.getApp());
+                boolean isStatic = 
CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape());
+                String type = isStatic ? monitor.getApp() : 
monitor.getScrape();
+                Job job = appService.getAppDefine(type);
                 List<String> metrics = job.getMetrics().stream()
                         .filter(Metrics::isVisible)
                         .map(Metrics::getName).collect(Collectors.toList());
@@ -563,7 +567,7 @@ public class MonitorServiceImpl implements MonitorService {
                 }
                 andList.add(inPredicate);
             }
-            if (StringUtils.isNotBlank(app)) {
+            if (StringUtils.hasText(app)) {
                 Predicate predicateApp = 
criteriaBuilder.equal(root.get("app"), app);
                 andList.add(predicateApp);
             }
@@ -575,17 +579,17 @@ public class MonitorServiceImpl implements MonitorService 
{
             Predicate andPredicate = 
criteriaBuilder.and(andList.toArray(andPredicates));
 
             List<Predicate> orList = new ArrayList<>();
-            if (StringUtils.isNotBlank(search)) {
+            if (StringUtils.hasText(search)) {
                 Predicate predicateHost = 
criteriaBuilder.like(root.get("host"), "%" + search + "%");
                 Predicate predicateName = 
criteriaBuilder.like(criteriaBuilder.lower(root.get("name")), "%" + 
search.toLowerCase() + "%");
-                if (StringUtils.isNumeric(search)){
+                if (CommonUtil.isNumeric(search)){
                     Predicate predicateId = 
criteriaBuilder.equal(root.get("id"), Long.parseLong(search));
                     orList.add(predicateId);
                 }
                 orList.add(predicateHost);
                 orList.add(predicateName);
             }
-            if (StringUtils.isNotBlank(labels)) {
+            if (StringUtils.hasText(labels)) {
                 String[] labelAres = labels.split(",");
                 for (String label : labelAres) {
                     String[] labelArr = label.split(":");
@@ -620,18 +624,10 @@ public class MonitorServiceImpl implements MonitorService 
{
     }
 
     @Override
-    public void cancelManageMonitors(HashSet<Long> ids) {
+    public void cancelManageMonitors(Set<Long> ids) {
         if (CollectionUtils.isEmpty(ids)) {
             return;
         }
-
-        final Set<Long> subMonitorIds = 
monitorBindDao.findAllByBizIdInAndType(ids, 
CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR).stream()
-                .map(MonitorBind::getMonitorId)
-                .collect(Collectors.toSet());
-        if (!CollectionUtils.isEmpty(subMonitorIds)) {
-            ids.addAll(subMonitorIds);
-        }
-
         // Update monitoring status Delete corresponding monitoring periodic 
task
         // The jobId is not deleted, and the jobId is reused again after the 
management is started.
         List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
@@ -648,7 +644,7 @@ public class MonitorServiceImpl implements MonitorService {
     }
 
     @Override
-    public void enableManageMonitors(HashSet<Long> ids) {
+    public void enableManageMonitors(Set<Long> ids) {
         // Update monitoring status Add corresponding monitoring periodic task
         List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
                 .stream().filter(monitor ->
@@ -662,20 +658,12 @@ public class MonitorServiceImpl implements MonitorService 
{
         for (Monitor monitor : unManagedMonitors) {
             // Construct the collection task Job entity
             List<Param> params = 
paramDao.findParamsByMonitorId(monitor.getId());
-            final Optional<Param> sdParam = 
SdMonitorOperator.getSdParam(params);
-            Job appDefine = appService.getAppDefine(monitor.getApp());
-            if (sdParam.isPresent()) {
-                final List<MonitorBind> mainMonitorBind = 
monitorBindDao.findMonitorBindByBizIdAndType(monitor.getId(), 
CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR);
-                if (CollectionUtils.isEmpty(mainMonitorBind)) {
-                    monitorBindDao.save(Objects.requireNonNull(
-                            SdMonitorOperator.buildSdMainMonitorBind(
-                                    
SdMonitorParam.builder().sdParam(sdParam.get()).build(), monitor.getId()
-                            )));
-                }
-
-                appDefine = SdMonitorOperator.constructSdJob(appDefine, 
sdParam.get());
+            boolean isStatic = 
CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || 
!StringUtils.hasText(monitor.getScrape());
+            String app = isStatic ? monitor.getApp() : monitor.getScrape();
+            Job appDefine = appService.getAppDefine(app);
+            if (!isStatic) {
+                appDefine.setSd(true);
             }
-
             if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
                 appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
             }
@@ -691,7 +679,7 @@ public class MonitorServiceImpl implements MonitorService {
             List<Configmap> configmaps = params.stream().map(param ->
                     new Configmap(param.getField(), param.getParamValue(), 
param.getType())).collect(Collectors.toList());
             List<ParamDefine> paramDefaultValue = 
appDefine.getParams().stream()
-                    .filter(item -> 
StringUtils.isNotBlank(item.getDefaultValue()))
+                    .filter(item -> 
StringUtils.hasText(item.getDefaultValue()))
                     .toList();
             paramDefaultValue.forEach(defaultVar -> {
                 if (configmaps.stream().noneMatch(item -> 
item.getKey().equals(defaultVar.getField()))) {
@@ -752,25 +740,6 @@ public class MonitorServiceImpl implements MonitorService {
         }).filter(Objects::nonNull).collect(Collectors.toList());
     }
 
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void copyMonitors(List<Long> ids) {
-
-        ids.stream().parallel().forEach(id -> {
-            // get monitor and Params according id
-            Optional<Monitor> monitorOpt = monitorDao.findById(id);
-            List<Param> params = paramDao.findParamsByMonitorId(id);
-
-            monitorOpt.ifPresentOrElse(monitor -> {
-                // deep copy original monitor to achieve persist in JPA
-                Monitor newMonitor = 
JsonUtil.fromJson(JsonUtil.toJson(monitor), Monitor.class);
-                if (newMonitor != null) {
-                    copyMonitor(newMonitor, params);
-                }
-            }, () -> log.warn("can not find the monitor for id :{}", id));
-        });
-    }
-
     @Override
     public void updateAppCollectJob(Job job) {
         List<Monitor> monitors = 
monitorDao.findMonitorsByAppEquals(job.getApp())
@@ -807,7 +776,7 @@ public class MonitorServiceImpl implements MonitorService {
                 List<Configmap> configmaps = params.stream().map(param -> new 
Configmap(param.getField(),
                         param.getParamValue(), 
param.getType())).collect(Collectors.toList());
                 List<ParamDefine> paramDefaultValue = 
appDefine.getParams().stream()
-                        .filter(item -> 
StringUtils.isNotBlank(item.getDefaultValue()))
+                        .filter(item -> 
StringUtils.hasText(item.getDefaultValue()))
                         .toList();
                 paramDefaultValue.forEach(defaultVar -> {
                     if (configmaps.stream().noneMatch(item -> 
item.getKey().equals(defaultVar.getField()))) {
@@ -827,80 +796,7 @@ public class MonitorServiceImpl implements MonitorService {
             }
         }
     }
-
-    @Override
-    public void addAndSaveMonitorJob(Monitor monitor, List<Param> params, 
String collector, SdMonitorParam sdMonitorParam, GrafanaDashboard 
grafanaDashboard) {
-        // Apply for monitor id
-        long monitorId = SnowFlakeIdGenerator.generateId();
-        Map<String, String> labels = monitor.getLabels();
-        if (labels == null) {
-            labels = new HashMap<>(8);
-            monitor.setLabels(labels);
-        }
-        MonitorBind monitorBind = null;
-        // Construct the collection task Job entity
-        Job appDefine = appService.getAppDefine(monitor.getApp());
-        if (Objects.nonNull(sdMonitorParam)) {
-            monitorBind = Objects.isNull(sdMonitorParam.getSdParam())
-                    ? SdMonitorOperator.buildSdSubMonitorBind(sdMonitorParam, 
monitorId, labels)
-                    : SdMonitorOperator.buildSdMainMonitorBind(sdMonitorParam, 
monitorId);
-
-            appDefine = SdMonitorOperator.constructSdJobAndTag(sdMonitorParam, 
labels, appDefine);
-        }
-        if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
-            appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
-        }
-        appDefine.setMonitorId(monitorId);
-        appDefine.setDefaultInterval(monitor.getIntervals());
-        appDefine.setCyclic(true);
-        appDefine.setTimestamp(System.currentTimeMillis());
-        Map<String, String> metadata = 
Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(), 
-                CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
-        appDefine.setMetadata(metadata);
-        appDefine.setLabels(monitor.getLabels());
-        appDefine.setAnnotations(monitor.getAnnotations());
-        resetMetricsCommonField(monitor, appDefine, sdMonitorParam);
-
-        List<Configmap> configmaps = params.stream().map(param -> {
-            param.setMonitorId(monitorId);
-            return new Configmap(param.getField(), param.getParamValue(), 
param.getType());
-        }).collect(Collectors.toList());
-        appDefine.setConfigmap(configmaps);
-
-        long jobId = collector == null ? 
collectJobScheduling.addAsyncCollectJob(appDefine, null) :
-                collectJobScheduling.addAsyncCollectJob(appDefine, collector);
-
-        try {
-            detectMonitor(monitor, params, collector);
-        } catch (Exception ignored) {
-        }
-
-        try {
-            if (collector != null) {
-                CollectorMonitorBind collectorMonitorBind = 
CollectorMonitorBind.builder()
-                        .collector(collector)
-                        .monitorId(monitorId)
-                        .build();
-                collectorMonitorBindDao.save(collectorMonitorBind);
-            }
-            monitor.setId(monitorId);
-            monitor.setJobId(jobId);
-            // create grafana dashboard
-            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
grafanaDashboard != null && grafanaDashboard.isEnabled()) {
-                
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), 
monitorId);
-            }
-            monitorDao.save(monitor);
-            if (Objects.nonNull(monitorBind)) {
-                monitorBindDao.save(monitorBind);
-            }
-            paramDao.saveAll(params);
-        } catch (Exception e) {
-            log.error("Error while adding monitor: {}", e.getMessage(), e);
-            collectJobScheduling.cancelAsyncCollectJob(jobId);
-            throw new MonitorDatabaseException(e.getMessage());
-        }
-    }
-
+    
     @Override
     public Monitor getMonitor(Long monitorId) {
         return monitorDao.findById(monitorId).orElse(null);
@@ -916,73 +812,69 @@ public class MonitorServiceImpl implements MonitorService 
{
         return monitorDao.findMonitorsByAppEquals(app);
     }
 
-    private void resetMetricsCommonField(Monitor monitor, Job appDefine, 
SdMonitorParam sdMonitorParam) {
-        if (Objects.isNull(sdMonitorParam)
-                || 
org.apache.commons.lang3.StringUtils.isAnyBlank(sdMonitorParam.getDetectedHost(),
 sdMonitorParam.getDetectedPort())) {
-            return;
-        }
-
-        for (Metrics metric : appDefine.getMetrics()) {
-            Arrays.stream(metric.getClass().getDeclaredFields())
-                    .filter(field -> 
metric.getProtocol().equalsIgnoreCase(field.getName()))
-                    .findFirst()
-                    .ifPresent(field -> {
-                        field.setAccessible(true);
-                        final Object obj;
-                        try {
-                            obj = field.get(metric);
-                            if (obj instanceof CommonRequestProtocol protocol) 
{
-                                
protocol.setHost(sdMonitorParam.getDetectedHost());
-                                
protocol.setPort(sdMonitorParam.getDetectedPort());
-                            }
-                        } catch (IllegalAccessException exception) {
-                            log.warn("Not such field {}", field.getName());
-                        }
-                    });
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void copyMonitor(Long id) {
+        // Get the source monitor information
+        Optional<Monitor> monitorOptional = monitorDao.findById(id);
+        if (monitorOptional.isEmpty()) {
+            throw new IllegalArgumentException("Monitor not found: " + id);
         }
-
-        monitor.setHost(sdMonitorParam.getDetectedHost());
-        Map<String, String> labels = monitor.getLabels();
-        if (labels == null) {
-            labels = new HashMap<>(8);
-            monitor.setLabels(labels);
+        Monitor sourceMonitor = monitorOptional.get();
+        // Get the parameters of source monitor
+        List<Param> sourceParams = paramDao.findParamsByMonitorId(id);
+        // Create new monitor object
+        Monitor newMonitor = new Monitor();
+        // Copy basic properties, exclude ID, jobId and status
+        BeanUtils.copyProperties(sourceMonitor, newMonitor, "id", "jobId", 
"status");
+        // Set new name
+        newMonitor.setName(sourceMonitor.getName() + "_copy");
+        // Set initial status
+        newMonitor.setStatus(CommonConstants.MONITOR_UP_CODE);
+        // Set create and update time
+        newMonitor.setGmtCreate(LocalDateTime.now());
+        newMonitor.setGmtUpdate(LocalDateTime.now());
+        // Copy parameters
+        List<Param> newParams = new ArrayList<>();
+        if (!sourceParams.isEmpty()) {
+            for (Param sourceParam : sourceParams) {
+                Param newParam = new Param();
+                BeanUtils.copyProperties(sourceParam, newParam, "id");
+                newParam.setMonitorId(newMonitor.getId());
+                newParams.add(newParam);
+            }
         }
-        labels.put(CommonConstants.TAG_MONITOR_HOST, 
sdMonitorParam.getDetectedHost());
-        monitor.setName(monitor.getApp().toUpperCase() + 
CommonConstants.LOCALE_SEPARATOR + sdMonitorParam.getDetectedHost()
-                + CommonConstants.LOCALE_SEPARATOR + 
SnowFlakeIdGenerator.generateId());
+        addMonitor(newMonitor, newParams, null, null);
     }
 
-    private void copyMonitor(Monitor monitor, List<Param> params) {
-        monitor.setName(String.format("%s - copy", monitor.getName()));
-        addMonitor(monitor, params, null, null);
-    }
 
-    private void collectOneTimeSdData(Monitor monitor, String collector, Param 
sdParam) {
+    private void detectSdMonitor(Monitor monitor, List<Param> params, String 
collector) {
         Long monitorId = monitor.getId();
         if (monitorId == null || monitorId == 0) {
             monitorId = MONITOR_ID_TMP;
         }
-        Job appDefine = appService.getAppDefine(monitor.getApp());
-        if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
-            appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
monitor.getName());
+        if (monitor.getScrape() == null || params == null || params.isEmpty()) 
{
+            throw new IllegalArgumentException("scrape params is null or 
empty!");
         }
+        Job appDefine = appService.getAppDefine(monitor.getScrape());
         appDefine.setMonitorId(monitorId);
         appDefine.setCyclic(false);
         appDefine.setTimestamp(System.currentTimeMillis());
-        Map<String, String> metadata = 
Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
-                CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
+        Map<String, String> metadata = 
Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName());
         appDefine.setMetadata(metadata);
         appDefine.setLabels(monitor.getLabels());
         appDefine.setAnnotations(monitor.getAnnotations());
-        final Job sdJob = SdMonitorOperator.constructSdJob(appDefine, sdParam);
+        List<Configmap> configmaps = params.stream().map(param ->
+                new Configmap(param.getField(), param.getParamValue(), 
param.getType())).collect(Collectors.toList());
+        appDefine.setConfigmap(configmaps);
+        appDefine.setSd(true);
         List<CollectRep.MetricsData> collectRep;
         if (collector != null) {
-            collectRep = collectJobScheduling.collectSyncJobData(sdJob, 
collector);
+            collectRep = collectJobScheduling.collectSyncJobData(appDefine, 
collector);
         } else {
-            collectRep = collectJobScheduling.collectSyncJobData(sdJob);
+            collectRep = collectJobScheduling.collectSyncJobData(appDefine);
         }
         monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
-
         // If the detection result fails, a detection exception is thrown
         if (collectRep == null || collectRep.isEmpty()) {
             monitor.setStatus(CommonConstants.MONITOR_DOWN_CODE);
@@ -1038,95 +930,4 @@ public class MonitorServiceImpl implements MonitorService 
{
         }
         collectRep.forEach(CollectRep.MetricsData::close);
     }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void copyMonitor(Long id) {
-        // Get the source monitor information
-        Optional<Monitor> monitorOptional = monitorDao.findById(id);
-        if (monitorOptional.isEmpty()) {
-            throw new IllegalArgumentException("Monitor not found: " + id);
-        }
-        Monitor sourceMonitor = monitorOptional.get();
-
-        // Get the parameters of source monitor
-        List<Param> sourceParams = paramDao.findParamsByMonitorId(id);
-
-        // Create new monitor object
-        Monitor newMonitor = new Monitor();
-        // Copy basic properties, exclude ID, jobId and status
-        BeanUtils.copyProperties(sourceMonitor, newMonitor, "id", "jobId", 
"status");
-        // Set new name
-        newMonitor.setName(sourceMonitor.getName() + "_copy");
-        // Set initial status
-        newMonitor.setStatus(CommonConstants.MONITOR_UP_CODE);
-        // Set create and update time
-        newMonitor.setGmtCreate(LocalDateTime.now());
-        newMonitor.setGmtUpdate(LocalDateTime.now());
-        // Generate new ID using snowflake algorithm
-        newMonitor.setId(SnowFlakeIdGenerator.generateId());
-        // Save new monitor
-        newMonitor = monitorDao.save(newMonitor);
-
-        // Ensure ID is set
-        if (newMonitor.getId() == null) {
-            throw new RuntimeException("Failed to generate monitor ID");
-        }
-
-        // Copy parameters
-        if (!sourceParams.isEmpty()) {
-            List<Param> newParams = new ArrayList<>();
-            for (Param sourceParam : sourceParams) {
-                Param newParam = new Param();
-                BeanUtils.copyProperties(sourceParam, newParam, "id");
-                newParam.setMonitorId(newMonitor.getId());
-                newParams.add(newParam);
-            }
-            paramDao.saveAll(newParams);
-        }
-
-        try {
-            // Build collect job
-            Job appDefine = appService.getAppDefine(newMonitor.getApp());
-            if (CommonConstants.PROMETHEUS.equals(newMonitor.getApp())) {
-                appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + 
newMonitor.getName());
-            }
-            // Ensure using correct monitor ID
-            appDefine.setMonitorId(newMonitor.getId());
-            appDefine.setDefaultInterval(newMonitor.getIntervals());
-            appDefine.setCyclic(true);
-            appDefine.setTimestamp(System.currentTimeMillis());
-            Map<String, String> metadata = 
Map.of(CommonConstants.LABEL_INSTANCE_NAME, newMonitor.getName(),
-                    CommonConstants.LABEL_INSTANCE_HOST, newMonitor.getHost());
-            appDefine.setMetadata(metadata);
-            appDefine.setLabels(newMonitor.getLabels());
-            appDefine.setAnnotations(newMonitor.getAnnotations());
-            List<Configmap> configmaps = sourceParams.stream()
-                    .map(param -> new Configmap(param.getField(), 
param.getParamValue(), param.getType()))
-                    .collect(Collectors.toList());
-            appDefine.setConfigmap(configmaps);
-
-            // Get collector configuration from source monitor
-            Optional<CollectorMonitorBind> bindOptional =
-                    
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(sourceMonitor.getId());
-            String collector = 
bindOptional.map(CollectorMonitorBind::getCollector).orElse(null);
-
-            // Dispatch collect job
-            long jobId = collectJobScheduling.addAsyncCollectJob(appDefine, 
collector);
-            newMonitor.setJobId(jobId);
-            monitorDao.save(newMonitor);
-
-            // Copy collector binding if exists
-            if (collector != null) {
-                CollectorMonitorBind newBind = CollectorMonitorBind.builder()
-                        .collector(collector)
-                        .monitorId(newMonitor.getId())
-                        .build();
-                collectorMonitorBindDao.save(newBind);
-            }
-        } catch (Exception e) {
-            log.error("Create collect job error: {}", e.getMessage(), e);
-            throw new RuntimeException("Create collect job failed: " + 
e.getMessage());
-        }
-    }
 }
diff --git a/hertzbeat-manager/src/main/resources/define/app-push.yml 
b/hertzbeat-manager/src/main/resources/define/app-http_sd.yml
similarity index 59%
copy from hertzbeat-manager/src/main/resources/define/app-push.yml
copy to hertzbeat-manager/src/main/resources/define/app-http_sd.yml
index 91bcd15ba7..77b2fbd483 100644
--- a/hertzbeat-manager/src/main/resources/define/app-push.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-http_sd.yml
@@ -14,67 +14,49 @@
 # limitations under the License.
 
 # The monitoring type category:service-application service monitoring 
db-database monitoring custom-custom monitoring os-operating system monitoring
-category: service
+category: __system__
 # Monitoring application type name (consistent with file name) eg: linux 
windows tomcat mysql aws...
-app: push
+app: http_sd
 # The app api i18n name
 name:
-  zh-CN: 推送方式监控
-  en-US: Push Style Monitor
+  zh-CN: Http Service Discovery
+  en-US: Http Service Discovery
 # Input params define for app api(render web ui by the definition)
 params:
   # field-param field key
-  - field: host
+  - field: __sd_url__
     # name-param field display i18n name
     name:
-      zh-CN: 推送模块Host
-      en-US: Push Module Host
+      zh-CN: 服务发现地址
+      en-US: Service Discovery Url
     # type-param field type(most mapping the html input type)
-    type: host
-    # required-true or false
-    required: true
-    # field-param field key
-    defaultValue: 127.0.0.1
-  - field: port
-    # name-param field display i18n name
-    name:
-      zh-CN: 端口
-      en-US: Port
-    # type-param field type(most mapping the html input type)
-    type: number
-    # when type is number, range is required
-    range: '[0,65535]'
-    # required-true or false
-    required: true
-    # default value
-    defaultValue: 1157
-  - field: fields
-    # name-param field display i18n name
-    name:
-      zh-CN: 监控数据字段
-      en-US: Metrics fields
-    # type-param field type(most mapping the html input type)
-    type: metrics-field
+    type: text
     # required-true or false
     required: true
 
-# collect metrics config list
 metrics:
-  # metrics - all
-  - name: metrics
+  - name: target
     i18n:
-      zh-CN: 指标
-      en-US: Metrics
+      zh-CN: 监控目标
+      en-US: Monitor Target
     # metrics scheduling priority(0->127)->(high->low), metrics with the same 
priority will be scheduled in parallel
     # priority 0's metrics is availability metrics, it will be scheduled 
first, only availability metrics collect success will the scheduling continue
     priority: 0
+    # collect metrics content
+    fields:
+      # field-metric name, type-metric type(0-number,1-string), unit-metric 
unit('%','ms','MB'), label-whether it is a metrics label field
+      - field: host
+        type: 1
+        i18n:
+          zh-CN: Host
+          en-US: Host
+      - field: port
+        type: 1
+        i18n:
+          zh-CN: Port
+          en-US: Port
     # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, 
sdk
-    protocol: push
-    # the config content when protocol is http
-    push:
-      # http host: ipv4 ipv6 domain
-      host: ^_^host^_^
-      # http port
-      port: ^_^port^_^
-      # http uri
-      uri: /api/push
+    protocol: http_sd
+    # the config content when protocol is http_sd
+    http_sd:
+      url: ^_^__sd_url__^_^
diff --git a/hertzbeat-manager/src/main/resources/define/app-push.yml 
b/hertzbeat-manager/src/main/resources/define/app-push.yml
index 91bcd15ba7..447f101eeb 100644
--- a/hertzbeat-manager/src/main/resources/define/app-push.yml
+++ b/hertzbeat-manager/src/main/resources/define/app-push.yml
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 # The monitoring type category:service-application service monitoring 
db-database monitoring custom-custom monitoring os-operating system monitoring
-category: service
+category: __system__
 # Monitoring application type name (consistent with file name) eg: linux 
windows tomcat mysql aws...
 app: push
 # The app api i18n name
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MonitorsControllerTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MonitorsControllerTest.java
index 5ace90bec7..1ef34b819f 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MonitorsControllerTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MonitorsControllerTest.java
@@ -145,15 +145,4 @@ class MonitorsControllerTest {
                 .andExpect(jsonPath("$.code").value("0"))
                 .andExpect(jsonPath("$.msg").value("Import success"));
     }
-
-    @Test
-    void duplicateMonitors() throws Exception {
-        // Mock the behavior of monitorService.copyMonitors
-        doNothing().when(monitorService).copyMonitors(List.of(6565463543L));
-
-        // Perform the POST request and verify the response
-        this.mockMvc.perform(MockMvcRequestBuilders.post("/api/monitors/copy")
-                        .param("ids", "6565463543"))
-                .andExpect(status().isOk());
-    }
 }
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
index 07b04305cc..e79a3886aa 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
@@ -744,7 +744,7 @@ class MonitorServiceTest {
         List<Param> params = Collections.singletonList(new Param());
         when(monitorDao.findById(1L)).thenReturn(Optional.of(monitor));
         when(paramDao.findParamsByMonitorId(1L)).thenReturn(params);
-        assertDoesNotThrow(() -> monitorService.copyMonitors(List.of(1L)));
+        assertDoesNotThrow(() -> monitorService.copyMonitor(1L));
 
     }
 }
diff --git a/web-app/src/app/pojo/Monitor.ts b/web-app/src/app/pojo/Monitor.ts
index e84c67831c..5093887d80 100644
--- a/web-app/src/app/pojo/Monitor.ts
+++ b/web-app/src/app/pojo/Monitor.ts
@@ -21,6 +21,7 @@ export class Monitor {
   id!: number;
   name!: string;
   app!: string;
+  scrape!: string;
   host!: string;
   intervals: number = 60;
   // Monitoring status 0: Paused, 1: Up, 2: Down
diff --git 
a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts 
b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts
index eb50e417b3..2362eb547a 100644
--- a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts
@@ -145,6 +145,9 @@ export class MonitorDetailComponent implements OnInit, 
OnDestroy {
           if (message.code === 0) {
             this.monitor = message.data.monitor;
             this.app = this.monitor?.app;
+            if (this.monitor.scrape && this.monitor.scrape != 'static') {
+              this.app = this.monitor.scrape;
+            }
             let params: Param[] = message.data.params;
             params.forEach(param => {
               if (param.field === 'port') {
diff --git 
a/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.html 
b/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.html
index 896a201497..32892a6932 100644
--- a/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.html
+++ b/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.html
@@ -39,6 +39,9 @@
   [paramValueMap]="paramValueMap"
   [collector]="collector"
   [collectors]="collectors"
+  [sdParams]="sdParams"
+  [sdDefines]="sdDefines"
+  (scrapeChange)="onScrapeChange($event)"
   (formCancel)="onCancel()"
   (formSubmit)="onSubmit($event)"
   (formDetect)="onDetect($event)"
diff --git 
a/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.ts 
b/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.ts
index cc92099ddb..26b0f0e9c8 100644
--- a/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-edit/monitor-edit.component.ts
@@ -24,8 +24,8 @@ import { I18NService } from '@core';
 import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme';
 import { NzNotificationService } from 'ng-zorro-antd/notification';
 import { NzUploadFile } from 'ng-zorro-antd/upload';
-import { throwError } from 'rxjs';
-import { switchMap } from 'rxjs/operators';
+import { of, throwError } from 'rxjs';
+import { finalize, switchMap } from 'rxjs/operators';
 
 import { Collector } from '../../../pojo/Collector';
 import { GrafanaDashboard } from '../../../pojo/GrafanaDashboard';
@@ -54,6 +54,8 @@ export class MonitorEditComponent implements OnInit {
     @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
   ) {}
 
+  sdDefines: ParamDefine[] = [];
+  sdParams: Param[] = [];
   paramDefines!: ParamDefine[];
   hostName!: string;
   params!: Param[];
@@ -172,27 +174,142 @@ export class MonitorEditComponent implements OnInit {
           return this.collectorSvc.getCollectors();
         })
       )
+      .pipe(
+        switchMap((message: any) => {
+          if (message.code === 0) {
+            this.collectors = message.data.content?.map((item: { collector: 
any }) => item.collector);
+          } else {
+            console.warn(message.msg);
+          }
+          if (this.monitor.scrape == 'static') {
+            return of({ code: 0, data: [], msg: '' });
+          } else {
+            return this.appDefineSvc.getAppParamsDefine(this.monitor.scrape);
+          }
+        })
+      )
       .subscribe(
         message => {
           if (message.code === 0) {
-            this.collectors = message.data.content?.map(item => 
item.collector);
+            if (message.data.length > 0) {
+              let params: Param[] = [];
+              let paramDefines: ParamDefine[] = [];
+              message.data.forEach(define => {
+                let param = this.paramValueMap.get(define.field);
+                if (param === undefined) {
+                  param = new Param();
+                  param.field = define.field;
+                  if (define.type === 'number') {
+                    param.type = 0;
+                  } else if (define.type === 'key-value') {
+                    param.type = 3;
+                  } else if (define.type === 'array') {
+                    param.type = 4;
+                  } else {
+                    param.type = 1;
+                  }
+                  if (define.type === 'boolean') {
+                    param.paramValue = define.defaultValue == 'true';
+                  } else if (param.field === 'host') {
+                    param.paramValue = this.monitor.host;
+                  } else if (define.defaultValue != undefined) {
+                    if (define.type === 'number') {
+                      param.paramValue = Number(define.defaultValue);
+                    } else if (define.type === 'boolean') {
+                      param.paramValue = define.defaultValue.toLowerCase() == 
'true';
+                    } else {
+                      param.paramValue = define.defaultValue;
+                    }
+                  }
+                } else {
+                  if (define.type === 'boolean') {
+                    if (param.paramValue != null) {
+                      param.paramValue = param.paramValue.toLowerCase() == 
'true';
+                    } else {
+                      param.paramValue = false;
+                    }
+                  }
+                }
+                define.name = 
this.i18nSvc.fanyi(`monitor.app.${this.monitor.scrape}.param.${define.field}`);
+                if (define.placeholder == null && 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`) != 
`monitor.${define.field}.tip`) {
+                  define.placeholder = 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`);
+                }
+                params.push(param);
+                paramDefines.push(define);
+              });
+              this.sdParams = [...params];
+              this.sdDefines = [...paramDefines];
+            }
           } else {
             console.warn(message.msg);
           }
           this.isSpinning = false;
         },
         error => {
-          console.error(error);
           this.isSpinning = false;
         }
       );
   }
 
+  onScrapeChange(scrapeValue: string) {
+    this.monitor.scrape = scrapeValue;
+    if (this.monitor.scrape !== 'static') {
+      this.isSpinning = true;
+      let queryScrapeDefine$ = this.appDefineSvc
+        .getAppParamsDefine(this.monitor.scrape)
+        .pipe(
+          finalize(() => {
+            queryScrapeDefine$.unsubscribe();
+            this.isSpinning = false;
+          })
+        )
+        .subscribe(message => {
+          if (message.code === 0) {
+            let params: Param[] = [];
+            let paramDefines: ParamDefine[] = [];
+            message.data.forEach(define => {
+              let param = new Param();
+              param.field = define.field;
+              if (define.type === 'number') {
+                param.type = 0;
+              } else if (define.type === 'key-value') {
+                param.type = 3;
+              } else if (define.type === 'array') {
+                param.type = 4;
+              } else {
+                param.type = 1;
+              }
+              if (define.type === 'boolean') {
+                param.paramValue = false;
+              }
+              if (define.defaultValue != undefined) {
+                if (define.type === 'number') {
+                  param.paramValue = Number(define.defaultValue);
+                } else if (define.type === 'boolean') {
+                  param.paramValue = define.defaultValue.toLowerCase() == 
'true';
+                } else {
+                  param.paramValue = define.defaultValue;
+                }
+              }
+              define.name = 
this.i18nSvc.fanyi(`monitor.app.${this.monitor.scrape}.param.${define.field}`);
+              if (define.placeholder == null && 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`) != 
`monitor.${define.field}.tip`) {
+                define.placeholder = 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`);
+              }
+              params.push(param);
+              paramDefines.push(define);
+            });
+            this.sdParams = [...params];
+            this.sdDefines = [...paramDefines];
+          }
+        });
+    }
+  }
+
   onSubmit(info: any) {
     let addMonitor = {
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams),
+      params: info.params.concat(info.advancedParams).concat(info.sdParams),
       grafanaDashboard: info.grafanaDashboard
     };
     this.spinningTip = 'Loading...';
@@ -218,7 +335,7 @@ export class MonitorEditComponent implements OnInit {
     let detectMonitor = {
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams)
+      params: info.params.concat(info.advancedParams).concat(info.sdParams)
     };
     this.spinningTip = this.i18nSvc.fanyi('monitor.spinning-tip.detecting');
     this.isSpinning = true;
diff --git 
a/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.html 
b/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.html
index 383c84961c..ce12b5b82b 100644
--- a/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.html
+++ b/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.html
@@ -21,6 +21,45 @@
   <div class="-inner-content">
     <form nz-form #form="ngForm">
       <nz-form-item>
+        <nz-form-control nzSpan="4" nzOffset="9" 
[nzErrorTip]="'validation.required' | i18n">
+          <nz-select
+            style="text-align: center"
+            [nzDropdownStyle]="{ textAlign: 'center' }"
+            [(ngModel)]="monitor.scrape"
+            name="scrape"
+            (ngModelChange)="onScrapeChange($event)"
+          >
+            <nz-option nzValue="static" 
[nzLabel]="'monitor.scrape.type.static' | i18n"></nz-option>
+            <nz-option nzValue="http_sd" 
[nzLabel]="'monitor.scrape.type.http_sd' | i18n"></nz-option>
+          </nz-select>
+        </nz-form-control>
+      </nz-form-item>
+
+      <ng-container *ngIf="monitor.scrape != 'static'">
+        <ng-container *ngFor="let sdPramDefine of sdDefines; let i = index">
+          <nz-form-item *ngIf="sdParams[i].display !== false">
+            <nz-form-label nzSpan="7" [nzRequired]="sdPramDefine.required" 
[nzFor]="sdPramDefine.field"
+              >{{ sdPramDefine.name }}
+            </nz-form-label>
+            <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | 
i18n">
+              <app-form-field
+                [item]="sdPramDefine"
+                [name]="sdPramDefine.field"
+                [(ngModel)]="sdParams[i].paramValue"
+                (ngModelChange)="
+                  sdPramDefine.type === 'boolean'
+                    ? onParamBooleanChanged($event, sdPramDefine.field)
+                    : sdPramDefine.type === 'radio'
+                    ? onDependChanged($event, sdPramDefine.field)
+                    : null
+                "
+              />
+            </nz-form-control>
+          </nz-form-item>
+        </ng-container>
+      </ng-container>
+
+      <nz-form-item *ngIf="monitor.scrape == 'static'">
         <nz-form-label nzSpan="7" [nzRequired]="true" [nzFor]="'host'">{{ 
hostName ? hostName : ('monitor.host' | i18n) }} </nz-form-label>
         <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | 
i18n">
           <app-form-field
@@ -53,6 +92,8 @@
         </nz-form-control>
       </nz-form-item>
 
+      <nz-divider></nz-divider>
+
       <ng-container *ngFor="let paramDefine of paramDefines; let i = index">
         <nz-form-item *ngIf="params[i].display !== false && paramDefine.field 
!== 'host'">
           <nz-form-label nzSpan="7" [nzRequired]="paramDefine.required" 
[nzFor]="paramDefine.field">{{ paramDefine.name }} </nz-form-label>
diff --git 
a/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.ts 
b/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.ts
index f8403a6b3b..97e888974a 100644
--- a/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-form/monitor-form.component.ts
@@ -46,11 +46,14 @@ export class MonitorFormComponent implements OnChanges {
   @Input() paramDefines!: ParamDefine[];
   @Input() advancedParamDefines!: ParamDefine[];
   @Input() paramValueMap!: Map<String, Param>;
+  @Input() sdDefines!: ParamDefine[];
+  @Input() sdParams!: Param[];
 
   @Output() readonly formSubmit = new EventEmitter<any>();
   @Output() readonly formCancel = new EventEmitter<any>();
   @Output() readonly formDetect = new EventEmitter<any>();
   @Output() readonly hostChange = new EventEmitter<string>();
+  @Output() readonly scrapeChange = new EventEmitter<string>();
   @Output() readonly collectorChange = new EventEmitter<string>();
 
   hasAdvancedParams: boolean = false;
@@ -87,7 +90,7 @@ export class MonitorFormComponent implements OnChanges {
       });
       return;
     }
-    this.monitor.host = this.monitor.host.trim();
+    this.monitor.host = this.monitor.host ? this.monitor.host.trim() : '';
     this.monitor.name = this.monitor.name.trim();
     // todo Set the host property value separately for now
     this.params.forEach(param => {
@@ -103,7 +106,18 @@ export class MonitorFormComponent implements OnChanges {
         param.paramValue = (param.paramValue as string).trim();
       }
     });
-    this.formDetect.emit({ monitor: this.monitor, params: this.params, 
advancedParams: this.advancedParams, collector: this.collector });
+    this.sdParams.forEach(param => {
+      if (param.paramValue != null && typeof param.paramValue == 'string') {
+        param.paramValue = (param.paramValue as string).trim();
+      }
+    });
+    this.formDetect.emit({
+      monitor: this.monitor,
+      sdParams: this.sdParams,
+      params: this.params,
+      advancedParams: this.advancedParams,
+      collector: this.collector
+    });
   }
 
   onSubmit(formGroup: FormGroup) {
@@ -132,8 +146,14 @@ export class MonitorFormComponent implements OnChanges {
         param.paramValue = (param.paramValue as string).trim();
       }
     });
+    this.sdParams.forEach(param => {
+      if (param.paramValue != null && typeof param.paramValue == 'string') {
+        param.paramValue = (param.paramValue as string).trim();
+      }
+    });
     this.formSubmit.emit({
       monitor: this.monitor,
+      sdParams: this.sdParams,
       params: this.params,
       advancedParams: this.advancedParams,
       collector: this.collector,
@@ -145,6 +165,10 @@ export class MonitorFormComponent implements OnChanges {
     this.formCancel.emit();
   }
 
+  onScrapeChange(scrape: string) {
+    this.scrapeChange.emit(scrape);
+  }
+
   onHostChange(host: string) {
     this.hostChange.emit(host);
   }
@@ -193,6 +217,17 @@ export class MonitorFormComponent implements OnChanges {
         }
       }
     });
+    this.sdDefines.forEach((paramDefine, index) => {
+      if (paramDefine.depend) {
+        let fieldValues = new 
Map(Object.entries(paramDefine.depend)).get(dependField);
+        if (fieldValues) {
+          this.sdParams[index].display = false;
+          if (fieldValues.map(String).includes(dependValue)) {
+            this.sdParams[index].display = true;
+          }
+        }
+      }
+    });
     this.advancedParamDefines.forEach((advancedParamDefine, index) => {
       if (advancedParamDefine.depend) {
         let fieldValues = new 
Map(Object.entries(advancedParamDefine.depend)).get(dependField);
diff --git 
a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html 
b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
index b8f6fdf5b3..23438d721a 100644
--- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
+++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
@@ -174,6 +174,7 @@
           <div class="monitor-card-info">
             <div class="monitor-card-info-item host-item">
               <button
+                *ngIf="data.scrape == 'static' || !data.scrape"
                 nz-button
                 nzType="text"
                 [cdkCopyToClipboard]="data.host"
@@ -184,6 +185,10 @@
                 <i nz-icon nzType="global"></i>
                 {{ data.host }}
               </button>
+              <button nz-button nzType="text" *ngIf="data.scrape && 
data.scrape != 'static'">
+                <i nz-icon nzType="partition"></i>
+                {{ 'monitor.scrape.type.' + data.scrape | i18n }}
+              </button>
 
               <button nz-button nz-dropdown [nzDropdownMenu]="actionMenu" 
class="action-button">
                 <span nz-icon nzType="ellipsis"></span>
diff --git 
a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts 
b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
index 9302e780c8..83caede859 100644
--- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
@@ -28,7 +28,6 @@ import { NzUploadChangeParam } from 'ng-zorro-antd/upload';
 import { finalize } from 'rxjs/operators';
 
 import { Monitor } from '../../../pojo/Monitor';
-import { AppDefineService } from '../../../service/app-define.service';
 import { MemoryStorageService } from '../../../service/memory-storage.service';
 import { MonitorService } from '../../../service/monitor.service';
 import { findDeepestSelected, renderLabelColor } from 
'../../../shared/utils/common-util';
@@ -46,7 +45,6 @@ export class MonitorListComponent implements OnInit, 
OnDestroy {
     private notifySvc: NzNotificationService,
     private monitorSvc: MonitorService,
     private storageSvc: MemoryStorageService,
-    private appDefineSvc: AppDefineService,
     private menuService: MenuService,
     @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
   ) {}
@@ -506,43 +504,29 @@ export class MonitorListComponent implements OnInit, 
OnDestroy {
   onAppSwitchModalOpen() {
     this.appSwitchModalVisible = true;
     this.appSearchLoading = true;
-    const getHierarchy$ = this.appDefineSvc
-      .getAppHierarchy(this.i18nSvc.defaultLang)
-      .pipe(
-        finalize(() => {
-          getHierarchy$.unsubscribe();
-          this.appSearchLoading = false;
-        })
-      )
-      .subscribe(
-        message => {
-          if (message.code === 0) {
-            let appMenus: Record<string, any> = {};
-            message.data.forEach((app: any) => {
-              let menus = appMenus[app.category];
-              app.categoryLabel = 
this.i18nSvc.fanyi(`menu.monitor.${app.category}`);
-              if (app.categoryLabel == `menu.monitor.${app.category}`) {
-                app.categoryLabel = app.category.toUpperCase();
-              }
-              if (menus == undefined) {
-                menus = { label: app.categoryLabel, child: [app] };
-              } else {
-                menus.child.push(app);
-              }
-              appMenus[app.category] = menus;
-            });
-            this.appSearchOrigin = Object.entries(appMenus);
-            this.appSearchOrigin.sort((a, b) => {
-              return b[1].length - a[1].length;
-            });
-          } else {
-            console.warn(message.msg);
-          }
-        },
-        error => {
-          console.warn(error.msg);
-        }
-      );
+    let appMenus: Record<string, any> = {};
+    let hierarchy: any[] = this.storageSvc.getData('hierarchy');
+    hierarchy.forEach((app: any) => {
+      if (app.category == '__system__') {
+        return;
+      }
+      let menus = appMenus[app.category];
+      app.categoryLabel = this.i18nSvc.fanyi(`menu.monitor.${app.category}`);
+      if (app.categoryLabel == `menu.monitor.${app.category}`) {
+        app.categoryLabel = app.category.toUpperCase();
+      }
+      if (menus == undefined) {
+        menus = { label: app.categoryLabel, child: [app] };
+      } else {
+        menus.child.push(app);
+      }
+      appMenus[app.category] = menus;
+    });
+    this.appSearchOrigin = Object.entries(appMenus);
+    this.appSearchOrigin.sort((a, b) => {
+      return b[1].length - a[1].length;
+    });
+    this.appSearchLoading = false;
   }
 
   onAppSwitchModalCancel() {
diff --git 
a/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.html 
b/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.html
index 8978a7ef46..4511bf0ed1 100644
--- a/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.html
+++ b/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.html
@@ -38,6 +38,9 @@
   [advancedParamDefines]="advancedParamDefines"
   [collector]="collector"
   [collectors]="collectors"
+  [sdParams]="sdParams"
+  [sdDefines]="sdDefines"
+  (scrapeChange)="onScrapeChange($event)"
   (hostChange)="onHostChange($event)"
   (formCancel)="onCancel()"
   (formSubmit)="onSubmit($event)"
diff --git 
a/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.ts 
b/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.ts
index ad4e18dc7a..ff700dd452 100644
--- a/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-new/monitor-new.component.ts
@@ -22,7 +22,8 @@ import { ActivatedRoute, ParamMap, Router } from 
'@angular/router';
 import { I18NService } from '@core';
 import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme';
 import { NzNotificationService } from 'ng-zorro-antd/notification';
-import { switchMap } from 'rxjs/operators';
+import { of } from 'rxjs';
+import { finalize, switchMap } from 'rxjs/operators';
 
 import { Collector } from '../../../pojo/Collector';
 import { GrafanaDashboard } from '../../../pojo/GrafanaDashboard';
@@ -41,6 +42,8 @@ import { generateReadableRandomString } from 
'../../../shared/utils/common-util'
   styles: []
 })
 export class MonitorNewComponent implements OnInit {
+  sdDefines: ParamDefine[] = [];
+  sdParams: Param[] = [];
   paramDefines!: ParamDefine[];
   hostName!: string;
   params!: Param[];
@@ -75,6 +78,7 @@ export class MonitorNewComponent implements OnInit {
           if (this.monitor.app == '') {
             this.router.navigateByUrl('/monitors/new?app=website');
           }
+          this.monitor.scrape = paramMap.get('scrape') || 'static';
           this.titleSvc.setTitleByI18n(`monitor.app.${this.monitor.app}`);
           this.isSpinning = true;
           return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
@@ -140,21 +144,125 @@ export class MonitorNewComponent implements OnInit {
           return this.collectorSvc.getCollectors();
         })
       )
+      .pipe(
+        switchMap((message: any) => {
+          if (message.code === 0) {
+            this.collectors = message.data.content?.map((item: { collector: 
any }) => item.collector);
+          } else {
+            console.warn(message.msg);
+          }
+          if (this.monitor.scrape == 'static') {
+            return of({ code: 0, data: [], msg: '' });
+          } else {
+            return this.appDefineSvc.getAppParamsDefine(this.monitor.scrape);
+          }
+        })
+      )
       .subscribe(
         message => {
           if (message.code === 0) {
-            this.collectors = message.data.content?.map(item => 
item.collector);
+            if (message.data.length > 0) {
+              let params: Param[] = [];
+              let paramDefines: ParamDefine[] = [];
+              message.data.forEach(define => {
+                let param = new Param();
+                param.field = define.field;
+                if (define.type === 'number') {
+                  param.type = 0;
+                } else if (define.type === 'key-value') {
+                  param.type = 3;
+                } else if (define.type === 'array') {
+                  param.type = 4;
+                } else {
+                  param.type = 1;
+                }
+                if (define.type === 'boolean') {
+                  param.paramValue = false;
+                }
+                if (define.defaultValue != undefined) {
+                  if (define.type === 'number') {
+                    param.paramValue = Number(define.defaultValue);
+                  } else if (define.type === 'boolean') {
+                    param.paramValue = define.defaultValue.toLowerCase() == 
'true';
+                  } else {
+                    param.paramValue = define.defaultValue;
+                  }
+                }
+                define.name = 
this.i18nSvc.fanyi(`monitor.app.${this.monitor.scrape}.param.${define.field}`);
+                if (define.placeholder == null && 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`) != 
`monitor.${define.field}.tip`) {
+                  define.placeholder = 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`);
+                }
+                params.push(param);
+                paramDefines.push(define);
+              });
+              this.sdParams = [...params];
+              this.sdDefines = [...paramDefines];
+            }
           } else {
             console.warn(message.msg);
           }
           this.isSpinning = false;
         },
         error => {
-          this.isSpinning = true;
+          this.isSpinning = false;
         }
       );
   }
 
+  onScrapeChange(scrapeValue: string) {
+    this.monitor.scrape = scrapeValue;
+    if (this.monitor.scrape !== 'static') {
+      this.isSpinning = true;
+      let queryScrapeDefine$ = this.appDefineSvc
+        .getAppParamsDefine(this.monitor.scrape)
+        .pipe(
+          finalize(() => {
+            queryScrapeDefine$.unsubscribe();
+            this.isSpinning = false;
+          })
+        )
+        .subscribe(message => {
+          if (message.code === 0) {
+            let params: Param[] = [];
+            let paramDefines: ParamDefine[] = [];
+            message.data.forEach(define => {
+              let param = new Param();
+              param.field = define.field;
+              if (define.type === 'number') {
+                param.type = 0;
+              } else if (define.type === 'key-value') {
+                param.type = 3;
+              } else if (define.type === 'array') {
+                param.type = 4;
+              } else {
+                param.type = 1;
+              }
+              if (define.type === 'boolean') {
+                param.paramValue = false;
+              }
+              if (define.defaultValue != undefined) {
+                if (define.type === 'number') {
+                  param.paramValue = Number(define.defaultValue);
+                } else if (define.type === 'boolean') {
+                  param.paramValue = define.defaultValue.toLowerCase() == 
'true';
+                } else {
+                  param.paramValue = define.defaultValue;
+                }
+              }
+              define.name = 
this.i18nSvc.fanyi(`monitor.app.${this.monitor.scrape}.param.${define.field}`);
+              if (define.placeholder == null && 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`) != 
`monitor.${define.field}.tip`) {
+                define.placeholder = 
this.i18nSvc.fanyi(`monitor.${define.field}.tip`);
+              }
+              params.push(param);
+              paramDefines.push(define);
+            });
+            this.sdParams = [...params];
+            this.sdDefines = [...paramDefines];
+          }
+        });
+    }
+  }
+
   onHostChange(hostValue: string) {
     if (this.monitor.name == undefined || this.monitor.name == '') {
       this.monitor.name = generateReadableRandomString();
@@ -165,7 +273,7 @@ export class MonitorNewComponent implements OnInit {
     let addMonitor = {
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams),
+      params: info.params.concat(info.advancedParams).concat(info.sdParams),
       grafanaDashboard: info.grafanaDashboard
     };
     this.spinningTip = 'Loading...';
@@ -191,7 +299,7 @@ export class MonitorNewComponent implements OnInit {
     let detectMonitor = {
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams)
+      params: info.params.concat(info.advancedParams).concat(info.sdParams)
     };
     this.spinningTip = this.i18nSvc.fanyi('monitor.spinning-tip.detecting');
     this.isSpinning = true;
diff --git a/web-app/src/app/routes/setting/define/define.component.ts 
b/web-app/src/app/routes/setting/define/define.component.ts
index 7246826f8c..063f05e6e0 100644
--- a/web-app/src/app/routes/setting/define/define.component.ts
+++ b/web-app/src/app/routes/setting/define/define.component.ts
@@ -94,6 +94,9 @@ export class DefineComponent implements OnInit {
               if (app.value == 'prometheus') {
                 return;
               }
+              if (app.category == '__system__') {
+                return;
+              }
               this.appLabel[app.value] = app.label;
               let menus = appMenus[app.category];
               if (menus == undefined) {
diff --git a/web-app/src/assets/i18n/en-US.json 
b/web-app/src/assets/i18n/en-US.json
index b3b778e066..c6b209bcf5 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -612,7 +612,7 @@
   "menu.monitor.service": "Service Monitor",
   "menu.monitor.webserver": "Webserver Monitor",
   "menu.more": "More",
-  "menu.search.placeholder": "Search Monitoring Task Name、Host etc",
+  "menu.search.placeholder": "Search Task Name、Host etc",
   "monitor": "Monitor",
   "monitor.advanced": "Advanced",
   "monitor.advanced.tip": "Advanced Setting Params",
@@ -709,7 +709,7 @@
   "monitor.headerValue.tip": "Header Value",
   "monitor.holdingRegisterAddresses.tip": "Input RegisterAddress",
   "monitor.host": "Target Host",
-  "monitor.host.tip": "The monitored peer ip or domain name",
+  "monitor.host.tip": "The target peer ip or domain name",
   "monitor.icon.bigdata": "dot-chart",
   "monitor.icon.cache": "group",
   "monitor.icon.center": "laptop",
@@ -728,7 +728,7 @@
   "monitor.keyword.tip": "Enter keyword which occurrences need to be 
monitored",
   "monitor.list": "Monitor List",
   "monitor.name": "Task Name",
-  "monitor.name.tip": "Monitoring task name",
+  "monitor.name.tip": "The unique name that identifies the task",
   "monitor.new": "New",
   "monitor.new-monitor": "New Monitor",
   "monitor.new.failed": "New Monitor Failed",
@@ -759,6 +759,8 @@
   "monitor.sshPort.tip": "Required When Enabling SSH Tunnel",
   "monitor.sshUsername.tip": "Required When Enabling SSH Tunnel",
   "monitor.sshPrivateKey.tip": "BEGIN RSA PRIVATE KEY",
+  "monitor.scrape.type.static": "Static Scrape",
+  "monitor.scrape.type.http_sd": "Http Service Discovery",
   "placeholder.key": "Key",
   "placeholder.value": "Value",
   "plugin.delete": "Delete Plugin",
diff --git a/web-app/src/assets/i18n/ja-JP.json 
b/web-app/src/assets/i18n/ja-JP.json
index 2354b80ea7..3e93acda1d 100644
--- a/web-app/src/assets/i18n/ja-JP.json
+++ b/web-app/src/assets/i18n/ja-JP.json
@@ -759,6 +759,8 @@
   "monitor.sshPort.tip": "SSHトンネルオープン時に必要",
   "monitor.sshUsername.tip": "SSHトンネルオープン時に必要",
   "monitor.sshPrivateKey.tip": "RSA秘密鍵の起動",
+  "monitor.scrape.type.static": "静的",
+  "monitor.scrape.type.http_sd": "Http Service Discovery",
   "placeholder.key": "キー",
   "placeholder.value": "値",
   "plugin.delete": "プラグインを削除",
diff --git a/web-app/src/assets/i18n/pt-BR.json 
b/web-app/src/assets/i18n/pt-BR.json
index 51e8811e0e..accdda3f03 100644
--- a/web-app/src/assets/i18n/pt-BR.json
+++ b/web-app/src/assets/i18n/pt-BR.json
@@ -571,6 +571,8 @@
     "monitor.sshPort.tip": "Obrigatório quando túnel SSH está ativo",
     "monitor.sshUsername.tip": "Obrigatório quando túnel SSH está ativo",
     "monitor.sshPrivateKey.tip": "Chave privada RSA",
+    "monitor.scrape.type.static": "Estatico",
+    "monitor.scrape.type.http_sd": "Http Service Discovery",
     "common.name": "Nome da Métrica",
     "common.value": "Valor da Métrica",
     "common.search": "Pesquisar",
diff --git a/web-app/src/assets/i18n/zh-CN.json 
b/web-app/src/assets/i18n/zh-CN.json
index 95431dbf07..e62856b83c 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -759,6 +759,8 @@
   "monitor.sshPort.tip": "SSH隧道开启时必填",
   "monitor.sshUsername.tip": "SSH隧道开启时必填",
   "monitor.sshPrivateKey.tip": "启动RSA私钥",
+  "monitor.scrape.type.static": "静态配置",
+  "monitor.scrape.type.http_sd": "Http 服务发现",
   "placeholder.key": "键",
   "placeholder.value": "值",
   "plugin.delete": "刪除插件",
diff --git a/web-app/src/assets/i18n/zh-TW.json 
b/web-app/src/assets/i18n/zh-TW.json
index 421e19384c..a9eef93d07 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -758,6 +758,8 @@
   "monitor.sshPort.tip": "SSH隧道開啓時必填",
   "monitor.sshUsername.tip": "SSH隧道開啓時必填",
   "monitor.sshPrivateKey.tip": "啟動RSA私鑰",
+  "monitor.scrape.type.static": "靜態配置",
+  "monitor.scrape.type.http_sd": "Http 服務發現",
   "placeholder.key": "鍵",
   "placeholder.value": "值",
   "plugin.delete": "刪除插件",


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@hertzbeat.apache.org
For additional commands, e-mail: notifications-h...@hertzbeat.apache.org

Reply via email to