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