Cat监控埋点集成

Cat监控埋点集成

首页休闲益智Project Cat更新时间:2024-05-11

原创不易,请多多支持。对java技术感兴趣的童鞋请关注我,后续会陆续推出各类java技术文章。 概述

看过上篇,对cat开源系统应该有了认识的全貌。本篇将介绍Cat如何在项目中集成。

由于cat基于java开发,这里以java springboot项目的集成为例。

集成步骤

cat采用侵入性的监控埋点,实现监控端数据的信息收集。即收集的数据信息,需要在项目业务代码中预埋cat的api。

添加依赖包

监控项目中添加cat-client.jar依赖

<dependency> <groupId>com.dianping.cat</groupId> <artifactId>cat-client</artifactId> <version>1.4.0</version> </dependency>

版本号可根据官方发布自行选择适合的依赖。

添加cat配置client.xml

项目对应根目录,添加client.xml文件。

\data\appdatas\cat\client.xml

cat监控客户端有自己的使用data目录,该目录要求放在集成开发项目(或发布项目)所在目录的根目录。如集成项目在d:\workspace\下,对应cat使用目录为d:\data。data目录下会存放cat日志文件和server配置的一些信息文件。

其中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> <!-- Local mode for development --> <server ip="127.0.0.1" port="2280" http-port="8080" /> </servers> </config>

server元素ip属性对应cat server端部署ip地址,port端口为上报监控消息的tcp访问端口,http-port端口为cat server管理端访问端口。

由此可知,cat client对集成项目的监听消息,是通过tcp长连接默认走2280端口上报数据。选择tcp方式,而非http,是为了保证数据上报的高效实时。http port的配置,是为了client调用cat server http api,获取一些server端集群机器变更的信息。

添加埋点api

项目的埋点有通用的埋点和定制化埋点。

通用埋点: 如restful api接口监控,sql数据库访问监控、缓存使用监控等。对于通用的监控埋点需求,可以封装成公共服务工具类,便于其他项目直接使用。

定制化埋点: 基于不同业务场景需求,如报表job生成、业务监控(当日订单金额监控)等,project中自行通过cat-client Api实现灵活的自定义埋点。

Cat核心Api

Cat对监控的消息,定义了几个监控对象 Transaction(访问时间)、Event(访问次数)、Heartbeat(系统心跳元数据)、Metric(业务指标监控)模型。主要api也是围绕这几类实现。

以下是官方给出的监控api样例。使用比较简单,业务代码中需要自行埋点的可以参考使用。

详请请参见官方文档

监控应用domain配置

项目目录中新增app.preperties文件。

src/main/resources/META-INF/app.properties

app.properties文件新增内容。

app.name={appkey}

{appkey}替换为监控应用名,如用户项目,app.name=user

restful api埋点

对于restful api项目,可以编写一个通用filter类,对http请求进行拦截,统计接口的访问次数、响应时间、调用报错等指标。

针对这类场景,cat-client中已实现了CatFilter类。项目中只需引入便可使用。

springboot项目中添加以下初始化配置。

@Bean public FilterRegistrationBean catFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); CatFilter catFilter = new CatFilter(); registration.setFilter(catFilter); registration.addUrlPatterns("/*"); // 定制化实现无关请求的过滤 registration.addInitParameter("excludeUris", ".*\\.css$;.*\\.js$;.*\\.png$;.*\\.gif$;.*\\.jpg$"); registration.setName("catFilter"); registration.setOrder(1); return registration; } mybatis sql埋点

新增CatMybatisPlugin.java文件

package com.dianping.cat.ext; import com.alibaba.fastjson.JSON; import com.dianping.cat.Cat; import com.dianping.cat.ext.CatGlobalPropConfig; import com.dianping.cat.ext.MybatisSqlCfg; import com.dianping.cat.message.Transaction; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; @Intercepts({ @Signature( method = "query", type = Executor.class, 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} ), @Signature( method = "update", type = Executor.class, args = {MappedStatement.class, Object.class} )}) public class CatMybatisPlugin implements Interceptor { private static Log logger = LogFactory.getLog(CatMybatisPlugin.class); private Executor target; public CatMybatisPlugin() { } public Object intercept(Invocation invocation) throws Throwable { MybatisSqlCfg mybatisSqlCfg = CatGlobalPropConfig.getInstance().getMybatisSqlCfgThreadLocal(); Object returnObj = null; if(mybatisSqlCfg != null && !mybatisSqlCfg.isSqlMonitor()) { returnObj = invocation.proceed(); return returnObj; } else { MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0]; String[] strArr = mappedStatement.getId().split("\\."); String methodName = strArr[strArr.length - 2] "." strArr[strArr.length - 1]; Object parameter = null; if(invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } Transaction t = Cat.newTransaction("SQL", methodName); BoundSql boundSql = mappedStatement.getBoundSql(parameter); String sql = boundSql.getSql(); Object parameterObject = boundSql.getParameterObject(); SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); Cat.logEvent("SQL.Method", sqlCommandType.name().toLowerCase(), "0", sql); Cat.logEvent("SQL.Param", "Value", "0", JSON.toJSONString(parameterObject)); try { returnObj = invocation.proceed(); t.setStatus("0"); } catch (Exception var17) { t.setStatus(var17); Cat.logError(var17); throw var17; } finally { t.complete(); } return returnObj; } } public Object plugin(Object target) { if(target instanceof Executor) { this.target = (Executor)target; return Plugin.wrap(target, this); } else { return target; } } public void setProperties(Properties properties) { } }

以mybatis插件方式实现sql的监控埋点。

项目中mybatis-config.xml添加插件集成。

全局错误埋点

springboot全局异常处理添加cat error埋点。

package com.dctl.ea.demo.app.config; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.support.spring.FastJsonJsonView; import com.dctl.ea.base.vo.BaseResponseVo; import com.dctl.ea.base.vo.DefaultResponseVo; import com.dctl.ea.common.redis.flowcontrol.RedisFlowLimitException; import com.dctl.ea.common.util.IpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import sun.net.util.IPAddressUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; @Component public class ExceptionResolver implements HandlerExceptionResolver { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { logger.error("系统全局异常",e); int code = BaseResponseVo.SYSYTEM_EXCEPTION; String message = "系统异常"; //Cat 全局异常埋点 Cat.logError("系统全局异常:",e); FastJsonJsonView fastJsonJsonView = new FastJsonJsonView(); ModelAndView modelAndView = new ModelAndView(); fastJsonJsonView.setAttributesMap(JSON.parseObject(JSON.toJSONString(DefaultResponseVo.fail(code,message)), Map.class)); modelAndView.setView(fastJsonJsonView); return modelAndView; } }

到此,监控项目的Cat client集成已完成。本文介绍了Cat在java项目中如何实现自定义的埋点方式,有类似需求的童鞋可以参考实现。

下篇将介绍Cat项目集成中的一些深入定制优化,有兴趣的童鞋,请关注我。原创不易,请多多支持,谢谢!

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved