• Mybatis拦截器自定义prometheus监控指标


    1、定义各个prometheus指标

    public class MybatisMetrics {
    
        private static final String[] labelNames = new String[] { "class", "command", "status" };
    
        public static final Counter QUERY_COUNT = Counter.build()
                .name("mybatis_requests_total").help("total sql command.")
                .labelNames(labelNames).register();
    
        public static final Gauge QUERY_MAX = Gauge.build()
                .name("mybatis_requests_max").help("run sql command latency in seconds.")
                .labelNames(labelNames).register();
    
        public static final Summary QUERY_SUMMARY = Summary.build()
                .name("mybatis_latency_seconds").help("Request latency in seconds.").labelNames(labelNames)
                .register();
    
    }

    2、将指标注册到prometheus收集器之中

    @Component
    public class PrometheusConfigation {
        @Autowired
        private CollectorRegistry collectorRegistry;
    
        @PostConstruct
        public void init() {
            /**
             * 自定义指标
             */
            MybatisMetrics.QUERY_COUNT.register(collectorRegistry);
            MybatisMetrics.QUERY_MAX.register(collectorRegistry);
            MybatisMetrics.QUERY_SUMMARY.register(collectorRegistry);
        }
    }

    3、定义mybatis的拦截器将每次SQL COMMAND信息收集

    @SuppressWarnings({"rawtypes"})
    @Intercepts(
        {
            @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class}),
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
        }
    )
    public class MyBatisInterceptor implements Interceptor {
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            final Object[] args = invocation.getArgs();
            if (args != null && args.length > 0) {
                final MappedStatement mappedStatement = (MappedStatement) args[0];
                if (mappedStatement != null) {
                    final String className = mappedStatement.getId();
                    final String command = mappedStatement.getSqlCommandType().name();
                    String status = "";
                    //以类名和方法名为标签
                    String[] labelValues = new String[3];
                    labelValues[0] = className;
                    labelValues[1] = command;
                    labelValues[2] = status;
                    SimpleTimer startTimer = new SimpleTimer();
                    try {
                        status = MybatisMetricsStatusEnum.success.getCode();
                        return invocation.proceed();
                    } catch (Throwable throwable) {
                        status = MybatisMetricsStatusEnum.fail.getCode();
                        throw throwable;
                    } finally {
                        labelValues[2] = status;
                        MybatisMetrics.QUERY_MAX.labels(labelValues).set(startTimer.elapsedSeconds());
                        MybatisMetrics.QUERY_SUMMARY.labels(labelValues).observe(startTimer.elapsedSeconds());
                        MybatisMetrics.QUERY_COUNT.labels(labelValues).inc();
                    }
                }
            }
            return invocation.proceed();
        }
    
        @Override
        public Object plugin(Object target) {
            if (target instanceof Executor || target instanceof StatementHandler) {
                return Plugin.wrap(target, this);
            }
            return target;
        }
    
        @Override
        public void setProperties(Properties properties) {
        }
    }

    4、注册拦截器到Mybatis之中

    @Configuration
    public class MybatisConfig {
        @Bean
        public ConfigurationCustomizer mybatisConfigurationCustomizer() {
            return configuration -> configuration.addInterceptor(new MyBatisInterceptor());
        }
    }

    5、查看收集到的指标

    # 请求次数和总时长
    # HELP mybatis_latency_seconds Request latency in seconds.
    # TYPE mybatis_latency_seconds summary
    mybatis_latency_seconds_count{class="com.example.one.mapper.SchoolMapper.selectList",command="SELECT",status="fail",} 1.0
    mybatis_latency_seconds_sum{class="com.example.one.mapper.SchoolMapper.selectList",command="SELECT",status="fail",} 0.292885
    mybatis_latency_seconds_count{class="com.example.one.mapper.UserMapper.selectList",command="SELECT",status="success",} 4.0
    mybatis_latency_seconds_sum{class="com.example.one.mapper.UserMapper.selectList",command="SELECT",status="success",} 1.5040959
    # 请求次数
    # HELP mybatis_requests_total total sql command.
    # TYPE mybatis_requests_total counter
    mybatis_requests_total{class="com.example.one.mapper.SchoolMapper.selectList",command="SELECT",status="fail",} 1.0
    mybatis_requests_total{class="com.example.one.mapper.UserMapper.selectList",command="SELECT",status="success",} 4.0
    # HELP mybatis_requests_max run sql command latency in seconds.
    # TYPE mybatis_requests_max gauge
    mybatis_requests_max{class="com.example.one.mapper.SchoolMapper.selectList",command="SELECT",status="fail",} 0.0200141
    mybatis_requests_max{class="com.example.one.mapper.UserMapper.selectList",command="SELECT",status="success",} 0.7781894

    可以获取到 mybatis 查询数据库的吞吐、时延、错误分布

  • 相关阅读:
    Corosync+Pacemaker+DRBD+Mysql高可用HA配置
    高可用集群corosync+pacemaker之crmsh使用
    nfs+DRBD+corosync+pacemaker 实现高可用(ha)的nfs集群
    nginx匹配
    2011年的最后一篇
    Python自然语言处理学习笔记(66):7.7 小结
    Python自然语言处理学习笔记(65):7.6 关系抽取
    Python自然语言处理学习笔记(64): 7.5 命名实体识别
    Python自然语言处理学习笔记(67):7.8 扩展阅读
    Python自然语言处理学习笔记(68):7.9 练习
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/16521930.html
Copyright © 2020-2023  润新知