跳至内容

dbx 可观测性与 Hooks

可观测性与 Hooks

Hooks 在每个 DB 操作前后执行。可用于日志、指标、链路追踪和慢查询检测。

HookEvent

HookEvent 携带操作详情:

字段说明
Operationquery, exec, query_row, begin_tx, commit_tx, rollback_tx, auto_migrate, validate_schema
Statement高层 statement 名称(若有)
SQL实际 SQL 字符串
Args绑定参数
Table目标表(若已知)
StartedAt操作开始时间
Duration耗时(在 After 中设置)
RowsAffectedexec 操作影响行数
Err错误(若有)
Metadata任意 key-value,用于 trace_id、request_id 等

Duration 与 StartedAt

使用 StartedAtDuration 做慢查询检测和耗时统计:

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

BeforeAfter 会收到 context.Context。Hooks 可从 context 中读取 trace/request ID(例如来自中间件),并复制到 event.Metadata 供日志或指标使用。

Runtime Node 日志

开启 WithDebug(true) 后,dbx 还会输出阶段级日志,日志消息为 dbx runtime node,并携带 node=<name>

常见节点分组:

  • build.*:查询构建链路(build.startbuild.donebuild.error
  • exec* / query_*:BoundQuery 执行与扫描阶段
  • schema.*:schema plan / validate / auto-migrate 阶段
  • relation.load.*:关系加载阶段(singlemultimany_to_many
  • sql.*:SQL statement helper(sql.bind.*sql.list.*sql.scalar.* 等)

建议聚合字段:

  • node
  • statement
  • operation
  • table
  • error