From 4c745437c526f88916e224d92e57e2e6c3d05598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E7=AB=8B?= <413940119@qq.com> Date: Wed, 20 Jan 2021 18:20:37 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90monitor=E3=80=91=E6=96=B0=E5=A2=9Eprom?= =?UTF-8?q?etheus=E7=9B=91=E6=8E=A7tomcat=E3=80=81jvm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 17 ++ .../cn/stylefeng/guns/GunsApplication.java | 10 +- .../guns/core/consts/ProjectConstants.java | 23 +++ .../system/controller/MonitorController.java | 77 +++++++- .../modular/system/model/PromDataInfo.java | 28 +++ .../modular/system/model/PromMetricInfo.java | 29 +++ .../system/model/PromResponceInfo.java | 24 +++ .../modular/system/model/PromResultInfo.java | 21 ++ .../modular/system/service/MetricService.java | 25 +++ .../service/impl/MetricServiceImpl.java | 58 ++++++ src/main/resources/application.yml | 18 ++ .../webapp/pages/modular/frame/jvmInfo.html | 60 ++++++ .../pages/modular/frame/tomcatInfo.html | 187 ++++++++++++++++++ 13 files changed, 574 insertions(+), 3 deletions(-) create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/model/PromDataInfo.java create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/model/PromMetricInfo.java create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/model/PromResponceInfo.java create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/model/PromResultInfo.java create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/service/MetricService.java create mode 100644 src/main/java/cn/stylefeng/guns/modular/system/service/impl/MetricServiceImpl.java create mode 100644 src/main/webapp/pages/modular/frame/jvmInfo.html create mode 100644 src/main/webapp/pages/modular/frame/tomcatInfo.html diff --git a/pom.xml b/pom.xml index 42d961f2..91779bfa 100644 --- a/pom.xml +++ b/pom.xml @@ -146,6 +146,23 @@ druid-spring-boot-starter 1.1.10 + + + + org.springframework.boot + spring-boot-starter-actuator + + + + io.micrometer + micrometer-registry-prometheus + + + + org.apache.commons + commons-lang3 + 3.11 + diff --git a/src/main/java/cn/stylefeng/guns/GunsApplication.java b/src/main/java/cn/stylefeng/guns/GunsApplication.java index b8391d24..d79fc3b5 100644 --- a/src/main/java/cn/stylefeng/guns/GunsApplication.java +++ b/src/main/java/cn/stylefeng/guns/GunsApplication.java @@ -1,8 +1,12 @@ package cn.stylefeng.guns; +import io.micrometer.core.instrument.MeterRegistry; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; /** * SpringBoot方式启动类 @@ -18,6 +22,10 @@ public class GunsApplication { SpringApplication.run(GunsApplication.class, args); log.info(GunsApplication.class.getSimpleName() + " is success!"); } - + @Bean + MeterRegistryCustomizer configurer( + @Value("${spring.application.name}") String applicationName) { + return (registry) -> registry.config().commonTags("application", applicationName); + } } diff --git a/src/main/java/cn/stylefeng/guns/core/consts/ProjectConstants.java b/src/main/java/cn/stylefeng/guns/core/consts/ProjectConstants.java index 00556c9a..9fdea577 100644 --- a/src/main/java/cn/stylefeng/guns/core/consts/ProjectConstants.java +++ b/src/main/java/cn/stylefeng/guns/core/consts/ProjectConstants.java @@ -35,4 +35,27 @@ public interface ProjectConstants { */ Integer SUPER_ADMIN_INIT_LISTENER_SORT = 400; + /** + * prometheus查询命令 + */ + String PROMETHEUS_QUERY = "query"; + + /** + * prometheus查询区间向量命令 + */ + String PROMETHEUS_QUERY_RANGE = "query_range"; + /** + * prometheus查询开始时间 + */ + String PROMETHEUS_START = "start"; + + /** + * prometheus查询结束时间 + */ + String PROMETHEUS_END = "end"; + + /** + * prometheus查询步长 + */ + String PROMETHEUS_STEP = "step"; } \ No newline at end of file diff --git a/src/main/java/cn/stylefeng/guns/modular/system/controller/MonitorController.java b/src/main/java/cn/stylefeng/guns/modular/system/controller/MonitorController.java index 83e6c037..21ca605e 100644 --- a/src/main/java/cn/stylefeng/guns/modular/system/controller/MonitorController.java +++ b/src/main/java/cn/stylefeng/guns/modular/system/controller/MonitorController.java @@ -1,13 +1,24 @@ package cn.stylefeng.guns.modular.system.controller; +import cn.stylefeng.guns.core.consts.ProjectConstants; +import cn.stylefeng.guns.modular.system.model.PromResultInfo; +import cn.stylefeng.guns.modular.system.service.MetricService; import cn.stylefeng.guns.modular.system.warpper.SystemHardwareWarpper; import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource; import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource; +import com.alibaba.fastjson.JSON; + import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import java.util.List; +import java.util.Objects; + /** * 项目监控 * @@ -24,13 +35,25 @@ public class MonitorController { @Value("${server.port}") private String port; + @Value("${spring.application.name}") + private String name; + + @Value("${prometheus.url}") + private String prometheusUrl; + + @Value("${prometheus.instance}") + private String prometheusInstance; + + @Autowired + private MetricService service; + /** * 系统硬件信息页面 * * @author fengshuonan * @Date 2018/12/24 22:43 */ - @GetResource(name = "服务器监控", path = "/monitor/systemInfo", requiredPermission = false) + @GetResource(name = "服务器监控", path = "/monitor/systemInfo") public String systemInfo(Model model) { SystemHardwareWarpper systemHardwareWarpper = new SystemHardwareWarpper(); systemHardwareWarpper.copyTo(); @@ -44,10 +67,60 @@ public class MonitorController { * @author chenli * @Date 2021/1/4 16:32 */ - @GetResource(name = "SQL监控", path = "/monitor/druid", requiredPermission = false,requiredLogin = false) + @GetResource(name = "SQL监控", path = "/monitor/druid") public String duridInfo(Model model){ model.addAttribute("port",port); return PREFIX+"/druid.html"; } + /** + * tomcat监控页面 + * + * @author chenli + * @Date 2021/1/4 16:32 + */ + @GetResource(name = "tomcat监控", path = "/monitor/tomcatInfo") + public String tomcatInfo(Model model){ + getMetricInfos("tomcat_",model); + return PREFIX+"/tomcatInfo.html"; + } + + /** + * jvm监控 + * + * @author chenli + * @Date 2021/1/4 16:32 + */ + @GetResource(name = "jvm监控", path = "/monitor/jvmInfo") + public String jvmInfo(Model model){ + getMetricInfos("jvm_",model); + return PREFIX+"/jvmInfo.html"; + } + + /** + * 分别输出监控名称以及对应的值 + * + * @author chenli + * @Date 2021/1/4 16:32 + */ + private void getMetricInfos(String metric,Model model){ + String promQL = ""; + if(!StringUtils.isEmpty(prometheusInstance)){ + promQL = "{application=\""+name+"\",instance=\""+prometheusInstance+"\"}"; + } else { + promQL = "{application=\""+name+"\"}"; + } + if(!StringUtils.isEmpty(prometheusUrl)){ + List promResultInfos = service.getMetricInfo(prometheusUrl.concat(ProjectConstants.PROMETHEUS_QUERY_RANGE), promQL); + for(PromResultInfo promResultInfo : promResultInfos){ + String metricName = promResultInfo.getMetric().get__name__(); + if(!Objects.isNull(metricName)){ + if(metricName.contains(metric)){ + String metricValues = StringEscapeUtils.unescapeJava(JSON.toJSONString(promResultInfo.getValues())); + model.addAttribute(metricName, metricValues.replace("\"","")); + } + } + } + } + } } diff --git a/src/main/java/cn/stylefeng/guns/modular/system/model/PromDataInfo.java b/src/main/java/cn/stylefeng/guns/modular/system/model/PromDataInfo.java new file mode 100644 index 00000000..fcae2330 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/model/PromDataInfo.java @@ -0,0 +1,28 @@ +package cn.stylefeng.guns.modular.system.model; + +import lombok.Data; + +import java.util.List; + +/** + * prometheus查询返回结果信息 + * + * @author chenli + * @date 2021/1/10 19:10 + */ +@Data +public class PromDataInfo { + /** + * prometheus结果类型 + * vector--瞬时向量 + * matrix--区间向量 + * scalar--标量 + * string--字符串 + */ + private String resultType; + + /** + * prometheus指标属性和值 + */ + private List result; +} \ No newline at end of file diff --git a/src/main/java/cn/stylefeng/guns/modular/system/model/PromMetricInfo.java b/src/main/java/cn/stylefeng/guns/modular/system/model/PromMetricInfo.java new file mode 100644 index 00000000..c4a90da2 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/model/PromMetricInfo.java @@ -0,0 +1,29 @@ +package cn.stylefeng.guns.modular.system.model; + +import lombok.Data; + +/** + * prometheus返回监控指标信息 + * + * @author chenli + * @date 2021/1/10 18:53 + */ +@Data +public class PromMetricInfo { + + /** + * prometheus监控指标名称 + */ + private String __name__; + + /** + * prometheus实例名称 + */ + private String instance; + + /** + * prometheus任务名称 + */ + private String job; +} + diff --git a/src/main/java/cn/stylefeng/guns/modular/system/model/PromResponceInfo.java b/src/main/java/cn/stylefeng/guns/modular/system/model/PromResponceInfo.java new file mode 100644 index 00000000..de62e9ca --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/model/PromResponceInfo.java @@ -0,0 +1,24 @@ +package cn.stylefeng.guns.modular.system.model; + +import lombok.Data; + +/** + * prometheus http响应信息 + * + * @author chenli + * @date 2021/1/10 19:00 + */ +@Data +public class PromResponceInfo { + + /** + * 状态 + * 成功-- success + */ + private String status; + + /** + * prometheus指标属性和值 + */ + private PromDataInfo data; +} \ No newline at end of file diff --git a/src/main/java/cn/stylefeng/guns/modular/system/model/PromResultInfo.java b/src/main/java/cn/stylefeng/guns/modular/system/model/PromResultInfo.java new file mode 100644 index 00000000..eaffc4d0 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/model/PromResultInfo.java @@ -0,0 +1,21 @@ +package cn.stylefeng.guns.modular.system.model; + +import lombok.Data; + +/** + * @author chenli + * @date 2021/1/10 18:58 + */ +@Data +public class PromResultInfo { + /** + * prometheus指标属性 + */ + private PromMetricInfo metric; + + /** + * prometheus指标值 + */ + private String[] values; + +} diff --git a/src/main/java/cn/stylefeng/guns/modular/system/service/MetricService.java b/src/main/java/cn/stylefeng/guns/modular/system/service/MetricService.java new file mode 100644 index 00000000..72dce42b --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/service/MetricService.java @@ -0,0 +1,25 @@ +package cn.stylefeng.guns.modular.system.service; + +import cn.stylefeng.guns.modular.system.model.PromResultInfo; + +import java.util.List; + +/** + * 监控管理prometheus + * + * @author chenli + * @date 2021/1/10 16:09 + */ +public interface MetricService { + + /** + * prometheus采集监控指标 + * + * @param promURL prometheus地址 + * @param promQL prometheus查询表达式 + * @return Map 指标名称与指标数据的集合 + * @author chenli + * @date 2021/1/10 17:37 + */ + List getMetricInfo(String promURL, String promQL); +} diff --git a/src/main/java/cn/stylefeng/guns/modular/system/service/impl/MetricServiceImpl.java b/src/main/java/cn/stylefeng/guns/modular/system/service/impl/MetricServiceImpl.java new file mode 100644 index 00000000..7bdc2d41 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/system/service/impl/MetricServiceImpl.java @@ -0,0 +1,58 @@ +package cn.stylefeng.guns.modular.system.service.impl; + +import cn.hutool.http.HttpUtil; +import cn.stylefeng.guns.core.consts.ProjectConstants; +import cn.stylefeng.guns.core.exception.BusinessException; +import cn.stylefeng.guns.modular.system.model.PromResponceInfo; +import cn.stylefeng.guns.modular.system.model.PromResultInfo; +import cn.stylefeng.guns.modular.system.service.MetricService; +import com.alibaba.excel.util.StringUtils; +import com.alibaba.fastjson.JSON; +import org.springframework.stereotype.Service; + +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 监控管理prometheus + * + * @author chenli + * @date 2021/1/10 16:09 + */ +@Service +public class MetricServiceImpl implements MetricService { + + /** + * prometheus采集监控指标 + * + * @author chenli + * @date 2021/1/10 16:09 + */ + @Override + public List getMetricInfo(String promURL, String promQL) { + Map paramMap = new HashMap<>(); + paramMap.put(ProjectConstants.PROMETHEUS_QUERY, promQL); + Calendar calendar = Calendar.getInstance(); + // 查询5分钟数据 + calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - 5); + // 查询开始时间 + paramMap.put(ProjectConstants.PROMETHEUS_START, (calendar.getTime().getTime())/1000L); + // 查询结束时间 + paramMap.put(ProjectConstants.PROMETHEUS_END, (new Date().getTime())/1000L); + // 查询步长 + paramMap.put(ProjectConstants.PROMETHEUS_STEP,15); + PromResponceInfo responseInfo = JSON.parseObject(HttpUtil.get(promURL, paramMap), PromResponceInfo.class); + if (StringUtils.isEmpty(responseInfo)) { + // prometheus未开启 + return null; + } + if (StringUtils.isEmpty(responseInfo.getStatus()) || !"success".equals(responseInfo.getStatus())) { + // prometheus查询失败 + return null; + } + return responseInfo.getData().getResult(); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d99e8de9..8272dd85 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -42,3 +42,21 @@ mybatis-plus: db-config: id-type: assign_id table-underline: true +# prometheus监控 +management: + endpoints: + web: + exposure: + include: "*" + metrics: + tags: + application: ${spring.application.name} + export: + prometheus: + enabled: true + jmx: + enabled: true +prometheus: + url: http://localhost:9090/api/v1/ + # 非必须配置项 + instance: \ No newline at end of file diff --git a/src/main/webapp/pages/modular/frame/jvmInfo.html b/src/main/webapp/pages/modular/frame/jvmInfo.html new file mode 100644 index 00000000..ccfaa591 --- /dev/null +++ b/src/main/webapp/pages/modular/frame/jvmInfo.html @@ -0,0 +1,60 @@ + + + + + + + ${constants.getSystemName()} + + + + + +
+
+
+
+
+
+
+
+
+
+
+ +@/* 加入contextPath属性和session超时的配置 */ + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/pages/modular/frame/tomcatInfo.html b/src/main/webapp/pages/modular/frame/tomcatInfo.html new file mode 100644 index 00000000..dd92d6c8 --- /dev/null +++ b/src/main/webapp/pages/modular/frame/tomcatInfo.html @@ -0,0 +1,187 @@ + + + + + + + ${constants.getSystemName()} + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + @/* 加入contextPath属性和session超时的配置 */ + + + + + + + + \ No newline at end of file