求教: golang error 和 log 的最佳实践思路

Ayanokouji · 2024-12-31 13:40:46 · 2253 次点击
用 go 写业务时,遇到 error 时,大多数情况只能一路向上 return err ,我们基于这个场景讨论。

这个场景,和 java 写业务遇到的 checked exception 很类似,写代码时,只能一路向上 throw (或者 catch 住 throw new unchecked exception ),最终由框架统一处理。

如果遇到 go 遇到经验不足的开发者(比如以前的我),就会看到这样的错误日志:

Error: unexpected '>' at the beginning of value

Error: EOF

Error: wrong argument value

嗯。。。这 tm 是啥啊,到底是哪一行代码出错啊。

调用链越长,问题越难排查。

比较通用的 web 业务调用链,一般是 handler -> service -> 中间件(数据库/redis/第三方 api 等)

随着坑踩的多了,现在遇到 err, 一般是 return fmt.Errorf("xxx:%w", err)

日志一般在 handler 层 slog.log("xxx", slog.Any("request", req), slog.Any("err", err))

但是缺少了调用栈,总觉得少了点什么。

请教下各位,如何平衡 error 和 log ,主要是服务于问题排查。

看过 echo 和 huma 的框架 error 处理,都是自定义 err ,框架统一处理

------

ps:那些上来只踩一脚 java 的,还是去多写写代码吧,这种 err ( unexpected '>' at the beginning of value ) 真的比 excetiop (含调用栈) 强吗。
举报· 2253 次点击
登录 注册 站外分享
20 条回复  
pluswu1986 初学 2024-12-31 13:52:51
业务代码一般不打印日志, 中间件统一在入口处理,底层错误返回 error.Warp 足够的信息(callstack 等) 让中间件统一处理
Ayanokouji 楼主 小成 2024-12-31 13:58:33
@pluswu1986 用的是 github.com/pkg/errors 这个库吗,但是这个已经不更新了
csys 初学 2024-12-31 13:58:36
没懂你这啥问题 go 记录 error 日志,怎么就没有调用栈了 如果 r 缺少调用栈,那是日志库有问题或者用法有问题
harleyliao 小成 2024-12-31 13:58:39
一般是在每个出错的地方都打印错误日志, 并返回错误给上一层, 这样通过错误日志就可以推测出调用链了.
Ayanokouji 楼主 小成 2024-12-31 14:02:04
@harleyliao @csys 日志是能说明是哪一行的。 如果遇到 error 就打印,这样日志太多了吧,比如 sevice 层,查了 5 次 sql ,那就需要写打印五次日志吗。
bli22ard 小成 2024-12-31 14:12:37
可能是最佳实战的做法是,你调用了标准库,或者第三方库,这些库返回 error 之后,你应该先用一些第三方 error 库 wrap 一下,主要目的是记录一下 error 发生的调用栈,这样上层什么位置拿到 error ,都能打印出来这个 error 是哪个位置发生的。还有一种,目的类似的做法,不记录调用栈,而改为附加一个错误码进去,这样上层的任何调用者也可以知道 error 哪里发生的,不过维护错误码这种方式维护时间越长,越容易搞混乱,导致排查问题困难。 原则上,只要不是本工程的代码生成的 error 都进行一次 wrap ,然后向上 return ,如果没有最上层,则进行错误日志打印。
Ayanokouji 楼主 小成 2024-12-31 14:17:34
@bli22ard 嗯,这种做法比较认同的。第三方 error 库不太好找,有推荐的吗 github.com/pkg/errors 这个已经停更了。 还有为了兼容 slog ,可能还需要封装一些代码。
dylanqqt 初学 2024-12-31 14:18:39
@Ayanokouji 我们就是遇到 err 就打印,“查五次”就要打印五次的 err ,要写五次 if err != nil ,因为可能第一个 err 会影响第二次的查询,不判断没法往下走啊
Ayanokouji 楼主 小成 2024-12-31 14:24:14
@dylanqqt 不能往下走是没问题的,就是五次 if err != nil 里边还有写五次打印日志,遇到错误也只能是其中一处,实际打印的日志也是一次
123下一页
返回顶部