dbx 可观测性与 Hooks
可观测性与 Hooks
Hooks 在每个 DB 操作前后执行。可用于日志、指标、链路追踪和慢查询检测。
HookEvent
HookEvent 携带操作详情:
| 字段 | 说明 |
|---|---|
Operation | query, exec, query_row, begin_tx, commit_tx, rollback_tx, auto_migrate, validate_schema |
Statement | 高层 statement 名称(若有) |
SQL | 实际 SQL 字符串 |
Args | 绑定参数 |
Table | 目标表(若已知) |
StartedAt | 操作开始时间 |
Duration | 耗时(在 After 中设置) |
RowsAffected | exec 操作影响行数 |
Err | 错误(若有) |
Metadata | 任意 key-value,用于 trace_id、request_id 等 |
Duration 与 StartedAt
使用 StartedAt 和 Duration 做慢查询检测和耗时统计:
dbx.NewWithOptions(raw, dialect,
dbx.WithHooks(dbx.HookFuncs{
AfterFunc: func(_ context.Context, event *dbx.HookEvent) {
if event.Duration > 100*time.Millisecond {
slog.Warn("slow query", "sql", event.SQL, "duration", event.Duration)
}
},
}),
)Metadata 传递 Trace 与 Request ID
在 Before 中设置 Metadata 可传递 trace_id、request_id 或其他上下文。值会出现在 dbx 日志中:
dbx.NewWithOptions(raw, dialect,
dbx.WithHooks(dbx.HookFuncs{
BeforeFunc: func(ctx context.Context, event *dbx.HookEvent) (context.Context, error) {
if tid := ctx.Value("trace_id"); tid != nil {
event.SetMetadata("trace_id", tid)
}
if rid := ctx.Value("request_id"); rid != nil {
event.SetMetadata("request_id", rid)
}
return ctx, nil
},
}),
)SetMetadata 会在需要时初始化 map,避免 nil map panic。
Context
Before 和 After 会收到 context.Context。Hooks 可从 context 中读取 trace/request ID(例如来自中间件),并复制到 event.Metadata 供日志或指标使用。
Runtime Node 日志
开启 WithDebug(true) 后,dbx 还会输出阶段级日志,日志消息为 dbx runtime node,并携带 node=<name>。
常见节点分组:
build.*:查询构建链路(build.start、build.done、build.error)exec*/query_*:BoundQuery 执行与扫描阶段schema.*:schema plan / validate / auto-migrate 阶段relation.load.*:关系加载阶段(single、multi、many_to_many)sql.*:SQL statement helper(sql.bind.*、sql.list.*、sql.scalar.*等)
建议聚合字段:
nodestatementoperationtableerror