All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taotao.boot.monitor.collect.task.DataSourceCollectTask Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020-2030, Shuigedeng ([email protected] & https://blog.taotaocloud.top/).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.taotao.boot.monitor.collect.task;

import com.taotao.boot.common.utils.context.ContextUtils;
import com.taotao.boot.common.utils.lang.ObjectUtils;
import com.taotao.boot.common.utils.log.LogUtils;
import com.taotao.boot.common.utils.reflect.ClassUtils;
import com.taotao.boot.common.utils.reflect.ReflectionUtils;
import com.taotao.boot.monitor.annotation.FieldReport;
import com.taotao.boot.monitor.collect.AbstractCollectTask;
import com.taotao.boot.monitor.collect.CollectInfo;
import com.taotao.boot.monitor.properties.CollectTaskProperties;

import javax.sql.DataSource;
import java.lang.reflect.Field;

/**
 * DataSourceCollectTask
 *
 * @author shuigedeng
 * @version 2021.9
 * @since 2021-09-10 17:31:27
 */
public class DataSourceCollectTask extends AbstractCollectTask {

    private static final String TASK_NAME = "ttc.monitor.collect.datasource";

    private final CollectTaskProperties properties;
    private final boolean classExist;

    public DataSourceCollectTask(CollectTaskProperties properties) {
        this.properties = properties;
        this.classExist = ClassUtils.isExist("javax.sql.DataSource");
    }

    @Override
    public int getTimeSpan() {
        return properties.getDatasourcTimeSpan();
    }

    @Override
    public String getDesc() {
        return this.getClass().getName();
    }

    @Override
    public String getName() {
        return TASK_NAME;
    }

    @Override
    public boolean getEnabled() {
        return properties.isDatasourceEnabled() && classExist;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected CollectInfo getData() {
        try {
            DataSourceInfo info = new DataSourceInfo();
            String[] names = ContextUtils.getApplicationContext().getBeanNamesForType(DataSource.class);

            int index = 0;
            for (String name : names) {
                if ("tracingDataSource".equals(name)) {
                    continue;
                }

                DataSource dataSource = ContextUtils.getApplicationContext().getBean(name, DataSource.class);

                Class druidCls = ReflectionUtils.tryClassForName("com.alibaba.druid.pool.DruidDataSource");
                if (druidCls != null && druidCls.isAssignableFrom(dataSource.getClass())) {
                    Field field = ReflectionUtils.findField(info.getClass(), "druid" + index++);
                    if (field != null) {
                        DruidDataSourceInfo druid = new DruidDataSourceInfo();
                        druid.active = (Integer) ReflectionUtils.callMethod(dataSource, "getActiveCount", null);
                        druid.connect = (Long) ReflectionUtils.callMethod(dataSource, "getConnectCount", null);
                        druid.poolingCount = (Integer) ReflectionUtils.callMethod(dataSource, "getPoolingCount", null);
                        druid.lockQueueLength =
                                (Integer) ReflectionUtils.callMethod(dataSource, "getLockQueueLength", null);
                        druid.waitThreadCount =
                                (Integer) ReflectionUtils.callMethod(dataSource, "getWaitThreadCount", null);
                        druid.initialSize = (Integer) ReflectionUtils.callMethod(dataSource, "getInitialSize", null);
                        druid.maxActive = (Integer) ReflectionUtils.callMethod(dataSource, "getMaxActive", null);
                        druid.minIdle = (Integer) ReflectionUtils.callMethod(dataSource, "getMinIdle", null);
                        druid.connectErrorCount =
                                (Long) ReflectionUtils.callMethod(dataSource, "getConnectErrorCount", null);
                        druid.createTimeSpan =
                                (Long) ReflectionUtils.callMethod(dataSource, "getCreateTimespanMillis", null);
                        druid.closeCount = (Long) ReflectionUtils.callMethod(dataSource, "getCloseCount", null);
                        druid.createCount = (Long) ReflectionUtils.callMethod(dataSource, "getCreateCount", null);
                        druid.destroyCount = (Long) ReflectionUtils.callMethod(dataSource, "getDestroyCount", null);
                        druid.isSharePreparedStatements = ReflectionUtils.callMethod(
                                        dataSource, "isSharePreparedStatements", null)
                                .toString();
                        druid.isRemoveAbandoned = ReflectionUtils.callMethod(dataSource, "isRemoveAbandoned", null)
                                .toString();
                        druid.removeAbandonedTimeout =
                                (Integer) ReflectionUtils.callMethod(dataSource, "getRemoveAbandonedTimeout", null);
                        druid.removeAbandonedCount =
                                (Long) ReflectionUtils.callMethod(dataSource, "getRemoveAbandonedCount", null);
                        druid.rollbackCount = (Long) ReflectionUtils.callMethod(dataSource, "getRollbackCount", null);
                        druid.commitCount = (Long) ReflectionUtils.callMethod(dataSource, "getCommitCount", null);
                        druid.startTransactionCount =
                                (Long) ReflectionUtils.callMethod(dataSource, "getStartTransactionCount", null);

                        field.setAccessible(true);
                        ReflectionUtils.setFieldValue(field, info, druid);
                    }
                }

                Class hikariCls = ReflectionUtils.tryClassForName("com.zaxxer.hikari.HikariDataSource");
                if (hikariCls != null && hikariCls.isAssignableFrom(dataSource.getClass())) {
                    Field field = ReflectionUtils.findField(info.getClass(), "hikari" + index++);
                    if (field != null) {
                        HikariDataSourceInfo hikari = new HikariDataSourceInfo();
                        Object hikariPoolMXBean = ReflectionUtils.callMethod(dataSource, "getHikariPoolMXBean", null);
                        Object hikariConfigMXBean =
                                ReflectionUtils.callMethod(dataSource, "getHikariConfigMXBean", null);

						if(ObjectUtils.isNotNull(hikariPoolMXBean)){
							hikari.activeConnections =
								(Integer) ReflectionUtils.callMethod(hikariPoolMXBean, "getActiveConnections", null);
							hikari.idleConnections =
								(Integer) ReflectionUtils.callMethod(hikariPoolMXBean, "getIdleConnections", null);
							hikari.threadsAwaitingConnection = (Integer)
								ReflectionUtils.callMethod(hikariPoolMXBean, "getThreadsAwaitingConnection", null);
							hikari.totalConnections =
								(Integer) ReflectionUtils.callMethod(hikariPoolMXBean, "getTotalConnections", null);
						}


                        hikari.catalog = (String) ReflectionUtils.callMethod(hikariConfigMXBean, "getCatalog", null);
                        hikari.connectionTimeout =
                                (Long) ReflectionUtils.callMethod(hikariConfigMXBean, "getConnectionTimeout", null);
                        hikari.idleTimeout =
                                (Long) ReflectionUtils.callMethod(hikariConfigMXBean, "getIdleTimeout", null);
                        hikari.maxLifetime =
                                (Long) ReflectionUtils.callMethod(hikariConfigMXBean, "getMaxLifetime", null);
                        hikari.validationTimeout =
                                (Long) ReflectionUtils.callMethod(hikariConfigMXBean, "getValidationTimeout", null);
                        hikari.leakDetectionThreshold = (Long)
                                ReflectionUtils.callMethod(hikariConfigMXBean, "getLeakDetectionThreshold", null);
                        hikari.maximumPoolSize =
                                (Integer) ReflectionUtils.callMethod(hikariConfigMXBean, "getMaximumPoolSize", null);
                        hikari.minimumIdle =
                                (Integer) ReflectionUtils.callMethod(hikariConfigMXBean, "getMinimumIdle", null);
                        hikari.poolName = (String) ReflectionUtils.callMethod(hikariConfigMXBean, "getPoolName", null);

                        field.setAccessible(true);
                        ReflectionUtils.setFieldValue(field, info, hikari);
                    }
                }
            }
            return info;
        } catch (Exception e) {
            if (LogUtils.isErrorEnabled()) {
                LogUtils.error(e);
            }
        }
        return null;
    }

    private static class HikariDataSourceInfo implements CollectInfo {

        @FieldReport(name = TASK_NAME + ".hikari.pool.active.connections", desc = "hikari当前活动连接的数量。")
        private Integer activeConnections = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.idle.connections", desc = "hikari当前空闲的连接数。")
        private Integer idleConnections = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.threads.awaiting.connection", desc = "hikari等待连接的线程数")
        private Integer threadsAwaitingConnection = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.total.connections", desc = "hikari连接池中的连接总数")
        private Integer totalConnections = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.catalog", desc = "hikari设置的默认目录名称")
        private String catalog = "";

        @FieldReport(name = TASK_NAME + ".hikari.pool.connection.timeout", desc = "hikari等待池中连接的最大毫秒数")
        private Long connectionTimeout = 0L;

        @FieldReport(name = TASK_NAME + ".hikari.pool.idle.timeout", desc = "hikari允许连接停留的最长时间(以毫秒为单位)")
        private Long idleTimeout = 0L;

        @FieldReport(name = TASK_NAME + ".hikari.pool.max.lifetime", desc = "hikari连接池中连接的最长生命周期")
        private Long maxLifetime = 0L;

        @FieldReport(name = TASK_NAME + ".hikari.pool.validation.timeout", desc = "hikari等待连接被验证为的最大毫秒数")
        private Long validationTimeout = 0L;

        @FieldReport(
                name = TASK_NAME + ".hikari.pool.leak.detection.threshold",
                desc = "hikari消息发送之前连接可以离开池的时间量.记录表明可能的连接泄漏")
        private Long leakDetectionThreshold = 0L;

        @FieldReport(
                name = TASK_NAME + ".hikari.pool.maximum.pool.size",
                desc = "hikari HikariCP 将保留在池中的最大连接数,包括空闲和使用中的连接。")
        private Integer maximumPoolSize = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.minimum.idle", desc = "hikari尝试在池中维护的最小空闲连接数。包括空闲和使用中的连接")
        private Integer minimumIdle = 0;

        @FieldReport(name = TASK_NAME + ".hikari.pool.name", desc = "hikari线程池名称")
        private String poolName = "";
    }

    private static class DataSourceInfo implements CollectInfo {

        @FieldReport(name = TASK_NAME + ".druid0.info", desc = "druid0信息")
        private DruidDataSourceInfo druid0;

        @FieldReport(name = TASK_NAME + ".druid1.info", desc = "druid1信息")
        private DruidDataSourceInfo druid1;

        @FieldReport(name = TASK_NAME + ".druid2.info", desc = "druid2信息")
        private DruidDataSourceInfo druid2;

        @FieldReport(name = TASK_NAME + ".druid3.info", desc = "druid3信息")
        private DruidDataSourceInfo druid3;

        @FieldReport(name = TASK_NAME + ".druid4.info", desc = "druid4信息")
        private DruidDataSourceInfo druid4;

        @FieldReport(name = TASK_NAME + ".druid5.info", desc = "druid5信息")
        private DruidDataSourceInfo druid5;

        @FieldReport(name = TASK_NAME + ".druid6.info", desc = "druid6信息")
        private DruidDataSourceInfo druid6;

        @FieldReport(name = TASK_NAME + ".druid7.info", desc = "druid7信息")
        private DruidDataSourceInfo druid7;

        @FieldReport(name = TASK_NAME + ".druid8.info", desc = "druid8信息")
        private DruidDataSourceInfo druid8;

        @FieldReport(name = TASK_NAME + ".druid9.info", desc = "druid9信息")
        private DruidDataSourceInfo druid9;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari0信息")
        private HikariDataSourceInfo hikari0;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari1信息")
        private HikariDataSourceInfo hikari1;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari2信息")
        private HikariDataSourceInfo hikari2;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari3信息")
        private HikariDataSourceInfo hikari3;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari4信息")
        private HikariDataSourceInfo hikari4;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari5信息")
        private HikariDataSourceInfo hikari5;

        @FieldReport(name = TASK_NAME + ".hikari.info", desc = "hikari6信息")
        private HikariDataSourceInfo hikari6;
    }

    private static class DruidDataSourceInfo implements CollectInfo {

        @FieldReport(name = TASK_NAME + ".druid.pool.startTransaction.count", desc = "druid sql 开启事务次数")
        private Long startTransactionCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.commit.count", desc = "druid sql commit次数")
        private Long commitCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.rollback.count", desc = "druid sql回滚次数")
        private Long rollbackCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.removeAbandoned.count", desc = "druid 连接超时回收次数")
        private Long removeAbandonedCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.removeAbandoned.timeout", desc = "druid 连接超时回收周期(秒)")
        private Integer removeAbandonedTimeout = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.isRemoveAbandoned", desc = "druid 是否开启连接超时回收")
        private String isRemoveAbandoned = "";

        @FieldReport(name = TASK_NAME + ".druid.pool.isSharePreparedStatements", desc = "druid preparedStatement是否缓存")
        private String isSharePreparedStatements = "";

        @FieldReport(name = TASK_NAME + ".druid.pool.destroy.count", desc = "druid销毁连接次数")
        private Long destroyCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.create.count", desc = "druid创建连接次数")
        private Long createCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.close.count", desc = "druid关闭连接次数")
        private Long closeCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.create.timeSpan", desc = "druid物理连接创建耗时(毫秒)")
        private Long createTimeSpan = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.connect.errorCount", desc = "druid物理连接错误数")
        private Long connectErrorCount = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.idle.min", desc = "druid连接池最小值")
        private Integer minIdle = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.active.max", desc = "druid连接池最大值")
        private Integer maxActive = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.initial.size", desc = "druid连接池初始化长度")
        private Integer initialSize = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.waitThread.count", desc = "druid获取连接时等待线程数")
        private Integer waitThreadCount = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.lockQueue.length", desc = "druid获取连接等待队列长度")
        private Integer lockQueueLength = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.active", desc = "druid正在打开的连接数")
        private Integer active = 0;

        @FieldReport(name = TASK_NAME + ".druid.pool.connect", desc = "druid申请连接的次数")
        private Long connect = 0L;

        @FieldReport(name = TASK_NAME + ".druid.pool.poolingCount", desc = "druid连接池空闲连接数")
        private Integer poolingCount = 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy