集成美团cat监控
点关注不迷路,欢迎再来!
精简博客内容,尽量已专业术语来分享。
努力做到对每一位认可自己的读者负责。
帮助别人的同时更是丰富自己的良机。
最近研究spring集成美团cat监控,关于美团cat环境搭建在上篇博客已介绍,集成美团cat在对代码异常,接口请求调用次数与调用时间,sql执行时间和异常,url访问调用时间和次数进行统计,使代码可以有效的管理,在代码与sql查错和排除优化上有显著的效果,可以提升开发和运维的工作效率。有需要的朋友可以了解下。直接步入主题:
CAT支持的监控消息类型包括:
• Transaction 适合记录跨越系统边界的程序访问行为,比如远程调用,数据库调用,也适合执行时间较长的业务逻辑监控,Transaction用来记录一段代码的执行时间和次数。
• Event 用来记录一件事发生的次数,比如记录系统异常,它和transaction相比缺少了时间的统计,开销比transaction要小。
• Heartbeat 表示程序内定期产生的统计信息, 如CPU%, MEM%, 连接池状态, 系统负载等。
• Metric 用于记录业务指标、指标可能包含对一个指标记录次数、记录平均值、记录总和,业务指标最低统计粒度为1分钟。
一.引入cat-client 的meven依赖
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.0</version>
</dependency>
二.springMVC集成url监控埋点
在web项目的web.xml配置文件中加入如下配置即可:
<filter>
<filter-name>cat-filter</filter-name>
<filter-class>com.dianping.cat.servlet.CatFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cat-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
三.springboot集成url监控埋点
因为springboot项目没有web.xml ,所以需要创建cat核心拦截器。
/**
* cat核心拦截器
*/
@Configuration
public class CatConfig {
//将拦截器注册到容器中
@Bean
public FilterRegistrationBean catFilter(){
FilterRegistrationBean registration = new FilterRegistrationBean();
CatFilter filter = new CatFilter();
registration.setFilter(filter);
registration.addUrlPatterns("/*");
registration.setName("cat-filter");
registration.setOrder(1);
return registration;
}
}
四.集成Mybatis监控埋点
/**
*<p>
*description:
*</p>
* @author andy
* @since 2018年5月6日
* @see
* mybatis拦截器注入到sqlSessionFactory
*/
@Configuration
@ConditionalOnClass({ EnableTransactionManagement.class, EntityManager.class })
@AutoConfigureAfter({ HikariCPConfig.class })
@MapperScan(basePackages = { "com.axatp.cloud.dao" })
public class MybatisConfig {
private static Log logger = LogFactory.getLog(MybatisConfig.class);
@Resource
private DataSource dataSource;
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory() {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage("com.axatp.cloud.model");
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:/com/axatp/cloud/mapper/*.xml"));
sessionFactory.setPlugins(new Interceptor[]{new CatMybatisInterceptor()}); //MyBatis插件
return sessionFactory.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Bean
@ConditionalOnMissingBean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
/**
* 对MyBatis进行拦截,添加Cat监控
*
*/
@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 CatMybatisInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) {
MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
Configuration configuration = statement.getConfiguration();
HikariDataSource dataSource = (HikariDataSource) configuration.getEnvironment().getDataSource();
//记录sql执行处理的时间
Transaction transaction = Cat.newTransaction(Constants.SQL, statement.getId());
//记录事件
Cat.logEvent(Constants.SQL_TYPE, statement.getSqlCommandType().name());
Cat.logEvent(Constants.SQL_URL, dataSource.getJdbcUrl());
//得到sql语句
if (invocation.getArgs().length > 1) {
Object obj = invocation.getArgs()[1];
BoundSql boundSql = statement.getBoundSql(obj);
Cat.logEvent(Constants.SQL_DETAILS, showSql(configuration, boundSql));
}
return doFinish(invocation, transaction);
}
@Override
public Object plugin(Object o) {
if (o instanceof Executor) {
return Plugin.wrap(o, this);
}
return o;
}
@Override
public void setProperties(Properties properties) {
}
private Object doFinish(Invocation invocation, Transaction transaction) {
Object object = null;
try {
object = invocation.proceed();
transaction.setStatus(Transaction.SUCCESS);
} catch (Exception e) {
Cat.getProducer().logError(e);
}
return object;
}
/**
* 解析sql语句
*
* @param configuration Configuration
* @param boundSql BoundSql
* @return String
*/
private static String showSql(Configuration configuration, BoundSql boundSql) {
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
if (parameterMappings.size() > 0 && parameterObject != null) {
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
for (ParameterMapping parameterMapping : parameterMappings) {
String propertyName = parameterMapping.getProperty();
if (metaObject.hasGetter(propertyName)) {
Object obj = metaObject.getValue(propertyName);
sql = sql.replaceFirst("\\?", getParameterValue(obj));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName);
sql = sql.replaceFirst("\\?", getParameterValue(obj));
}
}
}
}
return sql;
}
/**
* 获取 sql 参数值,参数解析
*
* @param obj value
* @return parameter value
*/
private static String getParameterValue(Object obj) {
String value;
if (obj instanceof String) {
value = "'" + obj.toString() + "'";
} else if (obj instanceof Date) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
value = "'" + formatter.format(new Date()) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "";
}
}
return value;
}
}
五. 配置监控的项目名
在需要接入CAT监控平台的项目中新建属性配置文件src/main/resources/META-INF/app.properties。其内容如下:
################## CAT会自动加载此文件 ##################
应用的名称(可以根据此名称在CAT的管理控制台查找对应的信息)
app.name=service
六. 客户端配置
你需要在此项目所在的盘符(即这里的D盘)创建data\appdatas\cat目录,并将client.xml配置文件存放在这个路径中。如作者的客户端配置文件D:\data\appdatas\cat\client.xml:
<?xml version="1.0" encoding="utf-8"?>
<config mode="client" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="config.xsd">
<servers>
<server ip="192.1168.23.1" port="2280" http-port="8080" />
</servers>
</config>
七. cat监控平台效果图
八. 笔记总结
本次博客写的笔记匆忙,有些地方集成写的可能不是很详细,不足之处欢迎指导,本人也会在后续持续更新。