Spring/Spring Boot微服务项目 集成Druid 实现监控功能

步骤如下: 1、首先新建2个model(LogInfo,MonitorInfo)

public class LogInfo implements Serializable {

	private static final long serialVersionUID = 5289821541255302264L;
	private String sql;
	private String sqlParam;
	private int maxParallel;
	private long executeMillisTotal;
	private long executeCount;
	private long executeErrorCount;
	private Date maxOccurTime;
	private long histogram_0_1;
	private long histogram_1_10;
	private int histogram_100_1000;
	private int histogram_1000_10000;
	private int histogram_10000_100000;
	private int histogram_100000_1000000;
	private int histogram_1000000_more;
	private String lastError;
	private String lastErrorMessage;
	private String lastErrorStackTrace;
	private String lastErrorClass;
	private Date lastErrorTime;
	private int histogram_10_100;
	private long executeMillisMax;
	public String getSql() {
		return sql;
	}
	public void setSql(String sql) {
		this.sql = sql;
	}
	public String getSqlParam() {
		return sqlParam;
	}
	public void setSqlParam(String sqlParam) {
		this.sqlParam = sqlParam;
	}
	public int getMaxParallel() {
		return maxParallel;
	}
	public void setMaxParallel(int maxParallel) {
		this.maxParallel = maxParallel;
	}
	public long getExecuteMillisTotal() {
		return executeMillisTotal;
	}
	public void setExecuteMillisTotal(long executeMillisTotal) {
		this.executeMillisTotal = executeMillisTotal;
	}
	public long getExecuteCount() {
		return executeCount;
	}
	public void setExecuteCount(long executeCount) {
		this.executeCount = executeCount;
	}
	public long getExecuteErrorCount() {
		return executeErrorCount;
	}
	public void setExecuteErrorCount(long executeErrorCount) {
		this.executeErrorCount = executeErrorCount;
	}
	public Date getMaxOccurTime() {
		return maxOccurTime;
	}
	public void setMaxOccurTime(Date maxOccurTime) {
		this.maxOccurTime = maxOccurTime;
	}
	public long getHistogram_0_1() {
		return histogram_0_1;
	}
	public void setHistogram_0_1(long histogram_0_1) {
		this.histogram_0_1 = histogram_0_1;
	}
	public long getHistogram_1_10() {
		return histogram_1_10;
	}
	public void setHistogram_1_10(long histogram_1_10) {
		this.histogram_1_10 = histogram_1_10;
	}
	public int getHistogram_100_1000() {
		return histogram_100_1000;
	}
	public void setHistogram_100_1000(int histogram_100_1000) {
		this.histogram_100_1000 = histogram_100_1000;
	}
	public int getHistogram_1000_10000() {
		return histogram_1000_10000;
	}
	public void setHistogram_1000_10000(int histogram_1000_10000) {
		this.histogram_1000_10000 = histogram_1000_10000;
	}
	public int getHistogram_10000_100000() {
		return histogram_10000_100000;
	}
	public void setHistogram_10000_100000(int histogram_10000_100000) {
		this.histogram_10000_100000 = histogram_10000_100000;
	}
	public int getHistogram_100000_1000000() {
		return histogram_100000_1000000;
	}
	public void setHistogram_100000_1000000(int histogram_100000_1000000) {
		this.histogram_100000_1000000 = histogram_100000_1000000;
	}
	public int getHistogram_1000000_more() {
		return histogram_1000000_more;
	}
	public void setHistogram_1000000_more(int histogram_1000000_more) {
		this.histogram_1000000_more = histogram_1000000_more;
	}
	public String getLastError() {
		return lastError;
	}
	public void setLastError(String lastError) {
		this.lastError = lastError;
	}
	public String getLastErrorMessage() {
		return lastErrorMessage;
	}
	public void setLastErrorMessage(String lastErrorMessage) {
		this.lastErrorMessage = lastErrorMessage;
	}
	public String getLastErrorStackTrace() {
		return lastErrorStackTrace;
	}
	public void setLastErrorStackTrace(String lastErrorStackTrace) {
		this.lastErrorStackTrace = lastErrorStackTrace;
	}
	public String getLastErrorClass() {
		return lastErrorClass;
	}
	public void setLastErrorClass(String lastErrorClass) {
		this.lastErrorClass = lastErrorClass;
	}
	public Date getLastErrorTime() {
		return lastErrorTime;
	}
	public void setLastErrorTime(Date lastErrorTime) {
		this.lastErrorTime = lastErrorTime;
	}
	public int getHistogram_10_100() {
		return histogram_10_100;
	}
	public void setHistogram_10_100(int histogram_10_100) {
		this.histogram_10_100 = histogram_10_100;
	}
	public long getExecuteMillisMax() {
		return executeMillisMax;
	}
	public void setExecuteMillisMax(long executeMillisMax) {
		this.executeMillisMax = executeMillisMax;
	}
}


