From 7297146f97701cfb336e2917aa7637eec5927ec8 Mon Sep 17 00:00:00 2001 From: "saimu.msm" Date: Wed, 1 Mar 2023 11:15:40 +0800 Subject: [PATCH] measure --- server/apm/apm-common/pom.xml | 5 + .../apm/common/model/query/BasicTrace.java | 12 +- .../apm/common/model/query/Topology.java | 12 +- .../apm/common/model/query/TraceBrief.java | 16 +- .../common/model/specification/sw/Trace.java | 12 +- .../server/common/service/Measurable.java | 18 ++ .../service/task/AlertTaskScheduler.java | 7 +- .../home/common/service/query/KeyResult.java | 12 +- .../common/service/query/QueryResponse.java | 17 +- .../home/common/service/query/Result.java | 11 +- .../common/service/query/ValueResult.java | 12 +- server/home/home-facade/pom.xml | 5 + .../home/facade/page/MonitorPageResult.java | 19 +- .../biz/access/model/MonitorAccessConfig.java | 19 +- .../server/home/web/AppInitListener.java | 6 +- .../home/web/common/FacadeTemplateImpl.java | 53 +++- .../home/web/common/ManageCallback.java | 22 ++ .../web/controller/AlarmRuleFacadeImpl.java | 73 +++++ .../home/web/controller/QueryFacadeImpl.java | 196 ++++++++++++- .../home/web/filter/Step3AuthFilter.java | 12 +- .../server/home/web/measure/ActionType.java | 18 ++ .../home/web/measure/ApikeyAuthority.java | 73 +++++ .../measure/HoloInsightRequestException.java | 23 ++ .../home/web/measure/MeasureStatistician.java | 266 ++++++++++++++++++ .../server/home/web/measure/ResourceType.java | 27 ++ 25 files changed, 919 insertions(+), 27 deletions(-) create mode 100644 server/common/common-service/src/main/java/io/holoinsight/server/common/service/Measurable.java create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ActionType.java create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ApikeyAuthority.java create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/HoloInsightRequestException.java create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/MeasureStatistician.java create mode 100644 server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ResourceType.java diff --git a/server/apm/apm-common/pom.xml b/server/apm/apm-common/pom.xml index f40c73cc1..4d00b9be9 100644 --- a/server/apm/apm-common/pom.xml +++ b/server/apm/apm-common/pom.xml @@ -46,6 +46,11 @@ com.google.code.gson gson + + io.holoinsight.server + common-service + ${project.version} + diff --git a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/BasicTrace.java b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/BasicTrace.java index 78978ec2b..b22d81010 100644 --- a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/BasicTrace.java +++ b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/BasicTrace.java @@ -3,9 +3,11 @@ */ package io.holoinsight.server.apm.common.model.query; +import io.holoinsight.server.common.service.Measurable; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; @@ -18,7 +20,7 @@ @Data @AllArgsConstructor @NoArgsConstructor -public class BasicTrace implements Serializable { +public class BasicTrace implements Serializable, Measurable { private static final long serialVersionUID = -4060937279918402711L; private String segmentId; @@ -29,4 +31,12 @@ public class BasicTrace implements Serializable { private long start; private boolean isError; private List traceIds = new ArrayList<>(); + + @Override + public long measure() { + if (CollectionUtils.isEmpty(traceIds)) { + return 0; + } + return this.traceIds.size(); + } } diff --git a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/Topology.java b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/Topology.java index 5a892fc82..197358bd3 100644 --- a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/Topology.java +++ b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/Topology.java @@ -3,13 +3,15 @@ */ package io.holoinsight.server.apm.common.model.query; +import io.holoinsight.server.common.service.Measurable; import lombok.Getter; +import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; @Getter -public class Topology { +public class Topology implements Measurable { private final List nodes; private final List calls; @@ -17,4 +19,12 @@ public Topology() { this.nodes = new ArrayList<>(); this.calls = new ArrayList<>(); } + + @Override + public long measure() { + if (CollectionUtils.isEmpty(calls)) { + return 0; + } + return this.calls.size(); + } } diff --git a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/TraceBrief.java b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/TraceBrief.java index d5a1d7f9f..d328ec28f 100644 --- a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/TraceBrief.java +++ b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/query/TraceBrief.java @@ -3,9 +3,11 @@ */ package io.holoinsight.server.apm.common.model.query; +import io.holoinsight.server.common.service.Measurable; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; @@ -18,8 +20,20 @@ @Data @AllArgsConstructor @NoArgsConstructor -public class TraceBrief implements Serializable { +public class TraceBrief implements Serializable, Measurable { private static final long serialVersionUID = -5452437207833607799L; private List traces = new ArrayList<>(); + + @Override + public long measure() { + if (CollectionUtils.isEmpty(traces)) { + return 0; + } + long result = 0; + for (BasicTrace basicTrace : traces) { + result += basicTrace.measure(); + } + return result; + } } diff --git a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/specification/sw/Trace.java b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/specification/sw/Trace.java index b0843003f..7d8bd25f2 100644 --- a/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/specification/sw/Trace.java +++ b/server/apm/apm-common/src/main/java/io/holoinsight/server/apm/common/model/specification/sw/Trace.java @@ -3,9 +3,11 @@ */ package io.holoinsight.server.apm.common.model.specification.sw; +import io.holoinsight.server.common.service.Measurable; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; @@ -18,7 +20,7 @@ @Data @AllArgsConstructor @NoArgsConstructor -public class Trace implements Serializable { +public class Trace implements Serializable, Measurable { private static final long serialVersionUID = 3436393920339302223L; @@ -26,4 +28,12 @@ public class Trace implements Serializable { * span 列表 */ private List spans = new ArrayList<>(); + + @Override + public long measure() { + if (CollectionUtils.isEmpty(spans)) { + return 0; + } + return this.spans.size(); + } } diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/Measurable.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/Measurable.java new file mode 100644 index 000000000..8df4a312d --- /dev/null +++ b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/Measurable.java @@ -0,0 +1,18 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.common.service; + +/** + * Measure the data + * + * @author masaimu + * @version 2023-03-10 16:38:00 + */ +public interface Measurable { + + /** + * @return data size + */ + long measure(); +} diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java index 4da004467..dda832f5d 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java @@ -50,7 +50,8 @@ public class AlertTaskScheduler { public void start() { try { - StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory(getScheduleProperties()); + StdSchedulerFactory stdSchedulerFactory = + new StdSchedulerFactory(getScheduleProperties("AlertTaskScheduler")); Scheduler scheduler = stdSchedulerFactory.getScheduler(); // 创建需要执行的任务 @@ -73,9 +74,9 @@ public void start() { } } - private Properties getScheduleProperties() { + public static Properties getScheduleProperties(String instanceName) { Properties properties = new Properties(); - properties.setProperty("org.quartz.scheduler.instanceName", "AlertTaskScheduler"); + properties.setProperty("org.quartz.scheduler.instanceName", instanceName); properties.setProperty("org.quartz.threadPool.threadCount", "1"); properties.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore"); properties.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); diff --git a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/KeyResult.java b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/KeyResult.java index 8eb1d26c0..f53ba1c75 100644 --- a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/KeyResult.java +++ b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/KeyResult.java @@ -3,7 +3,9 @@ */ package io.holoinsight.server.home.common.service.query; +import io.holoinsight.server.common.service.Measurable; import lombok.Data; +import org.springframework.util.CollectionUtils; import java.util.List; @@ -12,8 +14,16 @@ * @date 2022/4/29 11:23 上午 */ @Data -public class KeyResult { +public class KeyResult implements Measurable { private String metric; private List tags; + + @Override + public long measure() { + if (CollectionUtils.isEmpty(tags)) { + return 0; + } + return tags.size(); + } } diff --git a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/QueryResponse.java b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/QueryResponse.java index d0af5d352..3260010d0 100644 --- a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/QueryResponse.java +++ b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/QueryResponse.java @@ -3,13 +3,28 @@ */ package io.holoinsight.server.home.common.service.query; +import io.holoinsight.server.common.service.Measurable; import lombok.Data; +import org.springframework.util.CollectionUtils; import java.util.List; @Data -public class QueryResponse { +public class QueryResponse implements Measurable { private List results; + @Override + public long measure() { + if (CollectionUtils.isEmpty(results)) { + return 0; + } + long size = 0; + if (!CollectionUtils.isEmpty(results)) { + for (Result result : results) { + size += result.measure(); + } + } + return size; + } } diff --git a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/Result.java b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/Result.java index 082ab164b..72749e9b0 100644 --- a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/Result.java +++ b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/Result.java @@ -3,16 +3,25 @@ */ package io.holoinsight.server.home.common.service.query; +import io.holoinsight.server.common.service.Measurable; import lombok.Data; +import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; @Data -public class Result { +public class Result implements Measurable { private String metric; private Map tags; private List values; + @Override + public long measure() { + if (CollectionUtils.isEmpty(values)) { + return 0; + } + return values.size(); + } } diff --git a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/ValueResult.java b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/ValueResult.java index d0c44f064..0c48feaab 100644 --- a/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/ValueResult.java +++ b/server/home/home-common/src/main/java/io/holoinsight/server/home/common/service/query/ValueResult.java @@ -3,7 +3,9 @@ */ package io.holoinsight.server.home.common.service.query; +import io.holoinsight.server.common.service.Measurable; import lombok.Data; +import org.springframework.util.CollectionUtils; import java.util.List; @@ -12,7 +14,15 @@ * @date 2022/8/16 5:33 下午 */ @Data -public class ValueResult { +public class ValueResult implements Measurable { private String tag; private List values; + + @Override + public long measure() { + if (CollectionUtils.isEmpty(values)) { + return 0; + } + return values.size(); + } } diff --git a/server/home/home-facade/pom.xml b/server/home/home-facade/pom.xml index 871069caa..376251382 100644 --- a/server/home/home-facade/pom.xml +++ b/server/home/home-facade/pom.xml @@ -20,6 +20,11 @@ home-proto ${project.version} + + ${project.groupId} + common-service + ${project.version} + net.devh grpc-client-spring-boot-starter diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/page/MonitorPageResult.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/page/MonitorPageResult.java index ca7e8af73..d76f7073d 100644 --- a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/page/MonitorPageResult.java +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/page/MonitorPageResult.java @@ -3,7 +3,9 @@ */ package io.holoinsight.server.home.facade.page; +import io.holoinsight.server.common.service.Measurable; import lombok.Data; +import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.List; @@ -14,7 +16,7 @@ * @version 1.0: PageRequest.java, v 0.1 2022年03月21日 3:11 下午 jinsong.yjs Exp $ */ @Data -public class MonitorPageResult implements Serializable { +public class MonitorPageResult implements Serializable, Measurable { private static final long serialVersionUID = -8352196951709213541L; private int pageNum = 1; @@ -26,4 +28,19 @@ public class MonitorPageResult implements Serializable { private List items; + @Override + public long measure() { + if (CollectionUtils.isEmpty(items)) { + return 0; + } + long size = 0; + for (T item : items) { + if (item instanceof Measurable) { + size += ((Measurable) item).measure(); + } else { + size += 1; + } + } + return size; + } } diff --git a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/access/model/MonitorAccessConfig.java b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/access/model/MonitorAccessConfig.java index 68b8e97c6..a7eaf3dc0 100644 --- a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/access/model/MonitorAccessConfig.java +++ b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/access/model/MonitorAccessConfig.java @@ -13,7 +13,7 @@ /** * * @author jsy1001de - * @version 1.0: MonitorAccessConfig.java, v 0.1 2022年06月10日 3:56 下午 jinsong.yjs Exp $ + * @version 1.0: MonitorAccessConfig.java, v 0.1 2022-06-10 15:56 jinsong.yjs Exp $ */ @Data public class MonitorAccessConfig { @@ -30,30 +30,35 @@ public class MonitorAccessConfig { private Boolean online; /** - * 是否允许访问所有指标 + * allow all metric access permission */ private boolean accessAll = false; /** - * 允许访问的指标列表 + * allow metric list */ private Set accessRange = new HashSet<>(); /** - * 单机QPS, -1代表不限,0代表黑名单, 其他代表正常限流 + * server QPS, -1: no limit,0: in black list, other: normal flow limie policy */ private long metricQps = -1L; private long metaQps = -1L; /** - * 用户限流信息 + * flow limit configuration */ private Map userRate = new HashMap<>(); /** - * 一次查询指标中最多数据点 + * metric query upper limit */ private long dpsLimit = GatewayConstants.WEB_QUERY_DEFAULT_DPS_LIMIT; /** - * 一次查询维度中最多的Tags + * tags query upper limit */ private long tagsLimit = GatewayConstants.QUERY_DEFAULT_TAGS_LIMIT; + /** + * market plugin id + */ + private Long marketPluginId;; + } diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/AppInitListener.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/AppInitListener.java index cba9e9298..1d4e42ecf 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/AppInitListener.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/AppInitListener.java @@ -9,6 +9,7 @@ import io.holoinsight.server.home.biz.service.ClusterSchedulerTask; import io.holoinsight.server.home.common.util.cache.local.LocalCacheManage; import io.holoinsight.server.home.task.MonitorTaskManager; +import io.holoinsight.server.home.web.measure.MeasureStatistician; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -37,12 +38,13 @@ public class AppInitListener implements InitializingBean { @Autowired private AlertClusterService alertClusterService; - // @Autowired - // private SampleEventWriteTask sampleEventWriteTask; + @Autowired + private MeasureStatistician measureStatistician; @Override public void afterPropertiesSet() { try { + measureStatistician.start(); ScheduleLoadTask.registerTask(superCacheService, true); ScheduleLoadTask.registerTask(localCacheManage, true); // ScheduleLoadTask.registerTask(clusterSchedulerTask, true); diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/FacadeTemplateImpl.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/FacadeTemplateImpl.java index d25bdfef1..77757afe4 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/FacadeTemplateImpl.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/FacadeTemplateImpl.java @@ -3,10 +3,19 @@ */ package io.holoinsight.server.home.web.common; +import io.holoinsight.server.home.biz.access.AccessConfigService; +import io.holoinsight.server.home.biz.access.MonitorAccessService; +import io.holoinsight.server.home.biz.access.model.MonitorAccessConfig; +import io.holoinsight.server.home.biz.access.model.MonitorTokenData; +import io.holoinsight.server.home.common.util.scope.MonitorUser; +import io.holoinsight.server.home.common.util.scope.RequestContext; import io.holoinsight.server.home.web.controller.model.open.GrafanaJsonResult; import io.holoinsight.server.common.JsonResult; +import io.holoinsight.server.home.web.measure.MeasureStatistician; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -17,13 +26,22 @@ @Service public class FacadeTemplateImpl implements FacadeTemplate { + @Autowired + private MeasureStatistician measureStatistician; + @Override @SuppressWarnings("unchecked") public void manage(JsonResult result, ManageCallback callback) { + // 检测 token 的资源访问权限 + measureStatistician.checkAuth(getToken(), callback.getResourceTenant(), + callback.getResourceType(), callback.getActionType()); // 检验参数 callback.checkParameter(); // 执行管理方法 callback.doManage(); + // 计量统计 + measureStatistician.doStat(getToken(), callback.getResourceTenant(), callback.getResourceType(), + callback.getActionType(), result); } @Override @@ -36,7 +54,9 @@ public void manage(JsonResult result, ManageCallback callback, String trace) { callback.checkParameter(); // 执行管理方法 callback.doManage(); - + // 计量统计 + measureStatistician.doStat(getToken(), callback.getResourceTenant(), + callback.getResourceType(), callback.getActionType(), result); } finally { stopWatch.stop(); log.info(trace + ", clientResult=[" + result.isSuccess() + "], clientCost=[" @@ -51,6 +71,37 @@ public void manage(GrafanaJsonResult result, ManageCallback callback) { callback.checkParameter(); // 执行管理方法 callback.doManage(); + // 计量统计 + measureStatistician.doStat(getToken(), callback.getResourceTenant(), callback.getResourceType(), + callback.getActionType(), result); + } + + @Autowired + private AccessConfigService accessConfigService; + @Autowired + private MonitorAccessService monitorAccessService; + + private MonitorTokenData getToken() { + try { + MonitorUser mu = RequestContext.getContext().mu; + String token = mu == null ? StringUtils.EMPTY : mu.getAuthToken(); + if (StringUtils.isEmpty(token)) { + return null; + } + MonitorAccessConfig monitorAccessConfig = + accessConfigService.getAccessConfigDOMap().get(token); + + if (monitorAccessConfig != null) { + MonitorTokenData tokenData = new MonitorTokenData(); + tokenData.setAccessId(monitorAccessConfig.getAccessId()); + tokenData.setAccessKey(monitorAccessConfig.getAccessKey()); + return tokenData; + } + return monitorAccessService.check(token); + } catch (Exception e) { + log.error("fail to get token", e); + return null; + } } } diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/ManageCallback.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/ManageCallback.java index d418b0178..3ac15aa8c 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/ManageCallback.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/common/ManageCallback.java @@ -3,6 +3,12 @@ */ package io.holoinsight.server.home.web.common; +import io.holoinsight.server.home.common.util.scope.MonitorScope; +import io.holoinsight.server.home.common.util.scope.RequestContext; +import io.holoinsight.server.home.web.measure.ActionType; +import io.holoinsight.server.home.web.measure.ResourceType; +import org.apache.commons.lang3.StringUtils; + /** * * @author jsy1001de @@ -12,4 +18,20 @@ public interface ManageCallback { void checkParameter(); void doManage(); + + default ResourceType getResourceType() { + return ResourceType.unknown; + } + + default ActionType getActionType() { + return ActionType.unknown; + } + + default String getResourceTenant() { + MonitorScope ms = RequestContext.getContext().ms; + if (null != ms && !StringUtils.isEmpty(ms.tenant)) { + return ms.tenant; + } + return StringUtils.EMPTY; + } } diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlarmRuleFacadeImpl.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlarmRuleFacadeImpl.java index 2d3ba2ef7..3d180a3c9 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlarmRuleFacadeImpl.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlarmRuleFacadeImpl.java @@ -35,6 +35,9 @@ import io.holoinsight.server.home.web.common.ParaCheckUtil; import io.holoinsight.server.home.web.common.TokenUrls; import io.holoinsight.server.home.web.interceptor.MonitorScopeAuth; +import io.holoinsight.server.home.web.measure.ActionType; +import io.holoinsight.server.home.web.measure.MeasureStatistician; +import io.holoinsight.server.home.web.measure.ResourceType; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -134,6 +137,16 @@ public void doManage() { J.toJson(alarmRuleDTO), null, null, "alarm_rule_create"); JsonResult.createSuccessResult(result, id); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.create; + } }); return result; @@ -198,6 +211,16 @@ public void doManage() { JsonResult.createSuccessResult(result, save); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.update; + } }); return result; @@ -221,6 +244,16 @@ public void doManage() { alarmRuleService.queryById(id, RequestContext.getContext().ms.getTenant()); JsonResult.createSuccessResult(result, save); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -252,6 +285,16 @@ public void doManage() { JsonResult.createSuccessResult(result, rtn); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.delete; + } }); return result; } @@ -276,6 +319,16 @@ public void doManage() { } JsonResult.createSuccessResult(result, alarmRuleService.getListByPage(pageRequest)); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -308,6 +361,16 @@ public void doManage() { JsonResult.createSuccessResult(result, alarmRuleDTOS); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; } @@ -358,6 +421,16 @@ public void doManage() { alarmHistoryService.getListByPage(pageRequest, uniqueIds)); } + + @Override + public ResourceType getResourceType() { + return ResourceType.alert_config; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; } diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/QueryFacadeImpl.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/QueryFacadeImpl.java index 43633b0a0..02294d634 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/QueryFacadeImpl.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/QueryFacadeImpl.java @@ -35,6 +35,8 @@ import io.holoinsight.server.home.web.controller.model.TagQueryRequest; import io.holoinsight.server.home.web.controller.model.open.GrafanaJsonResult; import io.holoinsight.server.home.web.interceptor.MonitorScopeAuth; +import io.holoinsight.server.home.web.measure.ActionType; +import io.holoinsight.server.home.web.measure.ResourceType; import io.holoinsight.server.query.grpc.QueryProto; import io.holoinsight.server.apm.common.model.query.Endpoint; import io.holoinsight.server.apm.common.model.query.QueryTraceRequest; @@ -94,13 +96,23 @@ public void doManage() { QueryResponse response = queryClientService.query(converRequest(request)); JsonResult.createSuccessResult(result, response); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; } @PostMapping("/tags") - public JsonResult queryTags(@RequestBody DataQueryRequest request) { + public JsonResult queryTags(@RequestBody DataQueryRequest request) { final JsonResult result = new JsonResult<>(); @@ -121,13 +133,23 @@ public void doManage() { JsonResult.createSuccessResult(result, response); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric_tag; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; } @PostMapping("/deltags") - public JsonResult deltags(@RequestBody DataQueryRequest request) { + public JsonResult deltags(@RequestBody DataQueryRequest request) { final JsonResult result = new JsonResult<>(); @@ -148,6 +170,16 @@ public void doManage() { JsonResult.createSuccessResult(result, true); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric_tag; + } + + @Override + public ActionType getActionType() { + return ActionType.delete; + } }); return result; @@ -182,6 +214,16 @@ public void doManage() { } JsonResult.createSuccessResult(result, keyResult); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric_tag; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -216,6 +258,16 @@ public void doManage() { List list = queryClientService.queryMetrics(queryMetricsRequest); JsonResult.createSuccessResult(result, list); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -257,6 +309,16 @@ public void doManage() { queryClientService.queryTagValues(builder.build(), tagQueryRequest.getKey()); JsonResult.createSuccessResult(result, response); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric_tag; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -287,6 +349,16 @@ public void doManage() { QueryResponse response = queryClientService.pqlRangeQuery(rangeRequest); GrafanaJsonResult.createSuccessResult(result, response.getResults()); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -316,6 +388,16 @@ public void doManage() { QueryResponse response = queryClientService.pqlInstantQuery(instantRequest); GrafanaJsonResult.createSuccessResult(result, response.getResults()); } + + @Override + public ResourceType getResourceType() { + return ResourceType.metric; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -341,6 +423,16 @@ public void doManage() { TraceBrief traceBrief = queryClientService.queryBasicTraces(request); JsonResult.createSuccessResult(result, traceBrief); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -366,6 +458,16 @@ public void doManage() { Trace trace = queryClientService.queryTrace(request); JsonResult.createSuccessResult(result, trace); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -402,6 +504,16 @@ public void doManage() { } JsonResult.createSuccessResult(result, services); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -428,6 +540,16 @@ public void doManage() { List endpoints = queryClientService.queryEndpointList(request); JsonResult.createSuccessResult(result, endpoints); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -455,6 +577,16 @@ public void doManage() { queryClientService.queryServiceInstanceList(request); JsonResult.createSuccessResult(result, serviceInstances); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -488,6 +620,16 @@ public void doManage() { List VirtualComponents = queryClientService.queryComponentList(request); JsonResult.createSuccessResult(result, VirtualComponents); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -515,6 +657,16 @@ public void doManage() { List traceIds = queryClientService.queryComponentTraceIds(request); JsonResult.createSuccessResult(result, traceIds); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -547,6 +699,16 @@ public void doManage() { Topology topology = queryClientService.queryTopology(request); JsonResult.createSuccessResult(result, topology); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -588,6 +750,16 @@ public void doManage() { JsonResult.createFailResult(result, "Create agent configuration failed!"); } } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.create; + } }); return result; @@ -625,6 +797,16 @@ public void doManage() { AgentConfiguration configuration = agentConfigurationService.get(agentConfiguration); JsonResult.createSuccessResult(result, configuration); } + + @Override + public ResourceType getResourceType() { + return ResourceType.agent_config; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; @@ -657,6 +839,16 @@ public void doManage() { List slowSqlList = queryClientService.querySlowSqlList(request); JsonResult.createSuccessResult(result, slowSqlList); } + + @Override + public ResourceType getResourceType() { + return ResourceType.trace; + } + + @Override + public ActionType getActionType() { + return ActionType.select; + } }); return result; diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/filter/Step3AuthFilter.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/filter/Step3AuthFilter.java index aae777f43..90420922d 100644 --- a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/filter/Step3AuthFilter.java +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/filter/Step3AuthFilter.java @@ -3,10 +3,9 @@ */ package io.holoinsight.server.home.web.filter; -import io.holoinsight.server.home.web.config.RestAuthUtil; import io.holoinsight.server.common.J; -import io.holoinsight.server.home.biz.ula.ULAFacade; import io.holoinsight.server.home.biz.common.MetaDictUtil; +import io.holoinsight.server.home.biz.ula.ULAFacade; import io.holoinsight.server.home.common.util.CookieUtils; import io.holoinsight.server.home.common.util.Debugger; import io.holoinsight.server.home.common.util.StringUtil; @@ -18,6 +17,8 @@ import io.holoinsight.server.home.common.util.scope.PowerConstants; import io.holoinsight.server.home.common.util.scope.RequestContext; import io.holoinsight.server.home.common.util.scope.RequestContext.Context; +import io.holoinsight.server.home.web.config.RestAuthUtil; +import io.holoinsight.server.home.web.measure.HoloInsightRequestException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -59,7 +60,12 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo filterChain.doFilter(servletRequest, servletResponse); } } catch (Throwable e) { - resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "auth check error, " + e.getMessage()); + if (e instanceof HoloInsightRequestException) { + HoloInsightRequestException exception = (HoloInsightRequestException) e; + resp.sendError(exception.sc, exception.getMessage()); + } else { + resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "auth check error, " + e.getMessage()); + } log.error("{} auth check error, auth info: {}", RequestContext.getTrace(), J.toJson(J.toJson(RequestContext.getContext())), e); } finally { diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ActionType.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ActionType.java new file mode 100644 index 000000000..b92f0b115 --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ActionType.java @@ -0,0 +1,18 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ + +package io.holoinsight.server.home.web.measure; + +/** + * @author masaimu + * @version 2023-03-07 16:37:00 + */ +public enum ActionType { + create, // + update, // + delete, // + select, // + unknown, // + ; +} diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ApikeyAuthority.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ApikeyAuthority.java new file mode 100644 index 000000000..7a3fe8927 --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ApikeyAuthority.java @@ -0,0 +1,73 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.web.measure; + +import io.holoinsight.server.common.dao.entity.ApikeyDO; +import io.holoinsight.server.home.biz.access.model.MonitorAccessConfig; +import io.holoinsight.server.home.biz.access.model.MonitorTokenData; +import io.holoinsight.server.home.common.util.MonitorException; +import io.holoinsight.server.home.dal.model.ApiKey; +import io.holoinsight.server.home.dal.model.MarketplacePlugin; +import org.springframework.util.CollectionUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * @author masaimu + * @version 2023-03-01 22:21:00 + */ +public class ApikeyAuthority { + + MonitorAccessConfig accessConfig; + + List resourceTypeList; + + List actionTypeList; + + Long marketPluginId; + + MarketplacePlugin marketplacePlugin; + + List tenants; + + public static ApikeyAuthority build(MonitorAccessConfig monitorAccessConfig) { + ApikeyAuthority apikeyAuthority = new ApikeyAuthority(); + apikeyAuthority.accessConfig = monitorAccessConfig; + apikeyAuthority.resourceTypeList = Arrays.asList(ResourceType.values()); + apikeyAuthority.actionTypeList = Arrays.asList(ActionType.values()); + apikeyAuthority.marketPluginId = monitorAccessConfig.getMarketPluginId(); + return apikeyAuthority; + } + + public void checkResourceType(ResourceType resourceType, MonitorTokenData tokenData) { + if (CollectionUtils.isEmpty(this.resourceTypeList)) { + throw new MonitorException(String.format("Resource type list is empty for token [%s] [%s].", + tokenData.accessId, tokenData.accessKey)); + } else if (!this.resourceTypeList.contains(resourceType)) { + throw new MonitorException( + String.format("Can not find resource type [%s] authority for token [%s] [%s].", + resourceType.code, tokenData.accessId, tokenData.accessKey)); + } + } + + public void checkActionType(ActionType actionType, MonitorTokenData tokenData) { + if (CollectionUtils.isEmpty(this.actionTypeList)) { + throw new MonitorException(String.format("Action type list is empty for token [%s] [%s].", + tokenData.accessId, tokenData.accessKey)); + } else if (!this.actionTypeList.contains(actionType)) { + throw new MonitorException( + String.format("Can not find action type [%s] authority for token [%s] [%s].", + actionType.name(), tokenData.accessId, tokenData.accessKey)); + } + } + + public void checkTenant(String resourceTenant, MonitorTokenData tokenData) { + if (!CollectionUtils.isEmpty(this.tenants) && !this.tenants.contains(resourceTenant)) { + throw new MonitorException( + String.format("Can not find tenant [%s] authority for token [%s] [%s].", resourceTenant, + tokenData.accessId, tokenData.accessKey)); + } + } +} diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/HoloInsightRequestException.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/HoloInsightRequestException.java new file mode 100644 index 000000000..ec48bbe1c --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/HoloInsightRequestException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.web.measure; + +/** + * @author masaimu + * @version 2023-03-05 21:11:00 + */ +public class HoloInsightRequestException extends Exception { + + public int sc; + + public HoloInsightRequestException(String message) { + super(message); + } + + public HoloInsightRequestException(String message, int sc) { + super(message); + this.sc = sc; + } + +} diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/MeasureStatistician.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/MeasureStatistician.java new file mode 100644 index 000000000..76d9a0401 --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/MeasureStatistician.java @@ -0,0 +1,266 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.web.measure; + +import io.holoinsight.server.common.JsonResult; +import io.holoinsight.server.common.service.Measurable; +import io.holoinsight.server.home.biz.access.AccessConfigService; +import io.holoinsight.server.home.biz.access.model.MonitorAccessConfig; +import io.holoinsight.server.home.biz.access.model.MonitorTokenData; +import io.holoinsight.server.home.common.util.MonitorException; +import io.holoinsight.server.home.common.util.scope.IdentityType; +import io.holoinsight.server.home.common.util.scope.MonitorUser; +import io.holoinsight.server.home.common.util.scope.RequestContext; +import io.holoinsight.server.home.web.controller.model.open.GrafanaJsonResult; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.Scheduler; +import org.quartz.TriggerBuilder; +import org.quartz.impl.StdSchedulerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import static io.holoinsight.server.home.alert.service.task.AlertTaskScheduler.getScheduleProperties; + +/** + * @author masaimu + * @version 2023-03-03 21:28:00 + */ +@Slf4j +@Service +public class MeasureStatistician { + + @Autowired + private AccessConfigService accessConfigService; + + private Map statisticsDataMap = new ConcurrentHashMap(); + + public ApikeyAuthority queryResourceTokenByToken(String accessKey) { + if (StringUtils.isEmpty(accessKey)) { + return null; + } + Map apikeyMap = + this.accessConfigService.getAccessConfigDOMap(); + MonitorAccessConfig monitorAccessConfig = apikeyMap.get(accessKey); + if (monitorAccessConfig == null) { + return null; + } + return ApikeyAuthority.build(monitorAccessConfig); + } + + public void doStat(MonitorTokenData tokenData, String resourceTenant, + ResourceType resourceType, ActionType actionType, GrafanaJsonResult result) { + if (resourceType == ResourceType.unknown || actionType == ActionType.unknown) { + return; + } + if (tokenData == null) { + MonitorUser mu = RequestContext.getContext().mu; + if (mu.getIdentityType() == null || mu.getIdentityType() == IdentityType.OUTTOKEN) { + return; + } + tokenData = new MonitorTokenData(); + tokenData.setAccessId("front"); + tokenData.setAccessKey("front"); + resourceTenant = mu.getLoginTenant(); + } + innerStat(tokenData, resourceTenant, resourceType, actionType, result.getResult()); + } + + public void doStat(MonitorTokenData tokenData, String resourceTenant, + ResourceType resourceType, ActionType actionType, JsonResult result) { + if (resourceType == ResourceType.unknown || actionType == ActionType.unknown) { + return; + } + if (tokenData == null) { + MonitorUser mu = RequestContext.getContext().mu; + if (mu.getIdentityType() == null || mu.getIdentityType() == IdentityType.OUTTOKEN) { + return; + } + tokenData = new MonitorTokenData(); + tokenData.setAccessId("front"); + tokenData.setAccessKey("front"); + resourceTenant = mu.getLoginTenant(); + } + innerStat(tokenData, resourceTenant, resourceType, actionType, result.getData()); + } + + private void innerStat(MonitorTokenData tokenData, String resourceTenant, + ResourceType resourceType, ActionType actionType, Object data) { + if (data == null) { + return; + } + long size = 0; + if (data instanceof Collection) { + Collection collection = (Collection) data; + for (Object item : collection) { + if (item instanceof Measurable) { + size += ((Measurable) item).measure(); + } else { + size += 1; + } + } + } else if (data instanceof Map) { + Map map = (Map) data; + for (Object item : map.values()) { + if (item instanceof Measurable) { + size += ((Measurable) item).measure(); + } else { + size += 1; + } + } + } else if (data instanceof Measurable) { + size = ((Measurable) data).measure(); + } else { + size = 1; + } + StatisticsData key = StatisticsData.getStatisticsDataKey(resourceType, actionType, + resourceTenant, tokenData.accessId, tokenData.accessKey); + StatisticsData statisticsData = + this.statisticsDataMap.computeIfAbsent(key, k -> new StatisticsData(key)); + statisticsData.add(size); + } + + /** + * Check authority of tenant, resource type, action type + * + * @param tokenData + * @param resourceTenant + * @param resourceType + * @param actionType + */ + public void checkAuth(MonitorTokenData tokenData, String resourceTenant, + ResourceType resourceType, ActionType actionType) { + if (tokenData == null) { + return; + } + ApikeyAuthority apikeyAuthority = queryResourceTokenByToken(tokenData.accessKey); + + if (apikeyAuthority == null) { + throw new MonitorException( + String.format("Can not find token [%s] authority.", tokenData.accessKey)); + } + + apikeyAuthority.checkResourceType(resourceType, tokenData); + apikeyAuthority.checkActionType(actionType, tokenData); + + if (StringUtils.isNotEmpty(resourceTenant)) { + apikeyAuthority.checkTenant(resourceTenant, tokenData); + } + } + + public static class StatisticsData { + ResourceType resourceType; + ActionType actionType; + String tenant; + String accessId; + String accessKey; + + AtomicLong counter = new AtomicLong(0); + + public StatisticsData(ResourceType resourceType, ActionType actionType, String tenant, + String accessId, String accessKey) { + this.resourceType = resourceType; + this.actionType = actionType; + this.tenant = tenant; + this.accessId = accessId; + this.accessKey = accessKey; + } + + public StatisticsData(StatisticsData key) { + if (key != null) { + this.resourceType = key.resourceType; + this.actionType = key.actionType; + this.tenant = key.tenant; + this.accessId = key.accessId; + this.accessKey = key.accessKey; + } + } + + static StatisticsData getStatisticsDataKey(ResourceType resourceType, ActionType actionType, + String tenant, String accessId, String accessKey) { + return new StatisticsData(resourceType, actionType, tenant, accessId, accessKey); + } + + public long add(long size) { + return counter.addAndGet(size); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + StatisticsData that = (StatisticsData) o; + return resourceType == that.resourceType && actionType == that.actionType + && Objects.equals(tenant, that.tenant) && Objects.equals(accessId, that.accessId) + && Objects.equals(accessKey, that.accessKey); + } + + @Override + public int hashCode() { + return Objects.hash(resourceType, actionType, tenant, accessId, accessKey); + } + } + + + public void start() { + try { + StdSchedulerFactory stdSchedulerFactory = + new StdSchedulerFactory(getScheduleProperties("StatisticsPrint")); + Scheduler scheduler = stdSchedulerFactory.getScheduler(); + + // 创建需要执行的任务 + String jobName = "apikey-stat-job"; + JobDetail jobDetail = + JobBuilder.newJob(StatisticsPrinter.class).withIdentity(jobName).build(); + jobDetail.getJobDataMap().put("statisticsDataMap", this.statisticsDataMap); + // 创建触发器,指定任务执行时间 + CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("PerMinTrigger") + .withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?")).build(); + + scheduler.scheduleJob(jobDetail, cronTrigger); + scheduler.start(); + log.info("[apikey-stat-job] start! "); + } catch (Exception e) { + log.error( + "[HoloinsightHomeInternalException][MeasureStatistician] fail to schedule stat task.", e); + } + } + + public static class StatisticsPrinter implements Job { + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + log.info("measure statistics print once."); + Map statisticsDataMap = + (Map) context.getJobDetail().getJobDataMap() + .get("statisticsDataMap"); + if (CollectionUtils.isEmpty(statisticsDataMap)) { + log.info("statistics data map is empty"); + return; + } + for (StatisticsData statisticsData : statisticsDataMap.values()) { + log.info(String.join("|", statisticsData.accessId, statisticsData.accessKey, + statisticsData.tenant, statisticsData.resourceType.code, + statisticsData.resourceType.type, statisticsData.actionType.name(), + String.valueOf(statisticsData.counter.getAndSet(0)))); + } + } + } +} diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ResourceType.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ResourceType.java new file mode 100644 index 000000000..9009c30e7 --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/measure/ResourceType.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.web.measure; + +/** + * @author masaimu + * @version 2023-03-01 22:22:00 + */ +public enum ResourceType { + log("log", "LOG"), // + metric("metric", "METRIC"), // + metric_tag("metric_tag", "METRIC"), // + tag("tag", "METRIC"), // + trace("trace", "TRACE"), // + alert_config("alert_config", "CONFIG"), // + agent_config("agent_config", "CONFIG"), // + unknown("unknown", "UNKNOWN"),; + + String code; + String type; + + ResourceType(String code, String type) { + this.code = code; + this.type = type; + } +}