跳到主要内容

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:行号) 符合标准,可直接点击跳转。