public class MonitorInfo implements Serializable {

	
	private static final long serialVersionUID = -2127636421971490585L;

	private List<LogInfo> LogInfos;
	private String sysIdentify;

	public List<LogInfo> getLogInfos() {
		return LogInfos;
	}

	public void setLogInfos(List<LogInfo> logInfos) {
		LogInfos = logInfos;
	}

	public String getSysIdentify() {
		return sysIdentify;
	}

	public void setSysIdentify(String sysIdentify) {
		this.sysIdentify = sysIdentify;
	}

}

2、model建好之后,自定义一个StatLogger,创建一个抽象类 MonitorDataSourceSql来实现获取监控数据,代码如下:

public abstract class MonitorDataSourceSql extends DruidDataSourceStatLoggerAdapter
		implements DruidDataSourceStatLogger {

	private final static Log logger = LogFactory.getLog(DruidPooledConnection.class);

	public MonitorDataSourceSql() {
		this.configFromProperties(System.getProperties());
	}

	/* 
	 * DruidDataSourceStatValue包含这整个SQL监控数据,按需索取
	 * 
	 **/
	@Override
	public void log(DruidDataSourceStatValue statValue) {
		List<JdbcSqlStatValue> sqlList = statValue.getSqlList();
		if (sqlList != null && sqlList.size() > 0) {
			List<LogInfo> logInfos = new ArrayList<LogInfo>(sqlList.size());
			MonitorInfo monitorInfo = new MonitorInfo();
			JdbcSqlStatValue value = null;
			Throwable executeThrowable = null;
			LogInfo info = null;
			try {
				for (int i = 0; i < sqlList.size(); i++) {
					value = sqlList.get(i);
					info = new LogInfo();
					info.setHistogram_0_1(value.getHistogram_0_1());
					info.setHistogram_1_10(value.getHistogram_1_10());
					info.setHistogram_10_100(value.getHistogram_10_100());
					info.setHistogram_100_1000(value.getHistogram_100_1000());
					info.setHistogram_1000_10000(value.getHistogram_1000_10000());
					info.setHistogram_1000000_more(value.getHistogram_1000000_more());
					info.setHistogram_100000_1000000(value.getHistogram_100000_1000000());
					info.setHistogram_10000_100000(value.getHistogram_10000_100000());
					info.setMaxParallel(value.getConcurrentMax());
					info.setMaxOccurTime(value.getExecuteNanoSpanMaxOccurTime());
					info.setSql(value.getSql());
					info.setSqlParam(value.getLastSlowParameters());
					info.setExecuteMillisTotal(value.getExecuteMillisTotal());
					info.setExecuteErrorCount(value.getExecuteErrorCount());
					info.setExecuteMillisMax(value.getExecuteMillisMax());
					info.setExecuteCount(value.getExecuteCount());

					executeThrowable = value.getExecuteErrorLast();
					if (executeThrowable != null) {
						info.setLastErrorClass(executeThrowable.getClass().getName());
						info.setLastErrorMessage(executeThrowable.getMessage());
						info.setLastErrorStackTrace(Utils.toString(executeThrowable.getStackTrace()));
						info.setLastErrorTime(value.getExecuteErrorLastTime());
					}
					
					logInfos.add(info);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("监控数据转换异常", e);
			}
			monitorInfo.setLogInfos(logInfos);
			monitorInfo.setSysIdentify(getIdentify());
			sendMonitorLog(monitorInfo);
		}
	}

	/**
	 * 监控数据
	 * 
	 **/
	public abstract void sendMonitorLog(MonitorInfo monitorInfo);

	public abstract String getIdentify();

	@Override
	public void configFromProperties(Properties properties) {
		super.configFromProperties(properties);
	}

	@Override
	public void setLogger(Log logger) {
	}

	@Override
	public void setLoggerName(String loggerName) {
		super.setLoggerName(loggerName);
	}

}

3、创建MonitorDataSourceSqlImpl 继承刚才创建的抽象类并引入redis,将监控数据放到redis中,这里的JSON使用的也是阿里巴巴的fastjson

public class MonitorDataSourceSqlImpl extends MonitorDataSourceSql {

	@Autowired
	private IRedisService cacheService;
	
	@Override
	public void sendMonitorLog(MonitorInfo monitorInfo) {

		try {
			String str = JSONObject.toJSONString(monitorInfo);
			this.cacheService.set(RedisKey.MONITORLOG, str);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public String getIdentify() {
		return null;
	}

}

4、数据源配置,代码如下:

<bean id="webDataSource" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="${web.jdbcUrl}" />
		<property name="username" value="${web.user}" />
		<property name="password" value="${web.password}" />
		<!-- 配置初始化大小、最小、最大 -->
		<property name="initialSize" value="5" />
		<property name="minIdle" value="2" />
		<property name="maxActive" value="200" />
                <!-- 设置数据库编码 为utf8mb4 -->
		<property name="connectionInitSqls" value="set names utf8mb4;" />
		<!-- 配置获取连接等待超时的时间 -->
		<property name="maxWait" value="60000" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
     	 <!-- 记录sql -->
		<property name="filters" value="config,stat,log4j,mergeStat" />
        <!-- 慢sql 时间定义 -->
     	        <property name="connectionProperties"             value="druid.stat.slowSqlMillis=5000;config.decrypt=true;config.decrypt.key=${tgbweb.publicKey}" /> 
        <!-- 每3秒保存日志 -->
         <property name="timeBetweenLogStatsMillis" value="3000" /> 
        <!-- 合并多个DruidDataSource的监控数据 -->
           <!-- <property name="useGlobalDataSourceStat" value="true" /> --> 
        <!-- 定制化日志输出 -->
        <property name="statLogger" ref="myStatLogger" />
       
	</bean>

	<bean id="myStatLogger" class="com.taoguba.monitor.sql.impl.MonitorDataSourceSqlImpl">

 	</bean>

5、通过Controller获取数据并返回JSON给前端

@RestController
@RequestMapping(value = "/new/monitor")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MonitorController extends BaseController{

	@Autowired
	protected IRedisService cacheService;
	
	@GetMapping(value = "/getDataSourceSql")
	public Result getDataSourceSql() {
	        String data = this.cacheService.get(RedisKey.MONITORLOG);
		MonitorInfo mon= JSONObject.parseObject(data,MonitorInfo.class);
		return new Result(mon);
	}
}

6、JSON数据,前端取到这些数据展示即可(此处暂不展示效果了。。)

{
status: true,
errorCode: 0,
errorMessage: "",
dto: {
sysIdentify: null,
logInfos: [
{
sql: "select count(*) from topi where beFg='Y' and usefulnum > 0 and catD between 2 and 3 and uid=?",
sqlParam: null,
maxParallel: 2,
executeMillisTotal: 3,
executeCount: 2,
executeErrorCount: 0,
maxOccurTime: 1505988865405,
histogram_0_1: 0,
histogram_1_10: 2,
histogram_100_1000: 0,
histogram_1000_10000: 0,
histogram_10000_100000: 0,
histogram_100000_1000000: 0,
histogram_1000000_more: 0,
lastError: null,
lastErrorMessage: null,
lastErrorStackTrace: null,
lastErrorClass: null,
lastErrorTime: null,
histogram_10_100: 0,
executeMillisMax: 1
}]
},
_t: 1505988871072

7、至此微服务项目集成Druid 监控数据 完成收集展示,如有问题 ,欢迎留言指正。

转载于:https://my.oschina.net/dyl226/blog/1541325

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值