首页 > 其他分享 >springboot接入prometheus监控

springboot接入prometheus监控

时间:2024-09-05 15:47:35浏览次数:11  
标签:springboot appName 接入 state private url prometheus public String

pom引入


org.springframework.boot
spring-boot-starter-actuator


io.micrometer
micrometer-core


io.micrometer
micrometer-registry-prometheus
1.5.6

yaml配置
management.endpoints.web.exposure.include=*
management.endpoints.web.base-path=/actuator
management.metrics.export.prometheus.enabled=true
management.metrics.tags.application: ${spring.application.name}

management:
endpoints:
web:
base-path: /actuator
exposure:
include: '*'
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}

点击查看代码

/**
 * 描述 工作JobMetrics
 * */
@Component
@Getter
@Slf4j
public class JobMetrics implements MeterBinder {

    private MeterRegistry meterRegistry;



    @Override
    public void bindTo(MeterRegistry meterRegistry) {

        this.meterRegistry = meterRegistry;
    }

    /**
     * 采集Prometheus指标信息的次数counter
     *
     */
    public void counter(String metricName, String[] tags) {

        try {
            meterRegistry.counter(metricName, tags).increment();
        } catch (Exception e) {
            //log.error("采集summary出现异常: {}", e.getMessage());
        }
    }

    /**
     * 采集Prometheus指标信息的次数timer
     *
     */
    public void timer(String metricName, long val, String[] tags) {

        try {

            Timer.builder(metricName)
                    .tags(tags)
                    .publishPercentiles(0.5, 0.95, 0.99) // 发布分位数
                    .description("ck summery")
                    .register(meterRegistry)
                    .record(val, TimeUnit.MILLISECONDS);

        } catch (Exception e) {
            //log.error("采集summary出现异常: {}", e.getMessage());
        }
    }


}
点击查看代码


@Slf4j
@RefreshScope
@Component
public class CheckResponseFilter implements GlobalFilter, Ordered {

    private static final String APP_INVOKE_COST_TIME = "app_invoke_cost_time";

    private static final String APP_INVOKE_URL_ERROR = "app_invoke_url_error";

    @Resource
    private JobMetrics jobMetrics;

    @Value("${country_code}")
    private String countryCode;

    @Value("${spring.profiles.active:test}")
    private String env;

    @Value("${shared.stateWhiteList:255}")
    private String stateWhiteList;

    private static final DataBufferFactory bufferFactory = new DefaultDataBufferFactory();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long start = System.currentTimeMillis();
        URI uri = exchange.getRequest().getURI();
        //请求路径
        String url = uri.getPath();
        String appName = url.split("/")[2];

        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory wrappedBufferFactory = originalResponse.bufferFactory();

        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            private final ArrayList<DataBuffer> bufferList = new ArrayList<DataBuffer>();

            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);

                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {

                        // 合并多个流集合,解决返回体分段传输
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer buff = dataBufferFactory.join(dataBuffers);
                        byte[] content = new byte[buff.readableByteCount()];
                        buff.read(content);
                        DataBufferUtils.release(buff);//释放掉内存

                        //排除Excel导出,不是application/json不打印。若请求是上传图片则在最上面判断。
                        MediaType contentType = originalResponse.getHeaders().getContentType();
                        if (!MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
                            return bufferFactory.wrap(content);
                        }

                        // 构建返回
                        String joinData = new String(content);

                        //统计错误
                        countResponseError(appName, url, joinData);

                        return bufferFactory.wrap(content);
                    }));
                } else {
                    log.error("gateway_status_code_error", getStatusCode());
                }
                return super.writeWith(body);
            }

        };

        return chain.filter(exchange.mutate().response(decoratedResponse).build())
                .then(Mono.fromRunnable(() -> {
                    long duration = System.currentTimeMillis() - start;
                    //统计耗时
                    summeryCostTime(appName, url, duration);
                }));

    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


    private void summeryCostTime(String appName, String url, long timeCost) {

        String[] tagArr = new String[]{
                "env", env,
                "countryCode", countryCode,
                "appName", appName,
                "url", url
        };
        // 执行耗时
        jobMetrics.timer(APP_INVOKE_COST_TIME, timeCost, tagArr);
        //log
        //log.error(APP_INVOKE_COST_TIME + "  timeCost:" + timeCost);

    }


    private void countResponseError(String appName, String url, String responseBody) {

        if (responseBody != null && !responseBody.isEmpty()) {
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            // 尝试解析JSON响应体
            String state = jsonObject.getString("state");
            //统计失败
            //state 返回代码,200==成功,255==失败,267==需要特殊处理,400==请求无效,403==禁止访问,404==请求地址不存在,503==服务器异常
            if (StringUtils.isNotBlank(state) && !StringUtils.equals(state, "200")) {

                String[] tagArr = new String[]{
                        "env", env,
                        "countryCode", countryCode,
                        "appName", appName,
                        "url", url,
                        "state", state

                };
                //如果不在白名单内
                if (!StringUtils.containsIgnoreCase(stateWhiteList,state)) {
                    //错误统计
                    jobMetrics.counter(APP_INVOKE_URL_ERROR, tagArr);
                }
                //log
                log.error(APP_INVOKE_URL_ERROR + "  url:" + url + "   body:" + responseBody);

            }

        }

    }

}


