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

xincheng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 8aec3846b4 [Improvement-14243][Metrics] Add user tag of response time 
of api server (#14248)
8aec3846b4 is described below

commit 8aec3846b4b2b186ef1e14d19493352e135549f2
Author: Rick Cheng <[email protected]>
AuthorDate: Thu Jun 1 15:13:28 2023 +0800

    [Improvement-14243][Metrics] Add user tag of response time of api server 
(#14248)
---
 docs/docs/en/guide/metrics/metrics.md              |  2 +-
 docs/docs/zh/guide/metrics/metrics.md              |  2 +-
 .../api/aspect/AccessLogAspect.java                | 22 ++++++++++------
 .../api/metrics/ApiServerMetrics.java              | 29 +++++++++++++++-------
 .../api/service/MetricsCleanUpService.java         |  2 ++
 .../service/impl/MetricsCleanUpServiceImpl.java    |  5 ++++
 .../api/service/impl/UsersServiceImpl.java         |  5 ++++
 .../api/service/UsersServiceTest.java              |  6 +++++
 8 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/docs/docs/en/guide/metrics/metrics.md 
b/docs/docs/en/guide/metrics/metrics.md
index 72911f7b60..e45c3c72d3 100644
--- a/docs/docs/en/guide/metrics/metrics.md
+++ b/docs/docs/en/guide/metrics/metrics.md
@@ -113,7 +113,7 @@ For example, you can get the master metrics by `curl 
http://localhost:5679/actua
 
 - ds.api.request.count: (counter) the number of requests received by the api 
server
 - ds.api.response.count: (counter) the number of responses received by the api 
server, sliced by tag `code`
-- ds.api.response.time: (histogram) the response time distribution of the api 
server
+- ds.api.response.time: (timer) the response time distribution of the api 
server, sliced by tag `user_id`
 - ds.api.resource.upload.size: (histogram) size distribution of resource files 
uploaded by the api server (bytes)
 - ds.api.resource.download.size: (histogram) size distribution of resource 
files download by the api server (bytes)
 
diff --git a/docs/docs/zh/guide/metrics/metrics.md 
b/docs/docs/zh/guide/metrics/metrics.md
index e5c746efa3..ce9430cb7c 100644
--- a/docs/docs/zh/guide/metrics/metrics.md
+++ b/docs/docs/zh/guide/metrics/metrics.md
@@ -113,7 +113,7 @@ metrics exporter端口`server.port`是在application.yaml里定义的: 
master: `
 
 - ds.api.request.count: (counter) api请求次数
 - ds.api.response.count: (counter) api响应次数,可由标签`code`切分
-- ds.api.response.time: (histogram) api响应时间分布
+- ds.api.response.time: (timer) api响应时间分布,可由标签`user_id`切分
 - ds.api.resource.upload.size: (histogram) api上传资源文件大小的分布(bytes)
 - ds.api.resource.download.size: (histogram) api下载资源文件大小的分布(bytes)
 
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java
 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java
index b64e4baa78..f22e98da8c 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java
+++ 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java
@@ -82,6 +82,9 @@ public class AccessLogAspect {
 
         String traceId = 
String.valueOf(CodeGenerateUtils.getInstance().genCode());
 
+        int userId = -1;
+        String userName = "NOT LOGIN";
+
         // log request
         if (!annotation.ignoreRequest()) {
             if (attributes != null) {
@@ -91,7 +94,11 @@ public class AccessLogAspect {
                     traceId = traceIdFromHeader;
                 }
                 // handle login info
-                String userName = parseLoginInfo(request);
+                User loginUser = parseLoginInfo(request);
+                if (loginUser != null) {
+                    userName = loginUser.getUserName();
+                    userId = loginUser.getId();
+                }
 
                 // handle args
                 String argsString = parseArgs(proceedingJoinPoint, annotation);
@@ -113,7 +120,10 @@ public class AccessLogAspect {
 
         long costTime = System.currentTimeMillis() - startTime;
         log.info("Call {}:{} success, cost: {}ms", requestMethod, URI, 
costTime);
-        ApiServerMetrics.recordApiResponseTime(costTime);
+
+        if (userId != -1) {
+            ApiServerMetrics.recordApiResponseTime(costTime, userId);
+        }
 
         return ob;
     }
@@ -160,13 +170,9 @@ public class AccessLogAspect {
         return originalData;
     }
 
-    private String parseLoginInfo(HttpServletRequest request) {
-        String userName = "NOT LOGIN";
+    private User parseLoginInfo(HttpServletRequest request) {
         User loginUser = (User) (request.getAttribute(Constants.SESSION_USER));
-        if (loginUser != null) {
-            userName = loginUser.getUserName();
-        }
-        return userName;
+        return loginUser;
     }
 
 }
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/metrics/ApiServerMetrics.java
 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/metrics/ApiServerMetrics.java
index 47ae1bcfab..08f114dc2e 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/metrics/ApiServerMetrics.java
+++ 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/metrics/ApiServerMetrics.java
@@ -17,10 +17,13 @@
 
 package org.apache.dolphinscheduler.api.metrics;
 
+import java.util.concurrent.TimeUnit;
+
 import lombok.experimental.UtilityClass;
 import io.micrometer.core.instrument.Counter;
 import io.micrometer.core.instrument.DistributionSummary;
 import io.micrometer.core.instrument.Metrics;
+import io.micrometer.core.instrument.Timer;
 
 @UtilityClass
 public class ApiServerMetrics {
@@ -70,13 +73,12 @@ public class ApiServerMetrics {
                     .description("size of download resource files on api")
                     .register(Metrics.globalRegistry);
 
-    private final DistributionSummary apiResponseTimeDistribution =
-            DistributionSummary.builder("ds.api.response.time")
-                    .baseUnit("milliseconds")
-                    .publishPercentiles(0.5, 0.75, 0.95, 0.99)
-                    .publishPercentileHistogram()
-                    .description("response time on api")
-                    .register(Metrics.globalRegistry);
+    static {
+        Timer.builder("ds.api.response.time")
+                .tag("user.id", "dummy")
+                .description("response time on api")
+                .register(Metrics.globalRegistry);
+    }
 
     public void incApiRequestCount() {
         apiRequestCounter.increment();
@@ -106,7 +108,16 @@ public class ApiServerMetrics {
         apiResourceDownloadSizeDistribution.record(size);
     }
 
-    public void recordApiResponseTime(final long milliseconds) {
-        apiResponseTimeDistribution.record(milliseconds);
+    public void recordApiResponseTime(final long milliseconds, final int 
userId) {
+        Metrics.globalRegistry.timer(
+                "ds.api.response.time",
+                "user.id", String.valueOf(userId)).record(milliseconds, 
TimeUnit.MILLISECONDS);
+    }
+
+    public void cleanUpApiResponseTimeMetricsByUserId(final int userId) {
+        Metrics.globalRegistry.remove(
+                Metrics.globalRegistry.timer(
+                        "ds.api.response.time",
+                        "user.id", String.valueOf(userId)));
     }
 }
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MetricsCleanUpService.java
 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MetricsCleanUpService.java
index 7878f91981..9ffa95de1d 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MetricsCleanUpService.java
+++ 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MetricsCleanUpService.java
@@ -21,4 +21,6 @@ public interface MetricsCleanUpService {
 
     void cleanUpWorkflowMetricsByDefinitionCode(String workflowDefinitionCode);
 
+    void cleanUpApiResponseTimeMetricsByUserId(int userId);
+
 }
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/MetricsCleanUpServiceImpl.java
 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/MetricsCleanUpServiceImpl.java
index 70c75aca69..70b19ddeac 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/MetricsCleanUpServiceImpl.java
+++ 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/MetricsCleanUpServiceImpl.java
@@ -17,6 +17,7 @@
 
 package org.apache.dolphinscheduler.api.service.impl;
 
+import org.apache.dolphinscheduler.api.metrics.ApiServerMetrics;
 import org.apache.dolphinscheduler.api.rpc.ApiRpcClient;
 import org.apache.dolphinscheduler.api.service.MetricsCleanUpService;
 import org.apache.dolphinscheduler.common.model.Server;
@@ -59,4 +60,8 @@ public class MetricsCleanUpServiceImpl implements 
MetricsCleanUpService {
         }
     }
 
+    @Override
+    public void cleanUpApiResponseTimeMetricsByUserId(int userId) {
+        ApiServerMetrics.cleanUpApiResponseTimeMetricsByUserId(userId);
+    }
 }
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
index 429523cdf6..05c715a805 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
+++ 
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
@@ -22,6 +22,7 @@ import static 
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationCon
 import org.apache.dolphinscheduler.api.dto.resources.ResourceComponent;
 import org.apache.dolphinscheduler.api.enums.Status;
 import org.apache.dolphinscheduler.api.exceptions.ServiceException;
+import org.apache.dolphinscheduler.api.service.MetricsCleanUpService;
 import org.apache.dolphinscheduler.api.service.UsersService;
 import org.apache.dolphinscheduler.api.utils.CheckUtils;
 import org.apache.dolphinscheduler.api.utils.PageInfo;
@@ -129,6 +130,9 @@ public class UsersServiceImpl extends BaseServiceImpl 
implements UsersService {
     @Autowired
     private K8sNamespaceUserMapper k8sNamespaceUserMapper;
 
+    @Autowired
+    private MetricsCleanUpService metricsCleanUpService;
+
     /**
      * create user, only system admin have permission
      *
@@ -522,6 +526,7 @@ public class UsersServiceImpl extends BaseServiceImpl 
implements UsersService {
         accessTokenMapper.deleteAccessTokenByUserId(id);
 
         if (userMapper.deleteById(id) > 0) {
+            metricsCleanUpService.cleanUpApiResponseTimeMetricsByUserId(id);
             log.info("User is deleted and id is :{}.", id);
             putMsg(result, Status.SUCCESS);
             return result;
diff --git 
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
 
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
index 67862e1557..6e15b76e88 100644
--- 
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
+++ 
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
@@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.api.service;
 import static 
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.USER_MANAGER;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 
 import org.apache.dolphinscheduler.api.enums.Status;
@@ -112,6 +113,9 @@ public class UsersServiceTest {
     @Mock
     private ResourceUserMapper resourceUserMapper;
 
+    @Mock
+    private MetricsCleanUpService metricsCleanUpService;
+
     @Mock
     private UDFUserMapper udfUserMapper;
 
@@ -338,9 +342,11 @@ public class UsersServiceTest {
 
             // success
             
Mockito.when(projectMapper.queryProjectCreatedByUser(1)).thenReturn(null);
+            
Mockito.doNothing().when(metricsCleanUpService).cleanUpApiResponseTimeMetricsByUserId(Mockito.anyInt());
             result = usersService.deleteUserById(loginUser, 1);
             logger.info(result.toString());
             Assertions.assertEquals(Status.SUCCESS, 
result.get(Constants.STATUS));
+            Mockito.verify(metricsCleanUpService, 
times(1)).cleanUpApiResponseTimeMetricsByUserId(Mockito.anyInt());
         } catch (Exception e) {
             logger.error("delete user error", e);
             Assertions.assertTrue(false);

Reply via email to