背景
一直在使用一款轻量级的APM监控工具:Javamelody。使用简单,监控数据还是挺多维度的,定期拉出来分析还是一件很有价值的事情。
但是Javamelody本身只对Http与Spring托管对象监控,还有很多我们自己的工具类或基础库没法监控起来。在阅读其部分源码后,写了一个扩展类,实现了监控项目的自定义操作。
话不多说,直接上代码:
代码
packagenet.bull.javamelody;//因MonitoringProxy类定义为了Package。此处的Package名称需要与net.bull.javamelody保持一置importlombok.extern.slf4j.Slf4j; importnet.bull.javamelody.internal.model.Counter; /**javamelody监控代理。在javamelody的基础上扩展部分监控项,用于一些自定义场景[或方法]的监控点。* @author heshengchao*/publicclassBusMonitorProxy { /**默认Counter 都放到Spring下面* @return*/publicstaticCountergetCounter() { returnMonitoringProxy.getSpringCounter(); } /** 自定义监控点* @param monitorName 业务监控点名称* @param call 回调函数* @throws Exception */publicstaticvoidmonitor(StringmonitorName,Functioncall) { booleansystemError=false;//主要用于标记方法执行期间是否产生的异常。try { getCounter().bindContextIncludingCpu(monitorName); call.call(); }catch (Throwablee) { systemError=true; thrownewRuntimeException(e); } finally { getCounter().addRequestForCurrentContext(systemError); } } /** 自定义监控点【执行完成后,需要将返回值】* @param <T>* @param monitorName 业务监控点名称* @param call 回调函数* @throws Exception */publicstatic<T>TmonitorAndReturn(StringmonitorName,Callback<T>call) { booleansystemError=false; try { getCounter().bindContextIncludingCpu(monitorName); returncall.call(); }catch (Throwablee) { systemError=true; thrownewRuntimeException(e); } finally { getCounter().addRequestForCurrentContext(systemError); } } /**不需要返回值的回调接口定义* @author heshengchao* @param <T>*/publicstaticinterfaceFunction { voidcall(); } /**需要返回值的回调接口定义* @author heshengchao* @param <T>*/publicstaticinterfaceCallback<T> { Tcall() ; } }
使用示例说明
importnet.bull.javamelody.BusMonitorProxy; publicclassBusMonitorProxyTest { Stringurl=""; /** 验证直接监控方法 */publicvoidtestMonitor() { BusMonitorProxy.monitor("post.url("+url+")", () -> { // do something. }); } /** 验证需要得到响应的监控 */publicvoidtestMonitorAndReturn() { booleanresult=BusMonitorProxy.monitorAndReturn("post.url("+url+")", () -> { // do something.returntrue; }); } }
最后效果