Grafana+Prometheus系统监控之SpringBoot
前言
前一段时间使用SpringBoot创建了一个webhook项目,由于近期项目中也使用了不少SpringBoot相关的项目,趁着周末,配置一下使用prometheus监控微服务Springboot。
项目配置
引入坐标
<!-- Exposition spring_boot -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_spring_boot</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Hotspot JVM metrics -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Exposition servlet -->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>0.1.0</version>
</dependency>
配置Application
@SpringBootApplication
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args);
logger.info("项目启动 ");
}
}
配置MonitoringConfig
@Configuration
class MonitoringConfig {
@Bean
SpringBootMetricsCollector springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics);
springBootMetricsCollector.register();
return springBootMetricsCollector;
}
@Bean
ServletRegistrationBean servletRegistrationBean() {
DefaultExports.initialize();
return new ServletRegistrationBean(new MetricsServlet(), "/prometheus");
}
}
配置Interceptor
RequestCounterInterceptor(计数):
public class RequestCounterInterceptor extends HandlerInterceptorAdapter {
// @formatter:off
// Note (1)
private static final Counter requestTotal = Counter.build()
.name("http_requests_total")
.labelNames("method", "handler", "status")
.help("Http Request Total").register();
// @formatter:on
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e)
throws Exception {
// Update counters
String handlerLabel = handler.toString();
// get short form of handler method name
if (handler instanceof HandlerMethod) {
Method method = ((HandlerMethod) handler).getMethod();
handlerLabel = method.getDeclaringClass().getSimpleName() + "." + method.getName();
}
// Note (2)
requestTotal.labels(request.getMethod(), handlerLabel, Integer.toString(response.getStatus())).inc();
}
}
RequestTimingInterceptor(统计请求时间):
package com.itstyle.webhook.interceptor;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.prometheus.client.Summary;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class RequestTimingInterceptor extends HandlerInterceptorAdapter {
private static final String REQ_PARAM_TIMING = "timing";
// @formatter:off
// Note (1)
private static final Summary responseTimeInMs = Summary
.build()
.name("http_response_time_milliseconds")
.labelNames("method", "handler", "status")
.help("Request completed time in milliseconds")
.register();
// @formatter:on
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Note (2)
request.setAttribute(REQ_PARAM_TIMING, System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
Long timingAttr = (Long) request.getAttribute(REQ_PARAM_TIMING);
long completedTime = System.currentTimeMillis() - timingAttr;
String handlerLabel = handler.toString();
// get short form of handler method name
if (handler instanceof HandlerMethod) {
Method method = ((HandlerMethod) handler).getMethod();
handlerLabel = method.getDeclaringClass().getSimpleName() + "." + method.getName();
}
// Note (3)
responseTimeInMs.labels(request.getMethod(), handlerLabel,
Integer.toString(response.getStatus())).observe(completedTime);
}
}
配置Controller
主要是为了测试拦截器的效果
@RestController
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping("/endpointA")
public void handlerA() throws InterruptedException {
logger.info("/endpointA");
Thread.sleep(RandomUtils.nextLong(0, 100));
}
@RequestMapping("/endpointB")
public void handlerB() throws InterruptedException {
logger.info("/endpointB");
Thread.sleep(RandomUtils.nextLong(0, 100));
}
}
以上都配置完成后启动项目即可。
配置Prometheus
vi prometheus.yml
- job_name: webhook
metrics_path: '/prometheus'
static_configs:
- targets: ['localhost:8080']
labels:
instance: webhook
保存后重新启动Prometheus即可。
访问http://ip/targets 服务State 为up说明配置成功,查阅很多教程都说需要配置 spring.metrics.servo.enabled=false,否则在prometheus的控制台的targets页签里,会一直显示此endpoint为down状态,然貌似并没有配置也是ok的。

访问http://ip/graph 测试一下效果

配置Grafana
如图所示:

