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

zhaoqingran 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 9080ccd2b [bugfix] fix load error when edit monitor and can not update 
(#2682)
9080ccd2b is described below

commit 9080ccd2bafa6531a44e2c86367b616800150c9b
Author: tomsun28 <[email protected]>
AuthorDate: Fri Sep 6 08:47:58 2024 +0800

    [bugfix] fix load error when edit monitor and can not update (#2682)
    
    Signed-off-by: tomsun28 <[email protected]>
---
 .../common/entity/grafana/GrafanaDashboard.java    |  18 +-
 .../common/entity/grafana/ServiceAccount.java      |  61 ------
 .../hertzbeat/common/entity/manager/Monitor.java   |   9 -
 .../apache/hertzbeat/common/util/CommonUtil.java   |  37 ++++
 ...{CommonConstants.java => GrafanaConstants.java} |  31 +--
 .../hertzbeat/grafana/config/GrafanaInit.java      |  23 +--
 .../grafana/config/GrafanaProperties.java          |   4 +-
 .../grafana/controller/DashboardController.java    |   6 +-
 .../controller/ServiceAccountController.java       | 119 -----------
 ...{ServiceTokenDao.java => GrafanaConfigDao.java} |  23 +--
 .../hertzbeat/grafana/dao/ServiceAccountDao.java   |  38 ----
 .../hertzbeat/grafana/dto/GrafanaConfig.java       |  28 +--
 .../grafana/service/DashboardService.java          |  35 +---
 .../grafana/service/DatasourceService.java         | 104 +++-------
 .../grafana/service/ServiceAccountService.java     | 226 ++++++---------------
 .../manager/controller/MonitorController.java      |   4 +-
 .../hertzbeat/manager/pojo/dto/MonitorDto.java     |   7 +-
 .../hertzbeat/manager/service/AccountService.java  |   4 +-
 .../hertzbeat/manager/service/MonitorService.java  |  21 +-
 .../service/impl/AbstractImExportServiceImpl.java  |   2 +-
 .../manager/service/impl/AccountServiceImpl.java   |   2 +-
 .../manager/service/impl/MonitorServiceImpl.java   |  27 ++-
 .../manager/service/AccountServiceTest.java        |   2 +-
 .../manager/service/MonitorServiceTest.java        |  10 +-
 web-app/src/app/pojo/Monitor.ts                    |   2 -
 .../monitor-detail/monitor-detail.component.html   |   6 +-
 .../monitor-detail/monitor-detail.component.ts     |   8 +-
 .../monitor-edit/monitor-edit.component.html       |   1 +
 .../monitor/monitor-edit/monitor-edit.component.ts |  18 +-
 .../monitor-form/monitor-form.component.html       |   4 +-
 .../monitor/monitor-form/monitor-form.component.ts |  11 +-
 .../monitor/monitor-new/monitor-new.component.html |   1 +
 .../monitor/monitor-new/monitor-new.component.ts   |   6 +-
 33 files changed, 261 insertions(+), 637 deletions(-)

diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/GrafanaDashboard.java
 
b/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/GrafanaDashboard.java
index f7ab207ff..00d1cc810 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/GrafanaDashboard.java
+++ 
b/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/GrafanaDashboard.java
@@ -28,9 +28,6 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-
-
-
 /**
  * Grafana dashboard entity
  */
@@ -42,23 +39,32 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 @Schema(description = "Grafana dashboard entity")
 public class GrafanaDashboard implements Serializable {
+
+    @Id
+    @Schema(description = "Monitor id")
+    private Long monitorId;
+    
     @Schema(description = "Dashboard folderUid")
     private String folderUid;
+    
     @Schema(description = "Dashboard slug")
     private String slug;
+    
     @Schema(description = "Dashboard status")
     private String status;
+    
     @Schema(description = "Dashboard uid")
     private String uid;
+    
     @Schema(description = "Dashboard url")
     private String url;
+    
     @Schema(description = "Dashboard version")
     private Long version;
-    @Id
-    @Schema(description = "Monitor id")
-    private Long monitorId;
+    
     @Schema(description = "is enabled")
     private boolean enabled;
+    
     @Schema(description = "template")
     @Transient
     private String template;
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java
 
b/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java
deleted file mode 100644
index 6aee87e07..000000000
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java
+++ /dev/null
@@ -1,61 +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.grafana;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-
-
-
-/**
- * Grafana service account entity
- */
-@Entity
-@Table(name = "hzb_grafana_service_account")
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Schema(description = "Grafana service account entity")
-public class ServiceAccount {
-    @Id
-    @Schema(description = "Service account id")
-    private Long id;
-    @Schema(description = "Service account name")
-    private String name;
-    @Schema(description = "Service account role")
-    private String role;
-    @Schema(description = "Service account is disabled")
-    private Boolean isDisabled;
-    @Schema(description = "Service account tokens")
-    private Integer tokens;
-    @Schema(description = "Service account avatar url")
-    private String avatarUrl;
-    @Schema(description = "Service account login")
-    private String login;
-    @Schema(description = "Service account orgId")
-    private Integer orgId;
-
-}
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
index c76051d3f..2d3665bf1 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
+++ 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/Monitor.java
@@ -32,7 +32,6 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.JoinTable;
 import jakarta.persistence.ManyToMany;
 import jakarta.persistence.Table;
-import jakarta.persistence.Transient;
 import jakarta.validation.constraints.Max;
 import jakarta.validation.constraints.Min;
 import jakarta.validation.constraints.Size;
@@ -42,7 +41,6 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
 import org.apache.hertzbeat.common.support.valid.HostValid;
 import org.springframework.data.annotation.CreatedBy;
 import org.springframework.data.annotation.CreatedDate;
@@ -168,11 +166,4 @@ public class Monitor {
         joinColumns = {@JoinColumn(name = "monitor_id", referencedColumnName = 
"id")},
         inverseJoinColumns = {@JoinColumn(name = "tag_id", 
referencedColumnName = "id")})
     private List<Tag> tags;
-
-    /**
-     * grafana dashboard
-     */
-    @Schema(title = "grafana dashboard")
-    @Transient
-    private GrafanaDashboard grafanaDashboard;
 }
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java 
b/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
index 88c0e7167..35d6a5762 100644
--- a/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
+++ b/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
@@ -23,6 +23,7 @@ import java.time.LocalTime;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import lombok.extern.slf4j.Slf4j;
@@ -223,4 +224,40 @@ public final class CommonUtil {
         }
     }
 
+    /**
+     * generate random word
+     * @param length length
+     * @return words
+     */
+    public static String generateRandomWord(int length) {
+        StringBuilder word = new StringBuilder();
+        Random random = new Random();
+        // 'a' ASCII
+        int minVowel = 97;
+        // 'z' ASCII
+        int maxVowel = 122;
+        // 'A' ASCII
+        int minConsonant = 65;
+        // 'Z' ASCII
+        int maxConsonant = 90;
+        // '0' ASCII
+        int minDigit = 48;
+        // '9' ASCII
+        int maxDigit = 57;
+        word.append((char) (minVowel + random.nextInt(5)));
+        for (int i = 1; i < length; i++) {
+            switch (random.nextInt(3)) {
+                case 0:
+                    word.append((char) (minVowel + random.nextInt(5)));
+                    break;
+                case 1:
+                    word.append((char) (minDigit + random.nextInt(10)));
+                    break;
+                default:
+                    word.append((char) (minConsonant + random.nextInt(26)));
+                    break;
+            }
+        }
+        return word.toString();
+    }
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/common/CommonConstants.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
similarity index 75%
rename from 
grafana/src/main/java/org/apache/hertzbeat/grafana/common/CommonConstants.java
rename to 
grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
index 7c227d0e5..36712c1a4 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/common/CommonConstants.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
@@ -20,7 +20,8 @@ package org.apache.hertzbeat.grafana.common;
 /**
  * Grafana Common Constants
  */
-public interface CommonConstants {
+public interface GrafanaConstants {
+    
     String HTTP = "http://";;
 
     String HTTPS = "https://";;
@@ -30,10 +31,6 @@ public interface CommonConstants {
     String REFRESH = "&refresh=15s";
 
     String INSTANCE = "&var-instance=";
-
-    String AUTHORIZATION = "Authorization";
-    
-    String BEARER = "Bearer ";
     
     String CREATE_DASHBOARD_API = "/api/dashboards/db";
     
@@ -41,37 +38,29 @@ public interface CommonConstants {
     
     String DATASOURCE_NAME = "hertzbeat-victoria-metrics";
     
+    String USE_DATASOURCE = "&var-ds=" + DATASOURCE_NAME;
+    
     String DATASOURCE_TYPE = "prometheus";
     
     String DATASOURCE_ACCESS = "proxy";
     
-    String CREATE_DATASOURCE_API = "%s:%s@%s/api/datasources";
+    String CREATE_DATASOURCE_API = "/api/datasources";
     
-    String DELETE_DATASOURCE_API = "%s:%s@%s/api/datasources/name/%s";  
+    String QUERY_DATASOURCE_API = "/api/datasources/name/" + DATASOURCE_NAME;
     
+    String GET_SERVICE_ACCOUNTS_API = "%s:%s@%s/api/serviceaccounts/search";
+
     String ACCOUNT_NAME = "hertzbeat";
     
     String ACCOUNT_ROLE = "Admin";
     
-    String ACCOUNT_TOKEN_NAME = "hertzbeat-token";
-    
     String CREATE_SERVICE_ACCOUNT_API = "%s:%s@%s/api/serviceaccounts";
     
-    String GET_SERVICE_ACCOUNTS_API = "%s:%s@%s/api/serviceaccounts/search";
-    
-    String DELETE_SERVICE_ACCOUNT_API = "%s:%s@%s/api/serviceaccounts/%d";
-    
     String CREATE_SERVICE_TOKEN_API = "%s:%s@%s/api/serviceaccounts/%d/tokens";
-    
-    String GET_SERVICE_TOKENS_API = "%s:%s@%s/api/serviceaccounts/%d/tokens";
-
-    String NAME = "name";
 
     String APPLICATION_JSON = "application/json";
-    
-    String HERTZBEAT_TOKEN = "hertzbeat-token";
-
-    String TYPE = "type";
 
     String URL = "url";
+
+    String GRAFANA_CONFIG = "grafanaConfig";
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
index 6306dbeb9..7b8537c52 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
@@ -42,22 +42,17 @@ public class GrafanaInit implements CommandLineRunner {
     //3. Determine whether there is a token, if not, create and ensure that 
the account is unique.
     @Override
     public void run(String... args) throws Exception {
-        if (grafanaProperties.enabled() && grafanaProperties.url() != null && 
grafanaProperties.username() != null && grafanaProperties.password() != null) {
-            serviceAccountService.reload();
+        if (grafanaProperties.enabled()) {
+            log.info("grafana init start");
             try {
-                serviceAccountService.getAccount();
-            } catch (RuntimeException e) {
-                log.error("service account is not exist, create service 
account");
-                serviceAccountService.createServiceAccount();
+                String token = serviceAccountService.getToken();
+                if (token == null) {
+                    token = serviceAccountService.applyForToken();
+                }
+                datasourceService.existOrCreateDatasource(token);   
+            } catch (Exception e) {
+                log.error("grafana init error", e);
             }
-            try {
-                serviceAccountService.getToken();
-            } catch (RuntimeException e) {
-                log.error("service token is not exist, create service token");
-                serviceAccountService.createToken();
-            }
-            datasourceService.deleteDatasource();
-            datasourceService.createDatasource();
         }
     }
 
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaProperties.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaProperties.java
index 77544bba7..49969d853 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaProperties.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaProperties.java
@@ -17,8 +17,8 @@
 
 package org.apache.hertzbeat.grafana.config;
 
-import static org.apache.hertzbeat.grafana.common.CommonConstants.HTTP;
-import static org.apache.hertzbeat.grafana.common.CommonConstants.HTTPS;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.HTTP;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.HTTPS;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.bind.DefaultValue;
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
index 754eb0361..0201566f3 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
@@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.entity.dto.Message;
 import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
-import org.apache.hertzbeat.grafana.config.GrafanaProperties;
 import org.apache.hertzbeat.grafana.service.DashboardService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
@@ -48,9 +47,6 @@ public class DashboardController {
     @Autowired
     private DashboardService dashboardService;
 
-    @Autowired
-    private GrafanaProperties grafanaProperties;
-
     /**
      * Creates a new Grafana dashboard.
      *
@@ -62,7 +58,7 @@ public class DashboardController {
     @PostMapping
     public ResponseEntity<Message<?>> createDashboard(@RequestParam String 
dashboardJson, @RequestParam Long monitorId) {
         try {
-            ResponseEntity<?> response = 
dashboardService.createDashboard(dashboardJson, monitorId);
+            ResponseEntity<?> response = 
dashboardService.createOrUpdateDashboard(dashboardJson, monitorId);
             if (response.getStatusCode().is2xxSuccessful()) {
                 return ResponseEntity.ok(Message.success("create dashboard 
success"));
             }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java
deleted file mode 100644
index 983fab1e3..000000000
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java
+++ /dev/null
@@ -1,119 +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.grafana.controller;
-
-import static org.apache.hertzbeat.common.constants.CommonConstants.FAIL_CODE;
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.apache.hertzbeat.common.entity.dto.Message;
-import org.apache.hertzbeat.grafana.service.ServiceAccountService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Controller for managing Grafana service accounts and tokens via API.
- */
-@Tag(name = "Service Account API")
-@RestController
-@RequestMapping(path = "/api/grafana/service-account", produces = 
{APPLICATION_JSON_VALUE})
-public class ServiceAccountController {
-
-    @Autowired
-    private ServiceAccountService serviceAccountService;
-
-    /**
-     * Creates a new service admin account.
-     *
-     * @return ResponseEntity containing the result of the account creation
-     */
-    @PostMapping(path = "/account")
-    @Operation(summary = "Create service account", description = "Create 
service account")
-    public ResponseEntity<Message<?>> createServiceAccount() {
-        try {
-            ResponseEntity<String> response = 
serviceAccountService.createServiceAccount();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Retrieves all service accounts.
-     *
-     * @return ResponseEntity containing the list of service accounts
-     */
-    @GetMapping(path = "/accounts")
-    @Operation(summary = "Get service account", description = "Get service 
account")
-    public ResponseEntity<Message<?>> getServiceAccount() {
-        try {
-            ResponseEntity<String> response = 
serviceAccountService.getAccounts();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Creates a new API token for a service account.
-     *
-     * @return ResponseEntity containing the result of the token creation
-     */
-    @PostMapping(path = "/token")
-    @Operation(summary = "Create service account token", description = "Create 
service account token")
-    public ResponseEntity<Message<?>> createToken() {
-        try {
-            ResponseEntity<String> response = 
serviceAccountService.createToken();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Retrieves all API tokens for service accounts.
-     *
-     * @return ResponseEntity containing the list of tokens
-     */
-    @GetMapping(path = "/tokens")
-    @Operation(summary = "Get service account token", description = "Get 
service account token")
-    public ResponseEntity<Message<?>> getToken() {
-        try {
-            ResponseEntity<String> response = 
serviceAccountService.getTokens();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    private ResponseEntity<Message<?>> handleResponse(ResponseEntity<String> 
response) {
-        if (response.getStatusCode().is2xxSuccessful()) {
-            return ResponseEntity.ok(Message.success(response.getBody()));
-        }
-        return ResponseEntity.ok(Message.fail(FAIL_CODE, response.getBody()));
-    }
-
-    private ResponseEntity<Message<?>> handleException(Exception e) {
-        return ResponseEntity.ok(Message.fail(FAIL_CODE, e.getMessage()));
-    }
-}
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
similarity index 63%
rename from 
grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java
rename to 
grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
index bb7d67e56..1a74bb05b 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
@@ -17,21 +17,20 @@
 
 package org.apache.hertzbeat.grafana.dao;
 
-import org.apache.hertzbeat.common.entity.grafana.ServiceToken;
+import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
- * ServiceAccount Dao
+ * Public server configuration Dao
+ * <p>This interface inherits the two interfaces JpaRepository and 
JpaSpecificationExecutor, providing basic CRUD operations and specification 
query capabilities.</p>
  */
-public interface ServiceTokenDao extends JpaRepository<ServiceToken, Long>, 
JpaSpecificationExecutor<ServiceToken> {
-    ServiceToken findByName(String name);
-
-    @Transactional
-    @Modifying
-    @Query(value = "truncate table hzb_grafana_service_token", nativeQuery = 
true)
-    void truncate();
+public interface GrafanaConfigDao extends JpaRepository<GeneralConfig, Long>, 
JpaSpecificationExecutor<GeneralConfig> {
+    
+    /**
+     * Query by type
+     * @param type type
+     * @return Return the queried configuration information
+     */
+    GeneralConfig findByType(String type);
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java
deleted file mode 100644
index ec47f495f..000000000
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java
+++ /dev/null
@@ -1,38 +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.grafana.dao;
-
-import org.apache.hertzbeat.common.entity.grafana.ServiceAccount;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * ServiceAccount Dao
- */
-public interface ServiceAccountDao extends JpaRepository<ServiceAccount, 
Long>, JpaSpecificationExecutor<ServiceAccount> {
-
-    ServiceAccount findByName(String name);
-
-    @Transactional
-    @Modifying
-    @Query(value = "truncate table hzb_grafana_service_account", nativeQuery = 
true)
-    void truncate();
-}
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java
 b/grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
similarity index 60%
rename from 
common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java
rename to 
grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
index 1ffcc9e81..337997693 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
@@ -15,36 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.hertzbeat.common.entity.grafana;
+package org.apache.hertzbeat.grafana.dto;
 
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-
 /**
- * Grafana service token entity
+ * System Configuration
  */
-@Entity
-@Table(name = "hzb_grafana_service_token")
 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
-@Schema(description = "Grafana service token entity")
-public class ServiceToken {
-    @Id
-    @Schema(description = "Service token id")
-    private Long id;
-    @Schema(description = "Service token name")
-    private String name;
-    @Schema(description = "Service token key")
-    @Column(name = "`key`")
-    private String key;
+public class GrafanaConfig {
+    
+    /**
+     * api token
+     */
+    private String token;
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
index 2249743f2..e5168c299 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
@@ -17,11 +17,12 @@
 
 package org.apache.hertzbeat.grafana.service;
 
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.CREATE_DASHBOARD_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DELETE_DASHBOARD_API;
-import static org.apache.hertzbeat.grafana.common.CommonConstants.INSTANCE;
-import static org.apache.hertzbeat.grafana.common.CommonConstants.KIOSK;
-import static org.apache.hertzbeat.grafana.common.CommonConstants.REFRESH;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_DASHBOARD_API;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.DELETE_DASHBOARD_API;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.INSTANCE;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.KIOSK;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.REFRESH;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.USE_DATASOURCE;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -68,7 +69,7 @@ public class DashboardService {
      * @return ResponseEntity containing the response from Grafana
      */
     @Transactional(rollbackFor = Exception.class)
-    public ResponseEntity<?> createDashboard(String dashboardJson, Long 
monitorId) {
+    public ResponseEntity<?> createOrUpdateDashboard(String dashboardJson, 
Long monitorId) {
         String token = serviceAccountService.getToken();
         String url = grafanaProperties.getPrefix() + 
grafanaProperties.getUrl() + CREATE_DASHBOARD_API;
 
@@ -90,7 +91,8 @@ public class DashboardService {
                 if (grafanaDashboard != null) {
                     grafanaDashboard.setEnabled(true);
                     grafanaDashboard.setUrl(grafanaProperties.getPrefix() + 
grafanaProperties.getUrl()
-                            + 
grafanaDashboard.getUrl().replace(grafanaProperties.getUrl(), "") + KIOSK + 
REFRESH + INSTANCE + monitorId);
+                            + 
grafanaDashboard.getUrl().replace(grafanaProperties.getUrl(), "")
+                            + KIOSK + REFRESH + INSTANCE + monitorId + 
USE_DATASOURCE);
                     grafanaDashboard.setMonitorId(monitorId);
                     dashboardDao.save(grafanaDashboard);
                     log.info("create dashboard success, token: {}", 
response.getBody());
@@ -105,8 +107,7 @@ public class DashboardService {
             throw new RuntimeException("create dashboard error", ex);
         }
     }
-
-
+    
     /**
      * Deletes a dashboard in Grafana by monitor ID.
      *
@@ -141,8 +142,7 @@ public class DashboardService {
             }
         }
     }
-
-
+    
     /**
      * Retrieves a dashboard by monitor ID.
      *
@@ -165,17 +165,4 @@ public class DashboardService {
             dashboardDao.save(grafanaDashboard);
         }
     }
-
-    /**
-     * Enables a Grafana dashboard by monitor ID.
-     *
-     * @param monitorId the ID of the monitor associated with the dashboard
-     */
-    public void openGrafanaDashboard(Long monitorId) {
-        GrafanaDashboard grafanaDashboard = 
dashboardDao.findByMonitorId(monitorId);
-        if (grafanaDashboard != null) {
-            grafanaDashboard.setEnabled(true);
-            dashboardDao.save(grafanaDashboard);
-        }
-    }
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
index baebd1baf..656529dcc 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
@@ -18,13 +18,11 @@
 package org.apache.hertzbeat.grafana.service;
 
 
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.CREATE_DATASOURCE_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DATASOURCE_ACCESS;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DATASOURCE_NAME;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DATASOURCE_TYPE;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DELETE_DATASOURCE_API;
-import jakarta.annotation.PostConstruct;
-import java.util.Base64;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_DATASOURCE_API;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_ACCESS;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_NAME;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_TYPE;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.QUERY_DATASOURCE_API;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.grafana.config.GrafanaProperties;
 import 
org.apache.hertzbeat.warehouse.store.history.vm.VictoriaMetricsProperties;
@@ -35,21 +33,16 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestTemplate;
 
 /**
- * Service for managing Grafana datasources.
+ * Service for managing Grafana datasource.
  */
 @Service
 @Slf4j
 public class DatasourceService {
 
-    private String grafanaUrl;
-    private String username;
-    private String password;
-    private String prefix;
-    private String victoriaMetricsUrl;
-
     private final GrafanaProperties grafanaProperties;
     private final VictoriaMetricsProperties warehouseProperties;
     private final RestTemplate restTemplate;
@@ -65,70 +58,39 @@ public class DatasourceService {
         this.restTemplate = restTemplate;
     }
 
-    @PostConstruct
-    public void init() {
-        this.grafanaUrl = grafanaProperties.getUrl();
-        this.username = grafanaProperties.username();
-        this.password = grafanaProperties.password();
-        this.prefix = grafanaProperties.getPrefix();
-        this.victoriaMetricsUrl = warehouseProperties.url();
-    }
-
     /**
      * Create a new datasource in Grafana.
      */
-    public void createDatasource() {
-        String url = String.format(prefix + CREATE_DATASOURCE_API, username, 
password, grafanaUrl);
-
-        HttpHeaders headers = createHeaders();
-
-        String body = String.format(
-                
"{\"name\":\"%s\",\"type\":\"%s\",\"access\":\"%s\",\"url\":\"%s\",\"basicAuth\":%s}",
-                DATASOURCE_NAME, DATASOURCE_TYPE, DATASOURCE_ACCESS, 
victoriaMetricsUrl, false
-        );
-
-        HttpEntity<String> entity = new HttpEntity<>(body, headers);
-
-        try {
-            ResponseEntity<String> response = restTemplate.postForEntity(url, 
entity, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Create datasource success");
-            }
-        } catch (Exception ex) {
-            log.error("Create datasource error", ex);
-            throw new RuntimeException("Create datasource error", ex);
-        }
-    }
-
-    /**
-     * Delete a datasource in Grafana.
-     */
-    public void deleteDatasource() {
-        String url = String.format(prefix + DELETE_DATASOURCE_API, username, 
password, grafanaUrl, DATASOURCE_NAME);
-
-        HttpHeaders headers = createHeaders();
-
+    public void existOrCreateDatasource(String token) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        headers.setBearerAuth(token);
+        // query if exist this datasource
+        String queryUrl = grafanaProperties.getPrefix() + 
grafanaProperties.getUrl() + QUERY_DATASOURCE_API;
         HttpEntity<Void> entity = new HttpEntity<>(headers);
-
         try {
-            ResponseEntity<String> response = restTemplate.exchange(url, 
HttpMethod.DELETE, entity, String.class);
+            ResponseEntity<String> response = restTemplate.exchange(queryUrl, 
HttpMethod.GET, entity, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Delete datasource success");
+                log.info("{} datasource exist", DATASOURCE_NAME);
             }
-
-        } catch (Exception ex) {
-            log.error("Delete datasource error", ex);
+        } catch (HttpClientErrorException.NotFound notFound) {
+            String createUrl = grafanaProperties.getPrefix() + 
grafanaProperties.getUrl() + CREATE_DATASOURCE_API;
+            String body = String.format(
+                    
"{\"name\":\"%s\",\"type\":\"%s\",\"access\":\"%s\",\"url\":\"%s\",\"basicAuth\":%s}",
+                    DATASOURCE_NAME, DATASOURCE_TYPE, DATASOURCE_ACCESS, 
warehouseProperties.url(), false
+            );
+            HttpEntity<String> createEntity = new HttpEntity<>(body, headers);
+            try {
+                ResponseEntity<String> createResponse = 
restTemplate.postForEntity(createUrl, createEntity, String.class);
+                if (createResponse.getStatusCode().is2xxSuccessful()) {
+                    log.info("Create datasource success");
+                }
+            } catch (Exception e) {
+                log.error("Create datasource error", e);
+            }
+        } catch (Exception e) {
+            log.error("Query datasource error", e);
         }
-    }
-
-    private HttpHeaders createHeaders() {
-        String auth = username + ":" + password;
-        byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
-        String authHeader = "Basic " + new String(encodedAuth);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_JSON);
-        headers.set("Authorization", authHeader);
-        return headers;
+        
     }
 }
diff --git 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
index 355c621b9..4d4080952 100644
--- 
a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
+++ 
b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
@@ -17,27 +17,23 @@
 
 package org.apache.hertzbeat.grafana.service;
 
-import static org.apache.hertzbeat.grafana.common.CommonConstants.ACCOUNT_NAME;
-import static org.apache.hertzbeat.grafana.common.CommonConstants.ACCOUNT_ROLE;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.ACCOUNT_TOKEN_NAME;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.CREATE_SERVICE_ACCOUNT_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.CREATE_SERVICE_TOKEN_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.DELETE_SERVICE_ACCOUNT_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.GET_SERVICE_ACCOUNTS_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.GET_SERVICE_TOKENS_API;
-import static 
org.apache.hertzbeat.grafana.common.CommonConstants.HERTZBEAT_TOKEN;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.ACCOUNT_NAME;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.ACCOUNT_ROLE;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_SERVICE_ACCOUNT_API;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_SERVICE_TOKEN_API;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.GET_SERVICE_ACCOUNTS_API;
+import static 
org.apache.hertzbeat.grafana.common.GrafanaConstants.GRAFANA_CONFIG;
 import com.fasterxml.jackson.databind.JsonNode;
 import jakarta.annotation.PostConstruct;
 import java.util.Base64;
-import java.util.List;
 import java.util.Objects;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.common.entity.grafana.ServiceAccount;
-import org.apache.hertzbeat.common.entity.grafana.ServiceToken;
+import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
+import org.apache.hertzbeat.common.util.CommonUtil;
 import org.apache.hertzbeat.common.util.JsonUtil;
 import org.apache.hertzbeat.grafana.config.GrafanaProperties;
-import org.apache.hertzbeat.grafana.dao.ServiceAccountDao;
-import org.apache.hertzbeat.grafana.dao.ServiceTokenDao;
+import org.apache.hertzbeat.grafana.dao.GrafanaConfigDao;
+import org.apache.hertzbeat.grafana.dto.GrafanaConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -56,8 +52,7 @@ import org.springframework.web.client.RestTemplate;
 public class ServiceAccountService {
 
     private final GrafanaProperties grafanaProperties;
-    private final ServiceAccountDao serviceAccountDao;
-    private final ServiceTokenDao serviceTokenDao;
+    private final GrafanaConfigDao grafanaConfigDao;
     private final RestTemplate restTemplate;
 
     private String url;
@@ -68,13 +63,11 @@ public class ServiceAccountService {
     @Autowired
     public ServiceAccountService(
             GrafanaProperties grafanaProperties,
-            ServiceAccountDao serviceAccountDao,
-            ServiceTokenDao serviceTokenDao,
+            GrafanaConfigDao grafanaConfigDao,
             RestTemplate restTemplate
     ) {
         this.grafanaProperties = grafanaProperties;
-        this.serviceAccountDao = serviceAccountDao;
-        this.serviceTokenDao = serviceTokenDao;
+        this.grafanaConfigDao = grafanaConfigDao;
         this.restTemplate = restTemplate;
     }
 
@@ -84,18 +77,20 @@ public class ServiceAccountService {
         this.username = grafanaProperties.username();
         this.password = grafanaProperties.password();
         this.prefix = grafanaProperties.getPrefix();
-        ServiceToken serviceToken = 
serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (serviceToken == null) {
-            log.error("Service token {} not found", ACCOUNT_TOKEN_NAME);
-        }
     }
 
     /**
-     * Creates a new service admin account.
+     * Creates a new service admin account id.
      *
      * @return ResponseEntity containing the result of the account creation
      */
-    public ResponseEntity<String> createServiceAccount() {
+    public Long createServiceAccount() {
+        JsonNode accounts = 
Objects.requireNonNull(JsonUtil.fromJson(getAccounts().getBody())).path("serviceAccounts");
+        for (JsonNode account : accounts) {
+            if (account.get("name").asText().equals(ACCOUNT_NAME)) {
+                return account.get("id").asLong();
+            }
+        }
         String endpoint = String.format(prefix + CREATE_SERVICE_ACCOUNT_API, 
username, password, url);
         HttpHeaders headers = createHeaders();
         String body = 
String.format("{\"name\":\"%s\",\"role\":\"%s\",\"isDisabled\":false}", 
ACCOUNT_NAME, ACCOUNT_ROLE);
@@ -104,72 +99,71 @@ public class ServiceAccountService {
         try {
             ResponseEntity<String> response = 
restTemplate.postForEntity(endpoint, request, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                ServiceAccount serviceAccount = 
JsonUtil.fromJson(response.getBody(), ServiceAccount.class);
-                if (serviceAccount != null) {
-                    serviceAccountDao.save(serviceAccount);
-                    log.info("Create service account success: {}", 
serviceAccount);
+                JsonNode jsonNode = JsonUtil.fromJson(response.getBody());
+                if (jsonNode != null && jsonNode.has("id")) {
+                    return jsonNode.get("id").asLong();
                 }
             }
-            return response;
         } catch (Exception e) {
             log.error("Service account creation failed", e);
             throw new RuntimeException("Service account creation failed");
         }
-    }
-
-    /**
-     * Deletes a service account by ID.
-     *
-     * @param id ID of the service account to delete
-     * @return ResponseEntity containing the result of the deletion
-     */
-    public ResponseEntity<String> deleteAccount(Long id) {
-        String endpoint = String.format(prefix + DELETE_SERVICE_ACCOUNT_API, 
username, password, url, id);
-        HttpHeaders headers = createHeaders();
-
-        HttpEntity<String> request = new HttpEntity<>(headers);
-        try {
-            ResponseEntity<String> response = restTemplate.exchange(endpoint, 
HttpMethod.DELETE, request, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Delete service account success");
-            }
-            return response;
-        } catch (Exception e) {
-            log.error("Delete service account error", e);
-            throw new RuntimeException("Delete service account error");
-        }
+        return null;
     }
 
     /**
      * Creates a new API token for a service account.
      *
-     * @return ResponseEntity containing the result of the token creation
      */
-    public ResponseEntity<String> createToken() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
+    public String applyForToken() {
+        Long accountId = createServiceAccount();
+        if (accountId == null) {
             log.error("Service account not found");
             throw new RuntimeException("Service account not found");
         }
-        String endpoint = String.format(prefix + CREATE_SERVICE_TOKEN_API, 
username, password, url, hertzbeat.getId());
+        String endpoint = String.format(prefix + CREATE_SERVICE_TOKEN_API, 
username, password, url, accountId);
         HttpHeaders headers = createHeaders();
-        String body = String.format("{\"name\":\"%s\"}", HERTZBEAT_TOKEN);
+        String body = String.format("{\"name\":\"%s\"}", 
CommonUtil.generateRandomWord(6));
 
         HttpEntity<String> request = new HttpEntity<>(body, headers);
         try {
             ResponseEntity<String> response = 
restTemplate.postForEntity(endpoint, request, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                ServiceToken serviceToken = 
JsonUtil.fromJson(response.getBody(), ServiceToken.class);
-                if (serviceToken != null) {
-                    serviceTokenDao.save(serviceToken);
+                JsonNode jsonNode = JsonUtil.fromJson(response.getBody());
+                if (jsonNode != null && jsonNode.has("key")) {
+                    String token = jsonNode.get("key").asText();
+                    GrafanaConfig grafanaConfig = 
GrafanaConfig.builder().token(token).build();
+                    GeneralConfig generalConfig = 
GeneralConfig.builder().type(GRAFANA_CONFIG)
+                            .content(JsonUtil.toJson(grafanaConfig)).build();
+                    grafanaConfigDao.save(generalConfig);
+                    return token;
                 }
                 log.info("Create token success: {}", response.getBody());
             }
-            return response;
         } catch (Exception e) {
             log.error("Create token error", e);
             throw new RuntimeException("Create token error");
         }
+        return null;
+    }
+
+    /**
+     * Retrieves the token for a service account.
+     *
+     * @return The token key
+     */
+    public String getToken() {
+        GeneralConfig generalConfig = 
grafanaConfigDao.findByType(GRAFANA_CONFIG);
+        if (generalConfig == null) {
+            log.error("Service token not found");
+            return null;
+        }
+        GrafanaConfig grafanaConfig = 
JsonUtil.fromJson(generalConfig.getContent(), GrafanaConfig.class);
+        if (grafanaConfig == null) {
+            log.error("Service token not found");
+            return null;
+        }
+        return grafanaConfig.getToken();
     }
 
     /**
@@ -194,108 +188,6 @@ public class ServiceAccountService {
         }
     }
 
-    /**
-     * Retrieves all API tokens for service accounts.
-     *
-     * @return ResponseEntity containing the list of tokens
-     */
-    public ResponseEntity<String> getTokens() {
-        String endpoint = String.format(prefix + GET_SERVICE_TOKENS_API, 
username, password, url, getAccountId());
-        HttpHeaders headers = createHeaders();
-
-        HttpEntity<String> request = new HttpEntity<>(headers);
-        try {
-            ResponseEntity<String> response = restTemplate.exchange(endpoint, 
HttpMethod.GET, request, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Get tokens success");
-            }
-            return response;
-        } catch (Exception e) {
-            log.error("Get tokens error", e);
-            throw new RuntimeException("Get tokens error");
-        }
-    }
-
-    /**
-     * Retrieves the token for a service account.
-     *
-     * @return The token key
-     */
-    public String getToken() {
-        ServiceToken hertzbeatToken = 
serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (hertzbeatToken == null) {
-            log.error("Service token not found");
-            throw new RuntimeException("Service token not found");
-        }
-        return hertzbeatToken.getKey();
-    }
-
-    /**
-     * Deletes a service account token.
-     */
-    public void deleteToken() {
-        ServiceToken hertzbeatToken = 
serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (hertzbeatToken == null) {
-            log.error("Service token not found");
-            throw new RuntimeException("Service token not found");
-        }
-        serviceTokenDao.delete(hertzbeatToken);
-    }
-
-    /**
-     * Retrieves the ID of the service account.
-     *
-     * @return The ID of the service account
-     */
-    public long getAccountId() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        log.info("Service account: {}", hertzbeat);
-        return hertzbeat.getId();
-    }
-
-    /**
-     * Retrieves the service account.
-     *
-     * @return The service account
-     */
-    public ServiceAccount getAccount() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        log.info("Service account: {}", hertzbeat);
-        return hertzbeat;
-    }
-
-    /**
-     * Deletes the service account.
-     */
-    public void deleteAccount() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        serviceAccountDao.delete(hertzbeat);
-    }
-
-    /**
-     * Reloads the service accounts and tokens, clearing existing data.
-     */
-    public void reload() {
-        List<JsonNode> idList = 
Objects.requireNonNull(JsonUtil.fromJson(getAccounts().getBody())).path("serviceAccounts").findValues("id");
-        for (JsonNode jsonNode : idList) {
-            deleteAccount(jsonNode.asLong());
-        }
-        serviceAccountDao.truncate();
-        serviceTokenDao.truncate();
-    }
-
     private HttpHeaders createHeaders() {
         String auth = username + ":" + password;
         byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
@@ -306,4 +198,4 @@ public class ServiceAccountService {
         headers.set("Authorization", authHeader);
         return headers;
     }
-}
\ No newline at end of file
+}
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorController.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorController.java
index f159fec59..392f9b7df 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorController.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/controller/MonitorController.java
@@ -55,7 +55,7 @@ public class MonitorController {
     public ResponseEntity<Message<Void>> addNewMonitor(@Valid @RequestBody 
MonitorDto monitorDto) {
         // Verify request data
         monitorService.validate(monitorDto, false);
-        monitorService.addMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector());
+        monitorService.addMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector(), 
monitorDto.getGrafanaDashboard());
         return ResponseEntity.ok(Message.success("Add success"));
     }
 
@@ -64,7 +64,7 @@ public class MonitorController {
     public ResponseEntity<Message<Void>> modifyMonitor(@Valid @RequestBody 
MonitorDto monitorDto) {
         // Verify request data
         monitorService.validate(monitorDto, true);
-        monitorService.modifyMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector());
+        monitorService.modifyMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector(), 
monitorDto.getGrafanaDashboard());
         return ResponseEntity.ok(Message.success("Modify success"));
     }
 
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java 
b/manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
index 9c71eb1ad..619442fb5 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
@@ -25,6 +25,7 @@ import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import java.util.List;
 import lombok.Data;
+import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
 import org.apache.hertzbeat.common.entity.manager.Param;
 
@@ -51,9 +52,9 @@ public class MonitorDto {
     @Schema(description = "Whether to Detect", accessMode = READ_WRITE)
     private boolean detected;
     
-    /**
-     * which collector this monitoring want to pin
-     */
     @Schema(description = "pinned collector, default null if system dispatch", 
accessMode = READ_WRITE)
     private String collector;
+    
+    @Schema(description = "grafana dashboard")
+    private GrafanaDashboard grafanaDashboard;
 }
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java
index 9a47f80c1..d03b17476 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/AccountService.java
@@ -38,7 +38,7 @@ public interface AccountService {
      * Use refresh TOKEN to re-acquire TOKEN
      * @param refreshToken refreshToken
      * @return token and refresh token
-     * @throws AuthenticationException failed to refresh
+     * @throws Exception failed to refresh
      */
-    RefreshTokenResponse refreshToken(String refreshToken) throws 
AuthenticationException;
+    RefreshTokenResponse refreshToken(String refreshToken) throws Exception;
 }
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
index 0a3007e86..abbe00072 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/MonitorService.java
@@ -21,6 +21,7 @@ import jakarta.servlet.http.HttpServletResponse;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+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;
@@ -46,12 +47,14 @@ public interface MonitorService {
 
     /**
      * Add monitoring
-     * @param monitor   Monitoring Entity
-     * @param params    Parameter information
-     * @param collector collector pinned
+     *
+     * @param monitor          Monitoring Entity
+     * @param params           Parameter information
+     * @param collector        collector pinned
+     * @param dashboard       grafana dashboard
      * @throws RuntimeException Add process exception throw
      */
-    void addMonitor(Monitor monitor, List<Param> params, String collector) 
throws RuntimeException;
+    void addMonitor(Monitor monitor, List<Param> params, String collector, 
GrafanaDashboard dashboard) throws RuntimeException;
 
     /**
      * Verify the correctness of request data parameters
@@ -63,12 +66,14 @@ public interface MonitorService {
 
     /**
      * Modify update monitoring
-     * @param monitor   Monitor Entity
-     * @param params    Parameter information
-     * @param collector collector pinned
+     *
+     * @param monitor          Monitor Entity
+     * @param params           Parameter information
+     * @param collector        collector pinned
+     * @param dashboard        grafana dashboard
      * @throws RuntimeException Exception thrown during modification
      */
-    void modifyMonitor(Monitor monitor, List<Param> params, String collector) 
throws RuntimeException;
+    void modifyMonitor(Monitor monitor, List<Param> params, String collector, 
GrafanaDashboard dashboard) throws RuntimeException;
 
     /**
      * Delete Monitor
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
index 5c6ee688f..1601c261e 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
@@ -69,7 +69,7 @@ public abstract class AbstractImExportServiceImpl implements 
ImExportService {
                 if (monitorDto.isDetected()) {
                     monitorService.detectMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector());
                 }
-                monitorService.addMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector());
+                monitorService.addMonitor(monitorDto.getMonitor(), 
monitorDto.getParams(), monitorDto.getCollector(), 
monitorDto.getGrafanaDashboard());
             });
         }
     }
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java
index 7d14d6234..8041ec0ba 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AccountServiceImpl.java
@@ -86,7 +86,7 @@ public class AccountServiceImpl implements AccountService {
     }
 
     @Override
-    public RefreshTokenResponse refreshToken(String refreshToken) throws 
AuthenticationException {
+    public RefreshTokenResponse refreshToken(String refreshToken) throws 
Exception {
         Claims claims = JsonWebTokenUtil.parseJwt(refreshToken);
         String userId = String.valueOf(claims.getSubject());
         boolean isRefresh = claims.get("refresh", Boolean.class);
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
index c11b708ee..8105d13df 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
@@ -44,6 +44,7 @@ import org.apache.hertzbeat.common.constants.CommonConstants;
 import org.apache.hertzbeat.common.constants.ExportFileConstants;
 import org.apache.hertzbeat.common.constants.NetworkConstants;
 import org.apache.hertzbeat.common.constants.SignConstants;
+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;
@@ -192,7 +193,7 @@ public class MonitorServiceImpl implements MonitorService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void addMonitor(Monitor monitor, List<Param> params, String 
collector) throws RuntimeException {
+    public void addMonitor(Monitor monitor, List<Param> params, String 
collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
         // Apply for monitor id
         long monitorId = SnowFlakeIdGenerator.generateId();
         // Init Set Default Tags: monitorId monitorName app
@@ -236,8 +237,8 @@ public class MonitorServiceImpl implements MonitorService {
             monitor.setId(monitorId);
             monitor.setJobId(jobId);
             // create grafana dashboard
-            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
monitor.getGrafanaDashboard().isEnabled()) {
-                
dashboardService.createDashboard(monitor.getGrafanaDashboard().getTemplate(), 
monitorId);
+            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
grafanaDashboard != null && grafanaDashboard.isEnabled()) {
+                
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), 
monitorId);
             }
             monitorDao.save(monitor);
             paramDao.saveAll(params);
@@ -511,7 +512,7 @@ public class MonitorServiceImpl implements MonitorService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void modifyMonitor(Monitor monitor, List<Param> params, String 
collector) throws RuntimeException {
+    public void modifyMonitor(Monitor monitor, List<Param> params, String 
collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
         long monitorId = monitor.getId();
         // Check to determine whether the monitor corresponding to the monitor 
id exists
         Optional<Monitor> queryOption = monitorDao.findById(monitorId);
@@ -572,18 +573,14 @@ public class MonitorServiceImpl implements MonitorService 
{
             }
             // force update gmtUpdate time, due the case: monitor not change, 
param change. we also think monitor change
             monitor.setGmtUpdate(LocalDateTime.now());
-            // create or open grafana dashboard
-            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
monitor.getGrafanaDashboard().isEnabled()) {
-                if (dashboardService.getDashboardByMonitorId(monitorId) == 
null) {
-                    
dashboardService.createDashboard(monitor.getGrafanaDashboard().getTemplate(), 
monitorId);
+            // update or open grafana dashboard
+            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
grafanaDashboard != null) {
+                if (grafanaDashboard.isEnabled()) {
+                    
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), 
monitorId);
                 } else {
-                    dashboardService.openGrafanaDashboard(monitorId);
+                    dashboardService.closeGrafanaDashboard(monitorId);
                 }
             }
-            // close grafana dashboard
-            if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && 
!monitor.getGrafanaDashboard().isEnabled()) {
-                dashboardService.closeGrafanaDashboard(monitorId);
-            }
             monitorDao.save(monitor);
             if (params != null) {
                 paramDao.saveAll(params);
@@ -647,7 +644,7 @@ public class MonitorServiceImpl implements MonitorService {
                 List<CollectRep.MetricsData> metricsDataList = 
warehouseService.queryMonitorMetricsData(id);
                 List<String> metrics = 
metricsDataList.stream().map(CollectRep.MetricsData::getMetrics).collect(Collectors.toList());
                 monitorDto.setMetrics(metrics);
-                
monitor.setGrafanaDashboard(dashboardService.getDashboardByMonitorId(id));
+                
monitorDto.setGrafanaDashboard(dashboardService.getDashboardByMonitorId(id));
             } else {
                 Job job = appService.getAppDefine(monitor.getApp());
                 List<String> metrics = job.getMetrics().stream()
@@ -918,7 +915,7 @@ public class MonitorServiceImpl implements MonitorService {
         monitor.setTags(newTags);
 
         monitor.setName(String.format("%s - copy", monitor.getName()));
-        addMonitor(monitor, params, null);
+        addMonitor(monitor, params, null, null);
     }
 
     private List<Tag> filterTags(List<Tag> tags) {
diff --git 
a/manager/src/test/java/org/apache/hertzbeat/manager/service/AccountServiceTest.java
 
b/manager/src/test/java/org/apache/hertzbeat/manager/service/AccountServiceTest.java
index 88fc2c9d6..c4804a116 100644
--- 
a/manager/src/test/java/org/apache/hertzbeat/manager/service/AccountServiceTest.java
+++ 
b/manager/src/test/java/org/apache/hertzbeat/manager/service/AccountServiceTest.java
@@ -117,7 +117,7 @@ class AccountServiceTest {
     }
 
     @Test
-    void testRefreshTokenWithValidToken() throws AuthenticationException {
+    void testRefreshTokenWithValidToken() throws Exception {
 
         String userId = "admin";
         String refreshToken = JsonWebTokenUtil.issueJwt(userId, 3600L, 
Collections.singletonMap("refresh", true));
diff --git 
a/manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
 
b/manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
index c61aa03a4..d8dafe3bc 100644
--- 
a/manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
+++ 
b/manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
@@ -196,7 +196,7 @@ class MonitorServiceTest {
         when(monitorDao.save(monitor)).thenReturn(monitor);
         List<Param> params = Collections.singletonList(new Param());
         when(paramDao.saveAll(params)).thenReturn(params);
-        assertDoesNotThrow(() -> monitorService.addMonitor(monitor, params, 
null));
+        assertDoesNotThrow(() -> monitorService.addMonitor(monitor, params, 
null, null));
     }
 
     @Test
@@ -211,7 +211,7 @@ class MonitorServiceTest {
         when(collectJobScheduling.addAsyncCollectJob(job, 
null)).thenReturn(1L);
         List<Param> params = Collections.singletonList(new Param());
         when(monitorDao.save(monitor)).thenThrow(RuntimeException.class);
-        assertThrows(MonitorDatabaseException.class, () -> 
monitorService.addMonitor(monitor, params, null));
+        assertThrows(MonitorDatabaseException.class, () -> 
monitorService.addMonitor(monitor, params, null, null));
     }
 
     /**
@@ -587,7 +587,7 @@ class MonitorServiceTest {
         dto.setMonitor(monitor);
         when(monitorDao.findById(monitorId)).thenReturn(Optional.empty());
         try {
-            monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), 
null);
+            monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), 
null, null);
         } catch (IllegalArgumentException e) {
             assertEquals("The Monitor " + monitorId + " not exists", 
e.getMessage());
         }
@@ -598,7 +598,7 @@ class MonitorServiceTest {
         Monitor existErrorMonitor = 
Monitor.builder().app("app2").name("memory").host("host").id(monitorId).build();
         
when(monitorDao.findById(monitorId)).thenReturn(Optional.of(existErrorMonitor));
         try {
-            monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), 
null);
+            monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), 
null, null);
         } catch (IllegalArgumentException e) {
             assertEquals("Can not modify monitor's app type", e.getMessage());
         }
@@ -607,7 +607,7 @@ class MonitorServiceTest {
         
when(monitorDao.findById(monitorId)).thenReturn(Optional.of(existOkMonitor));
         when(monitorDao.save(monitor)).thenThrow(RuntimeException.class);
 
-        assertThrows(MonitorDatabaseException.class, () -> 
monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), null));
+        assertThrows(MonitorDatabaseException.class, () -> 
monitorService.modifyMonitor(dto.getMonitor(), dto.getParams(), null, null));
     }
 
     @Test
diff --git a/web-app/src/app/pojo/Monitor.ts b/web-app/src/app/pojo/Monitor.ts
index 9a633515b..c6e05a51e 100644
--- a/web-app/src/app/pojo/Monitor.ts
+++ b/web-app/src/app/pojo/Monitor.ts
@@ -17,7 +17,6 @@
  * under the License.
  */
 
-import { GrafanaDashboard } from './GrafanaDashboard';
 import { Tag } from './Tag';
 
 export class Monitor {
@@ -34,5 +33,4 @@ export class Monitor {
   gmtCreate!: number;
   gmtUpdate!: number;
   tags!: Tag[];
-  grafanaDashboard!: GrafanaDashboard;
 }
diff --git 
a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html 
b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html
index bb394c3cf..5f184a9ad 100755
--- 
a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html
+++ 
b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html
@@ -91,13 +91,13 @@
             ></app-monitor-data-chart>
           </div>
         </nz-tab>
-        <nz-tab *ngIf="monitor.grafanaDashboard && 
monitor.grafanaDashboard.enabled" [nzTitle]="title3Template">
+        <nz-tab *ngIf="grafanaDashboard.enabled" [nzTitle]="title3Template">
           <ng-template #title3Template>
-            <i nz-icon nzType="line-chart" style="margin-left: 10px"></i>
+            <i nz-icon nzType="radar-chart" style="margin-left: 10px"></i>
             Grafana
           </ng-template>
           <div style="width: 100%; height: 1200px; margin-bottom: 6px">
-            <iframe [src]="monitor.grafanaDashboard.url | safe : 
'resourceUrl'" width="100%" height="100%" style="border: none"> </iframe>
+            <iframe [src]="grafanaDashboard.url | safe : 'resourceUrl'" 
width="100%" height="100%" style="border: none"> </iframe>
           </div>
         </nz-tab>
       </nz-tabset>
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 76a5cf089..fdbd6f381 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
@@ -25,6 +25,7 @@ import { NzNotificationService } from 
'ng-zorro-antd/notification';
 import { throwError } from 'rxjs';
 import { finalize, switchMap } from 'rxjs/operators';
 
+import { GrafanaDashboard } from '../../../pojo/GrafanaDashboard';
 import { Message } from '../../../pojo/Message';
 import { Monitor } from '../../../pojo/Monitor';
 import { Param } from '../../../pojo/Param';
@@ -50,6 +51,7 @@ export class MonitorDetailComponent implements OnInit, 
OnDestroy {
   monitorId!: number;
   app!: string;
   monitor: Monitor = new Monitor();
+  grafanaDashboard: GrafanaDashboard = new GrafanaDashboard();
   options: any;
   port: number | undefined;
   metrics!: string[];
@@ -203,10 +205,8 @@ export class MonitorDetailComponent implements OnInit, 
OnDestroy {
   getGrafana() {
     this.monitorSvc.getGrafanaDashboard(this.monitorId).subscribe(
       message => {
-        if (message.code === 0 && message.msg != null) {
-          this.monitor.grafanaDashboard = message.data;
-        } else {
-          console.warn(message.msg);
+        if (message.code === 0 && message.data != null) {
+          this.grafanaDashboard = message.data;
         }
       },
       error => {
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 40cb5f49c..d2099bf7a 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
@@ -30,6 +30,7 @@
   [loading]="isSpinning"
   [loadingTip]="spinningTip"
   [monitor]="monitor"
+  [grafanaDashboard]="grafanaDashboard"
   [hostName]="hostName"
   [params]="params"
   [paramDefines]="paramDefines"
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 30743394d..3ca2f90ab 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
@@ -84,6 +84,7 @@ export class MonitorEditComponent implements OnInit {
           if (message.code === 0) {
             let paramValueMap = new Map<String, Param>();
             this.monitor = message.data.monitor;
+            this.grafanaDashboard = message.data.grafanaDashboard != undefined 
? message.data.grafanaDashboard : new GrafanaDashboard();
             this.collector = message.data.collector == null ? '' : 
message.data.collector;
             this.titleSvc.setTitleByI18n(`monitor.app.${this.monitor.app}`);
             if (message.data.params != null) {
@@ -194,7 +195,8 @@ export class MonitorEditComponent implements OnInit {
       detected: this.detected,
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams)
+      params: info.params.concat(info.advancedParams),
+      grafanaDashboard: info.grafanaDashboard
     };
     if (this.detected) {
       this.spinningTip = this.i18nSvc.fanyi('monitors.spinning-tip.detecting');
@@ -249,18 +251,4 @@ export class MonitorEditComponent implements OnInit {
     app = app ? app : '';
     this.router.navigateByUrl(`/monitors?app=${app}`);
   }
-
-  //start grafana
-  handleTemplateInput(event: any): any {
-    if (event.file && event.file.originFileObj) {
-      const fileReader = new FileReader();
-      fileReader.readAsText(event.file.originFileObj, 'UTF-8');
-      fileReader.onload = () => {
-        this.grafanaDashboard.template = fileReader.result as string;
-      };
-      fileReader.onerror = error => {
-        console.log(error);
-      };
-    }
-  }
 }
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 0539ec210..0a365c693 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
@@ -165,11 +165,11 @@
           {{ 'monitor.grafana.enabled.label' | i18n }}
         </nz-form-label>
         <nz-form-control nzSpan="8">
-          <nz-switch [(ngModel)]="monitor.grafanaDashboard.enabled" 
name="grafana" id="grafana"></nz-switch>
+          <nz-switch [(ngModel)]="grafanaDashboard.enabled" name="grafana" 
id="grafana"></nz-switch>
         </nz-form-control>
       </nz-form-item>
       <!-- upload grafana dashboard json -->
-      <nz-form-item *ngIf="monitor.grafanaDashboard && 
monitor.grafanaDashboard.enabled && monitor.app === 'prometheus'">
+      <nz-form-item *ngIf="monitor.app === 'prometheus' && 
grafanaDashboard.enabled">
         <nz-form-label nzSpan="7" nzFor="grafanaJson" 
[nzTooltipTitle]="'monitor.grafana.upload.tip' | i18n">
           {{ 'monitor.grafana.upload.label' | i18n }}
         </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 6a931ec99..6942e34bb 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
@@ -31,6 +31,7 @@ import { ParamDefine } from '../../../pojo/ParamDefine';
 })
 export class MonitorFormComponent implements OnChanges {
   @Input() monitor!: any;
+  @Input() grafanaDashboard!: any;
   @Input() loading!: boolean;
   @Input() loadingTip!: string;
   @Input() hostName!: string;
@@ -127,7 +128,13 @@ export class MonitorFormComponent implements OnChanges {
         param.paramValue = (param.paramValue as string).trim();
       }
     });
-    this.formSubmit.emit({ monitor: this.monitor, params: this.params, 
advancedParams: this.advancedParams, collector: this.collector });
+    this.formSubmit.emit({
+      monitor: this.monitor,
+      params: this.params,
+      advancedParams: this.advancedParams,
+      collector: this.collector,
+      grafanaDashboard: this.grafanaDashboard
+    });
   }
 
   onCancel() {
@@ -184,7 +191,7 @@ export class MonitorFormComponent implements OnChanges {
       const fileReader = new FileReader();
       fileReader.readAsText(event.file.originFileObj, 'UTF-8');
       fileReader.onload = () => {
-        this.monitor.grafanaDashboard.template = fileReader.result as string;
+        this.grafanaDashboard.template = fileReader.result as string;
       };
       fileReader.onerror = error => {
         console.log(error);
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 6e0c211ce..5674684ad 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
@@ -30,6 +30,7 @@
   [loading]="isSpinning"
   [loadingTip]="spinningTip"
   [monitor]="monitor"
+  [grafanaDashboard]="grafanaDashboard"
   [hostName]="hostName"
   [params]="params"
   [paramDefines]="paramDefines"
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 0a5e6c9d6..60121f640 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
@@ -50,6 +50,7 @@ export class MonitorNewComponent implements OnInit {
   collectors!: Collector[];
   collector: string = '';
   detected: boolean = false;
+  grafanaDashboard!: GrafanaDashboard;
   // whether it is loading
   isSpinning: boolean = false;
   spinningTip: string = 'Loading...';
@@ -65,7 +66,7 @@ export class MonitorNewComponent implements OnInit {
   ) {
     this.monitor = new Monitor();
     this.monitor.tags = [];
-    this.monitor.grafanaDashboard = new GrafanaDashboard();
+    this.grafanaDashboard = new GrafanaDashboard();
   }
 
   ngOnInit(): void {
@@ -165,7 +166,8 @@ export class MonitorNewComponent implements OnInit {
       detected: this.detected,
       monitor: info.monitor,
       collector: info.collector,
-      params: info.params.concat(info.advancedParams)
+      params: info.params.concat(info.advancedParams),
+      grafanaDashboard: info.grafanaDashboard
     };
     if (this.detected) {
       this.spinningTip = this.i18nSvc.fanyi('monitors.spinning-tip.detecting');


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to