分布式监控CAT客户端的SpringBoot集成
程序员文章站
2022-03-11 15:32:37
客户端项目接入CAT监控:maven依赖 com.dianping.cat cat-client 3.0.0 项目中创建src/main/resources/META-INF/app.properties写入:app.na...
客户端
项目接入CAT监控:
maven依赖
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.0</version>
</dependency>
项目中创建src/main/resources/META-INF/app.properties
写入:app.name={appName}
appName (a-z, A-Z) (0-9) (_) (-)
spring boot接入
CatFilterConfigure.java
@Configuration
public class CatFilterConfigure {
@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接入
CatMybatisInterceptor.java
@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 {
private Properties properties;
private String datasourceUrl;
public CatMybatisInterceptor(String datasourceUrl) {
this.datasourceUrl = datasourceUrl;
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
//begin cat transaction
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
String methodName = this.getMethodName(mappedStatement);
Transaction t = Cat.newTransaction("SQL", methodName);
Cat.logEvent("SQL.Database", datasourceUrl);
Cat.logEvent("SQL.Method", mappedStatement.getSqlCommandType().name().toLowerCase(), Message.SUCCESS,
getSql(invocation, mappedStatement));
try {
Object returnValue = invocation.proceed();
t.setStatus(Transaction.SUCCESS);
return returnValue;
} catch (Throwable e) {
Cat.logError(e);
t.setStatus(e);
throw e;
} finally {
t.complete();
}
}
private String getMethodName(MappedStatement mappedStatement) {
String[] strArr = mappedStatement.getId().split("\\.");
return strArr[strArr.length - 2] + "." + strArr[strArr.length - 1];
}
private String getSql(Invocation invocation, MappedStatement mappedStatement) {
Object parameter = null;
if (invocation.getArgs().length > 1) {
parameter = invocation.getArgs()[1];
}
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
Configuration configuration = mappedStatement.getConfiguration();
return showSql(configuration, boundSql);
}
private static String getParameterValue(Object obj) {
StringBuilder retStringBuilder = new StringBuilder();
if (obj instanceof String) {
retStringBuilder.append("'").append(obj).append("'");
} else if (obj instanceof Date) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT,
Locale.CHINA);
retStringBuilder.append("'").append(formatter.format(new Date())).append("'");
} else {
retStringBuilder.append("'").append(obj == null ? "" : obj).append("'");
}
return retStringBuilder.toString();
}
public static String showSql(Configuration configuration, BoundSql boundSql) {
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
StringBuilder sqlBuilder = new StringBuilder(sql);
if (parameterMappings.size() > 0 && parameterObject != null) {
int start = sqlBuilder.indexOf("?");
int end = start + 1;
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sqlBuilder.replace(start, end, 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);
sqlBuilder.replace(start, end, getParameterValue(obj));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName);
sqlBuilder.replace(start, end, getParameterValue(obj));
}
start = sqlBuilder.indexOf("?");
end = start + 1;
}
}
}
return sqlBuilder.toString();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
this.properties = properties;
}
public String getDatasourceUrl() {
return datasourceUrl;
}
public void setDatasourceUrl(String datasourceUrl) {
this.datasourceUrl = datasourceUrl;
}
}
CatMybatisConfigure
@Configuration
public class CatMybatisConfigure {
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Bean
public SqlSessionFactory mysqlSessionFactory(DataSource mysqlDataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(mysqlDataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));
sqlSessionFactoryBean.setPlugins(new Interceptor[]{new CatMybatisInterceptor(jdbcUrl)});
return sqlSessionFactoryBean.getObject();
}
}
Logback接入
CatLogbackAppender
public class CatLogbackAppender extends AppenderBase<ILoggingEvent> {
@Override
protected void append(ILoggingEvent event) {
try {
boolean isTraceMode = Cat.getManager().isTraceMode();
Level level = event.getLevel();
if (level.isGreaterOrEqual(Level.ERROR)) {
logError(event);
} else if (isTraceMode) {
logTrace(event);
}
} catch (Exception ex) {
throw new LogbackException(event.getFormattedMessage(), ex);
}
}
private void logError(ILoggingEvent event) {
ThrowableProxy info = (ThrowableProxy) event.getThrowableProxy();
if (info != null) {
Throwable exception = info.getThrowable();
Object message = event.getFormattedMessage();
if (message != null) {
Cat.logError(String.valueOf(message), exception);
} else {
Cat.logError(exception);
}
}
}
private void logTrace(ILoggingEvent event) {
String type = "Logback";
String name = event.getLevel().toString();
Object message = event.getFormattedMessage();
String data;
if (message instanceof Throwable) {
data = buildExceptionStack((Throwable) message);
} else {
data = event.getFormattedMessage().toString();
}
ThrowableProxy info = (ThrowableProxy) event.getThrowableProxy();
if (info != null) {
data = data + '\n' + buildExceptionStack(info.getThrowable());
}
Cat.logEvent(type, name, "0", data);
}
private String buildExceptionStack(Throwable exception) {
if (exception != null) {
StringWriter writer = new StringWriter(2048);
exception.printStackTrace(new PrintWriter(writer));
return writer.toString();
} else {
return "";
}
}
}
logback.xml加入如下代码
<appender name="CatAppender" class="com.xxx.xxx.xxx.log.CatLogbackAppender"></appender>
<root level="ERROR">
<appender-ref ref="CatAppender" />
</root>
如何使用cat
替换appName
直接进入cat,地址:
http://192.168.1.120:8080/cat/r/h?domain=appName&ip=All&date=2020111216&reportType=day&op=view
选择项目
- 查看Transaction报表
- 查看Event报表
自定义上报Transaction
Transaction用来监控一段代码运行情况:QPSTp
上报Transaction
Transaction t = Cat.newTransaction("URL", "pageName");
try {
//
t.setStatus(Transaction.SUCCESS);
} catch (Exception e) {
t.setStatus(e);
Cat.logError(e);
} finally {
t.complete();
}
自定义上报event
event用来监控一段代码运行次数:。Event报表的整体结构与Transaction报表几乎一样,只缺少响应时间的统计
上报event
Event event = Cat.newEvent("Event", "event1");
try {
//
event.setSuccessStatus();
} catch (Exception e) {
event.setStatus("False");
Cat.logError(e);
} finally {
event.complete();
}
本文地址:https://blog.csdn.net/Victor_An/article/details/109647976
推荐阅读