参考链接
https://blog.52itstyle.com/archives/1984/
https://blog.52itstyle.com/archives/2084/
https://raymondhlee.wordpress.com/2016/09/24/monitoring-spring-boot-applications-with-prometheus/
Grafana+Prometheus系统监控之SpringBoot的更多相关文章
- Grafana+Prometheus系统监控之webhook
概述 Webhook是一个API概念,并且变得越来越流行.我们能用事件描述的事物越多,webhook的作用范围也就越大.Webhook作为一个轻量的事件处理应用,正变得越来越有用. 准确的说webho ...
- Grafana Prometheus系统监控Redis服务
Grafana Prometheus系统监控Redis服务 一.Grafana Prometheus系统监控Redis服务 1.1流程 1.2安装redis_exporter 1.3配置prometh ...
- Grafana+Prometheus系统监控之MySql
架构 grafana和prometheus之前安装配置过,见:Grafana+Prometheus打造全方位立体监控系统 MySql安装 MySql的地位和重要性就不言而喻了,作为开源产品深受广大中小 ...
- Grafana+Prometheus系统监控之Redis
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...
- 手动部署 Docker+Grafana+Prometheus系统监控之Redis
监控规划图 使用Docker 创建两台Redis docker run -d --name redis1 redis docker run -d --name redis2 redis 查看redis ...
- Grafana+Prometheus系统监控之钉钉报警功能
介绍 钉钉,阿里巴巴出品,专为中国企业打造的免费智能移动办公平台,含PC版,Web版和手机版.智能办公电话,消息已读未读,DING消息任务管理,让沟通更高效:移动办公考勤,签到,审批,企业邮箱,企业网 ...
- Prometheus 系统监控方案 一
最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错.而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下. Prometheus 是什 ...
- Grafana+Prometheus+node_exporter监控,Grafana无法显示数据的问题
环境搭建: 被测linux机器上部署了Grafana,Prometheus,node_exporter,并成功启动了它们. Grafana中已经创建了Prometheus数据源,并测试通过,并且导入了 ...
- Prometheus 系统监控方案 二 安装与配置
下载Prometheus 下载最新安装包,本文说的都是在Linux x64下面内容,其它平台没尝试过,请选择合适的下载. Prometheus 主程序,主要是负责存储.抓取.聚合.查询方面. Aler ...
随机推荐
- Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
前言 我们知道HDFS集群中,所有的文件都是存放在DN的数据块中的.那我们该怎么去查看数据块的相关属性的呢?这就是我今天分享的内容了 一.HDFS中数据块概述 1.1.HDFS集群中数据块存放位置 我 ...
- win10 uwp 截图 获取屏幕显示界面保存图片
本文主要讲如何保存我们的屏幕显示的,保存为图片,也就是截图,截我们应用显示的. UWP有一个功能,可以截图,RenderTargetBitmap 我们首先写一个Grid,我们需要给他名字,我这里给他S ...
- 65、django之模型层(model)--添加、单表查询、修改基础
上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...
- 数据库中WITH CHECK OPTION的用法
WITH CHECK OPTION:透过视图进行增删改操作时,不得破坏视图定义中的谓词条件(即子查询中的条件表达式) 例如: create view TestView as selec ...
- Vue源码后记-其余内置指令(2)
-- 指令这个讲起来还有点复杂,先把html弄上来: <body> <div id='app'> <div v-if="vIfIter" v-bind ...
- J - Scarily interesting! URAL - 2021
This year at Monsters University it is decided to arrange Scare Games. At the Games all campus gathe ...
- JavaScript sort() 方法详解
定义和用法 sort() 方法用于对数组的元素进行排序. 语法 arrayObject.sort(sortby) 参数 描述 sortby 可选.规定排序顺序.必须是函数. 返回值 对数组的引用.请注 ...
- shell命令输入输出重定向
Linux命令的执行过程 首先是输入:stdin输入可以从键盘,也可以从文件得到 命令执行完成:把成功结果输出到屏幕,stout默认是屏幕 命令执行有错误:把错误也输出到屏幕上面,stderr默认也是 ...
- vue初级学习--路由router的编写(resolve的使用)
一.导语 最近在用vue仿写淘宝的商品详情页面以及加入购物车页面,若是成功了,分享给大家~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 二.正文 我先用控制台创建了vue项目demo(如 ...
- 一些神奇的JS功效
1: 沉睡排序 var numbers=[1,2,3,4,5,5,99,4,20,11,200]; numbers.forEach((num)=>{ setTimeout(()=>{ co ...