You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Btrace:按应用过滤同名类,实现指定应用连接池方法追踪

只挂钩指定JBoss EAP 6应用中Apache Commons Pool 1.6方法的解决方案

这个问题的核心在于JBoss EAP 6中每个部署的应用都有独立的类加载器,我们可以利用这一点精准过滤目标应用的连接池方法调用。下面是几种实用的实现思路:

1. 通过类加载器标识过滤目标应用

JBoss EAP 6里,每个WAR/EAR部署的类加载器名称会包含应用的部署标识(比如你的应用叫my-business-app.war,类加载器名会带有deployment.my-business-app.war的字样)。在你的Trace脚本拦截逻辑中,先判断当前调用的类加载器是否属于目标应用,再执行监控逻辑即可。

示例代码(以Java Agent拦截为例)

如果你的Trace脚本是基于Java Agent实现的,可以在拦截方法中加入类加载器判断:

import net.bytebuddy.asm.Advice;

public class PoolInterceptor {
    // 可配置的目标应用标识,避免硬编码
    private static final String TARGET_APP_ID = "deployment.my-business-app.war";

    @Advice.OnMethodEnter
    public static void onPoolMethodEnter(@Advice.Origin Class<?> poolClass) {
        ClassLoader appClassLoader = poolClass.getClassLoader();
        // 匹配目标应用的类加载器
        if (appClassLoader != null && appClassLoader.toString().contains(TARGET_APP_ID)) {
            // 执行你的监控逻辑:记录调用、统计指标等
            System.out.printf("监控到目标应用的连接池方法调用: %s.%s%n", 
                poolClass.getName(), 
                Thread.currentThread().getStackTrace()[1].getMethodName());
        }
    }
}

JBoss CLI日志过滤(如果用日志追踪)

如果你的Trace是通过开启Commons Pool的日志实现的,可以给日志添加类加载器过滤器,只输出目标应用的日志:

# 添加带类加载器过滤的日志记录器
/subsystem=logging/logger=org.apache.commons.pool:add(
    level=TRACE,
    filter={
        class=org.jboss.logmanager.filter.ClassLoaderFilter,
        properties={pattern=.*deployment.my-business-app.war.*}
    }
)

2. 通过JBoss MBean关联目标应用类加载器

如果需要更精准的匹配,可以通过JBoss的MBean服务器获取目标应用的类加载器实例,然后在拦截时直接对比实例:

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

// 获取目标应用的类加载器
public static ClassLoader getTargetAppClassLoader(String appDeploymentName) throws Exception {
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    ObjectName objectName = new ObjectName("jboss.as:deployment=" + appDeploymentName + ",subsystem=classloading");
    return (ClassLoader) mBeanServer.getAttribute(objectName, "ClassLoader");
}

之后在拦截逻辑中,对比当前调用的类加载器是否等于获取到的目标类加载器即可。

关键注意事项

  • 如果Commons Pool是放在JBoss的全局模块中(而非应用自身的lib目录),那么池类的类加载器是全局模块类加载器,此时需要通过线程上下文类加载器来判断(应用调用池方法时,线程上下文类加载器是应用自己的类加载器)。
  • 尽量把目标应用标识做成可配置项,避免硬编码到脚本中,方便后续修改。

内容的提问来源于stack exchange,提问作者mauromax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:55