且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

扩展JavaMelod支持自定义监控点

更新时间:2022-08-20 23:04:28

背景

一直在使用一款轻量级的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
 */
@Slf4j
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>
     */
    @FunctionalInterface
    public static interface Function {
        void call();
    }
    
    /**需要返回值的回调接口定义
     * @author heshengchao
     * @param <T>
     */
    @FunctionalInterface
    public static interface Callback<T> {
        T call() ;
    }
}

使用示例说明


import net.bull.javamelody.BusMonitorProxy;

public class BusMonitorProxyTest {

    String url = "";

    /** 验证直接监控方法 */
  @Test
    public void testMonitor() {
        BusMonitorProxy.monitor("post.url(" + url + ")", () -> {
            // do something.
        });
    }

    /** 验证需要得到响应的监控 */
  @Test
    public void testMonitorAndReturn() {
        boolean result = BusMonitorProxy.monitorAndReturn("post.url(" + url + ")", () -> {
            // do something.
            return true;
        });
    }
}

最后效果

扩展JavaMelod支持自定义监控点