V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
aababc
V2EX  ›  程序员

go gorm error 的疑惑

  •  
  •   aababc · 8 小时 18 分钟前 · 838 次点击

    这一段时间在使用 gorm 的时候有一个疑惑,在 gorm 中查询可能会返回一个 error ,我希望在出错的时候记录具体的执行的 SQL 语句是什么,但是我看 gorm 返回的 error 中并没有提供相关的获取 SQL 的信息,反而在 Logger 中可以通过 Trace 的方式来记录 Error 信息以及执行的 SQL 。

    我疑惑的点在于是否应该通过 error 返回的时候携带具体执行的 SQL 语句更合适呢,这样在记录错误信息的时候也就能记录上相关出错的 SQL ,而通过 gorm 自身 Logger 的方法,就需要通过上下文关联才能定位到具体出错的 SQL 语句。

    希望大家帮忙分析一下那个更合适

    第 1 条附言  ·  6 小时 10 分钟前
    简单点来说,gorm 库是否应该(或者说可能)在执行 SQL 出错的时候在 error 里携带上 SQL 语句本身,这样对于错误处理来说更友好
    第 2 条附言  ·  3 小时 28 分钟前
    我大概举个例子,比如现在拿到了一个错误 Error 1054 (42S22): Unknown column 'defs' in 'field list' 不结合上下文根本就没有办法看出来这里哪里的错误,必须要结合 gorm 中的 Trace 中的 Error 日志,所以我就在想能不能丰富一下 error 的信息
    13 条回复    2025-10-10 16:00:30 +08:00
    Immortal
        1
    Immortal  
       8 小时 16 分钟前
    很多都是一层层 return err,等下 err 直接到 response 了
    我反而有点疑惑你的思路...目前 Gorm 这样我反而觉得是最合理最方便的
    aababc
        2
    aababc  
    OP
       8 小时 3 分钟前
    @Immortal #1 我的想法是在最上层的错误处理器里统一处理 error 并记录相关的错误信息而后返回 response ,但是我再使用 gorm 的时候,我希望在查询出错的时候能记录到 error 和执行的 SQL ,但是 gorm 返回的错误并没有携带 SQL 语句,如果要记录 gorm error 时执行的 SQL 就需要使用 gorm 自己的 Logger ,这样感觉就会把错误信息切分成两部分,我的错误处理器中记录一部分,如果要查询具体的 SQL 就需要去 gorm 的日志中查看
    Div1ne
        3
    Div1ne  
       7 小时 51 分钟前
    你自己写一个 logger trace ,类似
    func (l SQLLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
    sql, rows := fc()
    if err != nil {
    log.Errorf("[DB Error] %v | SQL: %s | Rows: %d", err, sql, rows)
    }
    }

    然后创建 gorm 的时候,把这个传给 config: &gorm.Config{
    Logger: SQLLogger{logger.Default.LogMode(logger.Info)},
    }
    Div1ne
        4
    Div1ne  
       7 小时 49 分钟前
    gorm 本身是为了让关注点分离:sql 打印这些属于上下文,由 trace 负责。error 只负责管理错误。
    aababc
        5
    aababc  
    OP
       7 小时 29 分钟前
    @Div1ne #3 gorm 现在都已经实现了这些功能,不需要自己再实现一遍,有基于 logger 和 slog 的两种实现
    rarpainting
        6
    rarpainting  
       7 小时 28 分钟前
    如果你是打算特定位置特定格式来记录,可以在 if err!=nil 里用 dryrun
    如果你是在事务里的话,gorm 的 Transaction 给的太灵活了,不会有官方手段的,项目内部规定一个 error 格式就好

    总体来说你的问题虽然奇怪,但是解决方法还是足够的
    Immortal
        7
    Immortal  
       7 小时 24 分钟前
    @aababc #2
    现代框架的方案一边都是在 Server 收到 Request 的时候,为每个 Request 创建一个 TraceID 在 Context 中,所有后续的 Log 都会打印出这个 TraceID 来追踪整个 Request 的处理情况.这样就不会出现你说的 DB 和逻辑日志分离了.

    具体处理可以试试在 Gorm 的 DB 实例中注入这个 TraceID,类似
    traceCtx := context.WithValue(context.Background(),traceKey,traceID)
    db := db.WithContext(traceCtx)
    如果日志中没有可以像 3L 说的这样注入一个自定义的 TraceLogger 在打印的时候也打印出 TraceID.
    wogogoing
        8
    wogogoing  
    PRO
       7 小时 20 分钟前
    这应该是 Gorm 的设计理念。返回 error 是业务级别的,而 logtrace 则是日志级别的,并且支持自定义实现,这样让使用者可以更加的自由。

    你可以看一下我在 go-sail 中对 trace 的自定义实现:
    https://github.com/keepchen/go-sail/blob/main/lib/db/logger.go

    这样,可以开发者可以自行做很多事情,灵活度更高。
    aababc
        9
    aababc  
    OP
       7 小时 14 分钟前
    @Immortal #7 咋说呢,我们现在的场景也有 traceID 上下文也能关联起来,现在使用的是 slog ,添加这个 traceID 也是挺恶心的,不单需要重新赋值 request ,还需要自己实现 slog 的 handler
    Immortal
        10
    Immortal  
       6 小时 41 分钟前
    @aababc #9
    不用动 Request 吧,把处理后的 slog 和 db 可以直接放在入口的 ctx 里,实际逻辑和日志用自定义的 Ctx 去处理,就能统一注入 TraceID 了?
    veni2023
        11
    veni2023  
       6 小时 8 分钟前
    请求进来时 gorm 和 slog 都关联对应的请求 traceID ,不就可以了吗?这两应该都支持接入 OpenTelemetry
    iyaozhen
        12
    iyaozhen  
       6 小时 0 分钟前
    你的想法不能算错,但有些问题你没考虑到

    1. sql 是不能随便显示的,如果混在 error 中,就可能打印在日志(这在大公司是不允许的),甚至返回给用户
    2. 日志打印还是有技巧的,既不能多也不能少,你应该靠业务中的日志定位问题,而不是 sql 。类似打印 request 请求体、sql 原文,是不合规的

    你的诉求 gorm 应该能实现,但我没这样需求,具体没弄过
    Sendya
        13
    Sendya  
       5 小时 48 分钟前
    我这是通过 gorm plugin 和 gorm hooks 增加 gorm 的执行 before,after 的流程,在里面处理想要记录的信息,虽然我这边是记录上报给 opentelemetry, 你想记录日志也是同理的,这样还不用入侵你原始业务代码

    https://github.com/omalloc/contrib/blob/main/kratos/orm/gorm_tracing_callbacks.go#L81
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2895 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:49 · PVG 21:49 · LAX 06:49 · JFK 09:49
    ♥ Do have faith in what you're doing.