StackCat 是一个开源的 Java 应用运行时调用链追踪与分析工具,采用 Java Agent 技术实现零侵入的方法调用监控,帮助开发者快速定位性能瓶颈、分析代码执行路径。
- 零侵入监控:基于 Java Instrumentation 和 ASM 字节码增强,无需修改业务代码
- 全链路追踪:自动捕获 Controller、Service、Repository 等各层级方法调用
- SQL 语句捕获:支持 Spring Data JPA、MyBatis 和原生 JDBC 的 SQL 语句跟踪
- 调用树构建:精确记录方法调用的父子关系和执行顺序
- 异步上报:采用批量异步上报机制,最小化对业务性能的影响
- 灵活过滤:支持包级别的 include/exclude 配置,精准控制监控范围
- 线程安全:基于 ThreadLocal 实现线程隔离的调用链追踪
- 实时仪表盘:展示请求总数、活跃请求、方法调用统计等关键指标
- 调用链可视化:树形结构展示完整的方法调用链,支持展开/折叠交互
- 请求搜索:支持按请求 ID、时间范围等条件查询历史调用记录
- SQL 关联展示:在调用链中直接查看关联的 SQL 语句
- OpenObserve 集成:可结合 OpenObserve 实现链路数据的深度集中采集与分析
- 多框架支持:内置对 Spring、MyBatis 等主流框架的适配
- 插件化设计:支持自定义拦截器和数据上报策略
graph TB
subgraph "被监控应用"
App[Java 应用进程]
Agent[StackCat Agent<br/>字节码增强]
end
subgraph "StackCat 服务端"
Server[StackCat App<br/>Spring Boot 服务]
API[REST API<br/>/api/tracking/batch]
Web[Web UI<br/>Thymeleaf 界面]
end
subgraph "数据存储"
DB[(PostgreSQL<br/>数据库)]
end
subgraph "可选集成"
OO[OpenObserve<br/>日志平台]
end
App -->|Java Agent 加载| Agent
Agent -->|异步批量上报| API
API --> Server
Server -->|持久化| DB
Server -->|查询数据| Web
Web -->|展示调用链| User[用户]
Server -.->|可选| OO
style Agent fill:#e1f5ff
style Server fill:#fff4e1
style DB fill:#e8f5e9
style OO fill:#f3e5f5
StackCat 采用 Agent + Server 的架构模式,实现零侵入的应用监控:
- 被监控应用:运行中的 Java 应用,通过 Java Agent 机制加载 StackCat Agent
- StackCat Agent:在应用进程中运行,通过字节码增强技术收集方法调用数据
- StackCat App:独立的后端服务,接收 Agent 上报的数据并提供 Web 界面
- PostgreSQL:持久化存储追踪数据和统计信息
- OpenObserve(可选):可集成日志平台进行深度分析
- 采集阶段:Agent 拦截方法调用,收集调用链、SQL 语句、HTTP 请求头等信息
- 上报阶段:Agent 通过异步批量机制将数据发送到 StackCat App
- 存储阶段:StackCat App 将数据持久化到 PostgreSQL 数据库
- 展示阶段:Web 界面从数据库查询数据,以树形结构展示调用链
graph TD
Parent[stackcat-parent<br/>父模块<br/>统一管理依赖和构建配置]
subgraph "子模块"
Agent[stackcat-agent<br/>Java Instrumentation Agent]
App[stackcat-app<br/>Spring Boot 应用]
end
subgraph "Agent 核心组件"
Transformer[MethodTrackingTransformer<br/>字节码转换器]
Bridge[MethodTrackingBridge<br/>数据收集与上报]
Filter[PackageFilter<br/>包过滤逻辑]
end
subgraph "App 核心组件"
Controller[ApiController<br/>REST API 接口]
Service[StatisticsService<br/>业务逻辑处理]
Repository[Repository 层<br/>数据访问]
Entity[Entity 层<br/>数据模型]
end
Parent --> Agent
Parent --> App
Agent --> Transformer
Agent --> Bridge
Agent --> Filter
App --> Controller
App --> Service
App --> Repository
App --> Entity
style Parent fill:#ffeb3b
style Agent fill:#2196f3,color:#fff
style App fill:#4caf50,color:#fff
stackcat-agent 核心功能:
- 基于
InstrumentationAPI 和 ASM 字节码操作 - 向目标 JVM 注入方法入口/出口监控逻辑
- 拦截数据库调用(JDBC、MyBatis、JPA)
- 通过
MethodTrackingBridge异步批量上报数据
stackcat-app 核心功能:
- Spring Boot 3 Web 应用
- 提供 REST API 接收 Agent 上报数据
- Thymeleaf 模板引擎渲染 Web 界面
- MyBatis-Plus 操作 PostgreSQL 数据库
- JDK 17+
- Maven 3.9+
- PostgreSQL 14+(或兼容版本)
git clone <repository-url>
cd StackCat
mvn clean package构建完成后:
stackcat-agent/target/stackcat-agent-<version>-agent.jar- 带依赖的 Agent JARstackcat-app/target/stackcat-app-<version>.jar- Spring Boot 可执行 JAR
在 PostgreSQL 中执行初始化脚本:
psql -U postgres -d stackcat -f stackcat-app/src/main/resources/db/init.sql或使用 psql 交互式执行:
\i stackcat-app/src/main/resources/db/init.sqljava -jar stackcat-app/target/stackcat-app-<version>.jar默认监听 http://localhost:8080,访问 http://localhost:8080 查看仪表盘。
在启动你的 Java 应用时添加 Agent 参数:
java -javaagent:/path/to/stackcat-agent-<version>-agent.jar \
-Dstackcat.filter.packages.include=com.yourcompany \
-Dstackcat.agent.api.url=http://localhost:8080/api/tracking/batch \
-jar your-application.jar| 属性 | 说明 | 默认值 |
|---|---|---|
stackcat.filter.packages.include |
仅跟踪指定包前缀,逗号分隔。为空时默认 com.stackcat |
com.stackcat |
stackcat.filter.packages.exclude |
排除特定包前缀,逗号分隔 | 空 |
stackcat.agent.api.url |
上报目标地址 | http://localhost:8080/api/tracking/batch |
stackcat.agent.async.interval |
异步发送时间间隔(毫秒) | 1000 |
stackcat.agent.async.batch-size |
批量发送的最小请求数 | 10 |
主要配置项:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/stackcat
username: postgres
password: your-password
stackcat:
filter:
packages:
include: ["com.yourcompany"] # 与 Agent 侧保持一致
agent:
async:
interval: 1000
batch-size: 10
api:
url: http://localhost:8080/api/tracking/batch完整的配置说明请参考 stackcat-app/src/main/resources/application.yml。
| 表 | 作用 | 关键字段 |
|---|---|---|
request_trace |
记录每一次请求(请求 ID、线程信息、时间区间、HTTP 头) | request_id, thread_id, start_time, end_time, http_headers |
method_call |
存储方法调用树中的节点 | request_trace_id, parent_call_id, sequence, depth, query |
method_statistics |
聚合统计方法调用次数、线程数及最后调用时间 | method_name, call_count, statistics_date |
详细的数据模型定义请参考 stackcat-app/src/main/resources/db/init.sql。
- 性能分析:识别慢查询、高频方法调用,定位性能瓶颈
- 问题排查:通过调用链追踪快速定位异常发生的代码路径
- 代码理解:可视化方法调用关系,帮助理解复杂的业务逻辑
- 接口治理:统计接口调用情况,为接口优化提供数据支持
- SQL 优化:分析实际执行的 SQL 语句,发现潜在的数据库性能问题
访问 http://localhost:8080 查看实时统计:
- 总请求数
- 活跃请求数
- 总方法调用数
访问 http://localhost:8080/tracking 进行调用链查询:
- 按请求 ID 搜索
- 按时间范围过滤
- 树形结构展示完整调用链
- 查看关联的 SQL 语句
精确控制监控范围,避免外部依赖库的干扰:
-Dstackcat.filter.packages.include=com.example.service,com.example.controller
-Dstackcat.filter.packages.exclude=org.springframework,com.sun根据业务负载调整上报策略:
-Dstackcat.agent.async.interval=500 # 缩短上报间隔
-Dstackcat.agent.async.batch-size=20 # 增加批量大小- Java 21:项目基于 Java 21 开发,充分利用现代 Java 特性
- Spring Boot 3.5.0:服务端应用框架
- ASM 9.7:字节码操作库,用于运行时方法注入
- MyBatis-Plus 3.5.14:数据持久化框架
- PostgreSQL 14+:关系型数据库
- Thymeleaf:服务端模板引擎
org.ow2.asm:asm:核心字节码操作org.ow2.asm:asm-commons:ASM 工具类org.slf4j:slf4j-api:日志接口- Spring Context/Beans(provided scope):用于反射获取请求上下文
- 类加载拦截:Agent 通过
ClassFileTransformer拦截类加载过程 - ASM 字节码分析:使用 ASM 9 解析类文件结构
- 方法注入:在目标方法入口和出口注入追踪代码
- 数据收集:通过
MethodTrackingBridge收集调用信息 - 异步上报:后台线程批量发送数据到服务端
StackCat 在以下关键位置进行拦截:
| 拦截点 | 目标类/方法 | 用途 |
|---|---|---|
| Controller | 包含 controller 的包路径 |
捕获 HTTP 请求入口,提取 requestId 和请求头 |
| Service/Repository | 通用业务类方法 | 记录方法调用链,构建调用树 |
| Spring Data JPA | RepositoryMethodInvoker.doInvoke |
拦截 Repository 方法,提取 SQL/JPQL |
| MyBatis | SimpleExecutor.doQuery/doUpdate |
拦截 MyBatis 执行器,提取完整 SQL |
| JDBC | Connection.prepareStatement |
捕获原生 JDBC SQL 语句 |
- 深度追踪:使用 ThreadLocal 维护调用深度计数器
- 父子关系:通过
parentIndex建立方法调用的父子关系 - 序列号:为每次调用分配递增序列号,保证调用顺序
- SQL 关联:通过线程本地变量关联 SQL 语句到对应的 Repository 方法
接收 Agent 批量上报的追踪数据。
请求体示例:
[
{
"requestId": "req-123456",
"startTime": "2024-01-01T10:00:00",
"endTime": "2024-01-01T10:00:01",
"headers": {
"User-Agent": "Mozilla/5.0",
"Accept": "application/json"
},
"methodCalls": [
{
"className": "com.example.controller.UserController",
"methodName": "getUser",
"packageName": "com.example.controller",
"depth": 0,
"sequence": 0,
"callTime": "2024-01-01T10:00:00.100",
"parentIndex": -1,
"query": null
}
]
}
]响应:200 OK 返回 "OK"
获取当前活跃的请求列表。
响应示例:
[
{
"id": 1,
"requestId": "req-123456",
"threadId": 42,
"threadName": "http-nio-8080-exec-1",
"startTime": "2024-01-01T10:00:00",
"endTime": null,
"httpHeaders": "{\"User-Agent\":\"...\"}",
"createdAt": "2024-01-01T10:00:00"
}
]查询历史请求记录。
查询参数:
requestId(可选):请求 IDstartTime(可选):开始时间(ISO 8601 格式)endTime(可选):结束时间(ISO 8601 格式)
示例:
GET /api/tracking/history?requestId=req-123456&startTime=2024-01-01T00:00:00&endTime=2024-01-01T23:59:59
获取指定请求的完整调用树。
响应示例:
[
{
"id": 1,
"requestTraceId": 1,
"parentCallId": null,
"methodName": "getUser",
"className": "com.example.controller.UserController",
"packageName": "com.example.controller",
"callTime": "2024-01-01T10:00:00.100",
"sequence": 0,
"depth": 0,
"query": null,
"children": [
{
"id": 2,
"methodName": "findById",
"className": "com.example.service.UserService",
"depth": 1,
"query": "SELECT * FROM users WHERE id = ?"
}
]
}
]获取方法调用统计信息。
查询参数:
methodName(可选):方法名(支持模糊匹配)startDate(可选):开始日期endDate(可选):结束日期
获取统计概览。
响应示例:
{
"totalRequests": 1000,
"activeRequests": 5,
"totalMethodCalls": 5000
}症状:应用启动后没有看到追踪数据。
排查步骤:
- 检查 JVM 启动参数是否包含
-javaagent - 查看应用日志,确认 Agent 是否加载成功(查找 "Starting method tracking agent...")
- 验证包过滤配置是否正确:
-Dstackcat.filter.packages.include=com.yourcompany
- 确认目标类是否在过滤范围内
症状:Agent 日志显示数据收集正常,但服务端没有收到数据。
排查步骤:
- 检查服务端是否正常运行(访问
http://localhost:8080/api/statistics/overview) - 验证
stackcat.agent.api.url配置是否正确 - 检查网络连通性(Agent 能否访问服务端)
- 查看 Agent 日志中的错误信息
- 检查服务端日志,查看是否有接收错误
症状:调用链中 Repository 方法的 query 字段为空。
排查步骤:
- Spring Data JPA:
- 检查是否使用了
@Query注解(会从注解中提取) - 确认是否使用了自定义 Repository 实现
- 检查是否使用了
- MyBatis:
- 验证 MyBatis 版本兼容性
- 检查是否使用了自定义 Executor
- 原生 JDBC:
- 确认数据源是否支持
prepareStatement拦截 - 检查是否有连接池代理层(如 HikariCP)影响拦截
- 确认数据源是否支持
症状:应用启动变慢或运行时性能下降。
优化建议:
- 缩小包过滤范围,只监控必要的包
- 增加批量上报大小,减少网络请求频率
- 调整上报间隔,平衡实时性和性能
- 排除高频调用的框架类(如 Spring 内部类)
启用详细日志以排查问题:
Agent 端:
-Djava.util.logging.config.file=logging.properties服务端(application.yml):
logging:
level:
com.stackcat: DEBUG
org.springframework.web: DEBUG-
包过滤策略:
- 只包含业务代码包,排除框架包
- 使用精确的包前缀,避免过度匹配
-
批量上报调优:
# 高并发场景 -Dstackcat.agent.async.batch-size=50 -Dstackcat.agent.async.interval=2000 # 低延迟要求 -Dstackcat.agent.async.batch-size=5 -Dstackcat.agent.async.interval=500
-
避免递归:
- Agent 自动排除
com.stackcat.agent.*包 - 确保过滤配置不会包含 Agent 自身
- Agent 自动排除
-
数据库索引:
- 确保
request_trace表的request_id、start_time有索引 method_call表的request_trace_id、sequence有索引
- 确保
-
连接池配置:
spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5
-
数据清理策略:
- 定期清理历史数据,避免表过大
- 考虑按时间分区存储
-
敏感信息:
- HTTP 请求头可能包含敏感信息(如 Authorization),建议在生产环境过滤
- SQL 语句可能包含参数值,注意数据脱敏
-
网络通信:
- 生产环境建议使用 HTTPS 进行 Agent 到服务端的通信
- 配置防火墙规则,限制服务端访问
-
数据存储:
- 定期备份数据库
- 考虑数据加密存储
-
访问控制:
- 为 Web 界面添加认证机制
- 限制 API 访问权限
在 application.properties 中配置:
# JVM 参数
-javaagent:/path/to/stackcat-agent-1.0.0-agent.jar
-Dstackcat.filter.packages.include=com.yourcompany
-Dstackcat.agent.api.url=http://localhost:8080/api/tracking/batchDockerfile 示例:
FROM openjdk:21-jdk-slim
COPY stackcat-agent-1.0.0-agent.jar /app/agent.jar
COPY your-app.jar /app/app.jar
ENTRYPOINT ["java", \
"-javaagent:/app/agent.jar", \
"-Dstackcat.filter.packages.include=com.yourcompany", \
"-Dstackcat.agent.api.url=http://stackcat-app:8080/api/tracking/batch", \
"-jar", "/app/app.jar"]Deployment 示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-app
spec:
template:
spec:
containers:
- name: app
image: your-app:latest
command: ["java"]
args:
- "-javaagent:/agent/stackcat-agent.jar"
- "-Dstackcat.filter.packages.include=com.yourcompany"
- "-Dstackcat.agent.api.url=http://stackcat-app:8080/api/tracking/batch"
- "-jar"
- "/app/app.jar"
volumeMounts:
- name: agent
mountPath: /agent
volumes:
- name: agent
configMap:
name: stackcat-agent我们欢迎社区贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
# 克隆仓库
git clone <repository-url>
cd StackCat
# 编译项目
mvn clean install
# 运行测试
mvn test本项目采用 MIT License。详见 LICENSE 文件。
- AI 智能分析:集成 DeepSeek / ChatGPT 等大模型,为调用链、统计数据、SQL 语句和索引策略提供自动诊断与优化建议
- 多框架支持:扩展对 gRPC、Dubbo、Spring Cloud Gateway 等框架的拦截,覆盖跨服务链路与异步任务
- 性能监控:引入调用耗时分布、瓶颈识别、异常模式告警以及 SLA 趋势分析
- 企业功能:支持实时拓扑可视化、报告导出、多租户隔离与访问控制
- OpenObserve 集成:深度融合 OpenObserve,实现链路数据的集中采集、长周期检索与多维度关联分析
- 提交 Issue:GitHub Issues
- 讨论区:GitHub Discussions
StackCat - 让 Java 调用链追踪变得简单 ✨