前言

前一段时间使用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/

https://raymondhlee.wordpress.com/2016/10/03/monitoring-spring-boot-applications-with-prometheus-part-2/

Grafana+Prometheus系统监控之SpringBoot的更多相关文章

  1. Grafana+Prometheus系统监控之webhook

    概述 Webhook是一个API概念,并且变得越来越流行.我们能用事件描述的事物越多,webhook的作用范围也就越大.Webhook作为一个轻量的事件处理应用,正变得越来越有用. 准确的说webho ...

  2. Grafana Prometheus系统监控Redis服务

    Grafana Prometheus系统监控Redis服务 一.Grafana Prometheus系统监控Redis服务 1.1流程 1.2安装redis_exporter 1.3配置prometh ...

  3. Grafana+Prometheus系统监控之MySql

    架构 grafana和prometheus之前安装配置过,见:Grafana+Prometheus打造全方位立体监控系统 MySql安装 MySql的地位和重要性就不言而喻了,作为开源产品深受广大中小 ...

  4. Grafana+Prometheus系统监控之Redis

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...

  5. 手动部署 Docker+Grafana+Prometheus系统监控之Redis

    监控规划图 使用Docker 创建两台Redis docker run -d --name redis1 redis docker run -d --name redis2 redis 查看redis ...

  6. Grafana+Prometheus系统监控之钉钉报警功能

    介绍 钉钉,阿里巴巴出品,专为中国企业打造的免费智能移动办公平台,含PC版,Web版和手机版.智能办公电话,消息已读未读,DING消息任务管理,让沟通更高效:移动办公考勤,签到,审批,企业邮箱,企业网 ...

  7. Prometheus 系统监控方案 一

    最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错.而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下. Prometheus 是什 ...

  8. Grafana+Prometheus+node_exporter监控,Grafana无法显示数据的问题

    环境搭建: 被测linux机器上部署了Grafana,Prometheus,node_exporter,并成功启动了它们. Grafana中已经创建了Prometheus数据源,并测试通过,并且导入了 ...

  9. Prometheus 系统监控方案 二 安装与配置

    下载Prometheus 下载最新安装包,本文说的都是在Linux x64下面内容,其它平台没尝试过,请选择合适的下载. Prometheus 主程序,主要是负责存储.抓取.聚合.查询方面. Aler ...

随机推荐

  1. Linux系列教程(一)——Linux系统简介

    本系列教程将完整的讲解整个Linux相关的知识,这是楼主学完之后重新对Linux知识体系的整理.从最基础的知识开始,对于一个完全不懂Linux系统的人,相信在看完整个系列教程之后,都能对Linux有一 ...

  2. spring中WebApplicationContextUtils类说明

    WebApplicationContextUtils是一个抽象类,其提供了一个很便利的方法来获取spring应用的上下文即WebApplicationContext. 其中的静态方法getWebApp ...

  3. vue.js实例对象+组件树

    vue的实例对象 首先用js的new关键字实例化一个vue el: vue组件或对象装载在页面的位置,可通过id或class或标签名 template: 装载的内容.HTML代码/包含指令或者其他组件 ...

  4. property--staticmethod--classmethod

    特性(property): 作为装饰器使用,调用方式从最初的方法调用改变为属性调用 类方法(classmethod):和类进行交互,单不和实例进行交互 在函数中可以不用上传参数 静态方法(static ...

  5. Jvm加载jar包的顺序

    使用-XX:+TraceClassPaths或者在服务器上执行jinfo时,都能得到classpath包含的jar包,例如: java.class.path = local/aaa/lib/sprin ...

  6. Cosmos OpenSSD--greedy_ftl1.2.0(一)

    从主函数跳到ReqHandler,在ReqHandler内先初始化SSD--InitNandReset,然后建立映射表InitFtlMapTable void InitNandReset() { // ...

  7. 使用bitset实现毫秒级查询(二)

    在上一篇中我们了解了bitset索引的基本用法,本篇开始学习bitset索引更新及一些复杂查询. 1.bitset索引更新   因为我们的数据是在系统启动时全部加载进内存,所以当数据库数据发生变化时要 ...

  8. session和cookie作用原理,区别

    Cookie概念 在浏览某些 网站 时,这些网站会把 一些数据存在 客户端 , 用于使用网站 等跟踪用户,实现用户自定义 功能. 是否设置过期时间: 如果不设置 过期时间,则表示这个 Cookie生命 ...

  9. Linux系统fdisk分区

    以下操作全部基于win7 64位系统上的Linux虚拟机(CentOS6.6). 当Linux虚拟机的硬盘空间不够用时,可以手动添加硬盘块,流程如下: 右键虚拟机,点击“Add”按钮: 选择“Hard ...

  10. px em rem的详解与区别

    在前端项目开发中,px,em,以及rem都是页面布局常用的单位,虽然它们是长度单位,但是所含的意义不一样.通过复习和查阅,总结了以下知识. px像素(Pixel) 定义:相对长度单位.像素px是相对于 ...