10 - 日志调试
10.1 SQL 日志
开启日志
dlz:
db:
# 是否打印 SQL
show-sql: true
# 是否格式化 SQL
format-sql: true
# 慢 SQL 阈值(毫秒)
slow-sql-threshold: 1000
日志输出格式
┌─────────────────────────────────────────────────────────────────────┐
│ [SQL] SELECT * FROM user WHERE id = 1 AND is_deleted = 0 │
│ [参数] id=1 │
│ [耗时] 15ms │
│ [调用] c.e.service.UserService.getById(UserService.java:42) │
│ └─ c.e.controller.UserController.detail(UC.java:28) │
└─────────────────────────────────────────────────────────────────────┘
慢 SQL 警告
⚠️ [慢SQL] 执行时间 2350ms 超过阈值 1000ms
[SQL] SELECT * FROM orders WHERE create_time > '2020-01-01'
[调用] c.e.service.OrderService.findAll(OrderService.java:56)
日志级别控制
logging:
level:
com.dlz.db: DEBUG // 开启详细日志
com.dlz.db.sql: INFO // SQL 日志
10.2 SQL 代码定位(独家特性)
痛点
传统开发中的问题:
1. 控制台看到一条慢 SQL
2. 不知道是哪个 Controller/Service 执行的
3. 全局搜索 SQL 关键词 → 找到 10+ 个地方
4. 一个个排查...
5. 浪费 30 分钟
DLZ-DB:直接告诉你是哪行代码!
效果对比
传统 MyBatis 日志
DEBUG - ==> Preparing: SELECT * FROM user WHERE status = ?
DEBUG - ==> Parameters: 1(Integer)
DEBUG - <== Total: 50
// 然后呢?这 SQL 是从哪来的?🤷♂️
DLZ-DB 日志
[SQL] SELECT * FROM user WHERE status = 1 AND is_deleted = 0
[耗时] 45ms
[调用] com.example.service.UserService.findActive(UserService.java:67)
↓
com.example.controller.UserController.list(UserController.java:34)
// 点击 UserService.java:67 直接跳转到代码位置!✅
实现原理
// DLZ-DB 内部实现(简化)
public void logSql(String sql, long costMs) {
// 1. 获取调用栈
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
// 2. 过滤框架代码,找到业务代码
String location = findBusinessCode(stack);
// 3. 格式化输出
log.info("[SQL] {}", sql);
log.info("[耗时] {}ms", costMs);
log.info("[调用] {}", location);
}
调用链深度
dlz:
db:
// 显示调用链深度(默认 2)
stack-trace-depth: 3
[调用] UserService.findActive(UserService.java:67)
└─ UserController.list(UserController.java:34)
└─ DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
IDE 集成
主流 IDE 都支持点击跳转:
- IntelliJ IDEA ✅
- Eclipse ✅
- VS Code ✅
日志格式 ClassName.method(File.java:行号) 符合标准,可直接点击跳转。