标签:springboot,appName,接入,state,private,url,prometheus,public,String
From: https://www.cnblogs.com/kunchengs/p/18398603

相关文章

  • prometheus告警配置
    这是prometheus告警规则配置,实际告警要结合alertmanager使用,请看下一篇文章。rulehttps://samber.github.io/awesome-prometheus-alerts/rulesjvm案例wgethttps://raw.githubusercontent.com/samber/awesome-prometheus-alerts/master/dist/rules/jvm/jvm-exporter.yml文件......
  • 基于SpringBoot+Vue的高校宣讲会管理系统(带1w+文档)
    基于SpringBoot+Vue的高校宣讲会管理系统(带1w+文档)基于SpringBoot+Vue的高校宣讲会管理系统(带1w+文档)高校宣讲会管理系统可以对高校宣讲会管理系统信息进行集中管理,可以真正避免传统管理的缺陷。高校宣讲会管理系统是一款运用软件开发技术设计实现的应用系统,在......
  • prometheus学习笔记之集群外服务发现
    一、部署二进制prometheus略,参考之前文档或自行百度二、创建prometheus获取api-server的token1.获取tokenkubectlgetsa-nmonitoringmonitor#上一篇给prometheus创建的sakubectlgetsa-nmonitoringmonitor-oyaml#每个sa默认会创建一个secretkubectlgetsecre......
  • 基于SpringBoot的流浪猫狗管理系统的设计与实现-毕业设计源码05049
    目录摘要1绪论1.1选题背景与意义1.2国内外目前现状2 系统分析2.1系统需求分析2.1.1系统功能性需求分析2.1.2系统非功能性需求分析2.1.3系统用例分析2.2可行性分析3系统设计3.1环境配置及关键技术3.1.1环境配置1.运行环境3.1.2关键技术......
  • Springboot计算机毕业设计图书馆座位预约管理平台(程序+源码+数据库+调试部署+开发环
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,阅览室,阅览室类型,我的申请,教师预约,阅读区座位,座位申请,座位预约,学院通知,数据统计,预约时长排名开题报告内容一、立题依据1.国内外研究进展或......
  • Springboot计算机毕业设计图书馆自习室管理系统的设计与实现(程序+源码+数据库+调试部
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,图书类型,图书信息,图书借阅,图书归还,座位信息,座位预约,座位续约,座位退座,续座退座,座位入座开题报告内容一、研究背景与意义随着高等教育规模的不断扩......
  • Springboot计算机毕业设计图书馆在线预约(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表读者,图书类别,图书信息,图书预约,取消预约,超时提醒开题报告内容一、立题依据1.国内外研究进展或选题背景在我国,随着高等教育普及化进程的加速,图书馆作为知......
  • Springboot计算机毕业设计图书馆管理系统o105u(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,图书馆信息,图书分类,图书信息,图书借阅,图书归还,预约信息开题报告内容一、选题依据1.国内外研究现状图书管理系统的应用和技术发展在发达国家已经相对......
  • 基于SpringBoot的高校宿舍管理系统+LW参考示例
    系列文章目录1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例4.基于SSM的高校实验室管理系统+LW参考示例5.基于SpringBoot的二手数码回收系统+原生微信小......
  • 基于SpringBoot的电影院订票系统+LW示例参考
    系列文章目录1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例4.基于SSM的高校实验室管理系统+LW参考示例5.基于SpringBoot的二手数码回收系统+原生微信小......