遵循:永不相信外部系统,永远相信内部系统
日志级别 | 打印标准 |
---|---|
Fatal | 一个或多个关键业务功能不符合预期,导致整个系统无法正常运行 |
Error | 一个或多个功能不符合预期,导致部分功能无法正确运行 |
Warn | 发生了不符合预期的行为,但相关功能仍能正常运行 |
Info | 发生了某件事,我们可能会在排查业务问题或查询相关信息时用到 |
Notice | 同上,一般不用 |
Debug | 用于调试 |
Trace | 用于调试 |
原则:
什么时候打印 error ?
如果打印error级别log,则认为一定发生了非预期的情况。例如mysql/下游挂了或自己代码中有bug,发生了从未考虑过的情况。其他的业务error一律是warn级别,例如扣钱时发现用户钱不够了这种业务错误 或不可信的上游(例如前端)传来的参数有问题
err : = json.Unmarshal(data, &task)
if err != nil {
logs.CtxError(ctx, "unmarshal error, err=%v", err)
return err
}
原始错误层层向上传递,每一层打印错误日志。这样会造成:
建议:
不需要处理的错误,错误级别不要使用Error级别,可以打印成Warn、Info、Debug等。
err:= json.Unmarshal(data, &task)
if err != nil {
return fmt.Errorf("unmarshal error, err=%v", err)
}
虽然日志变少了,但是也破坏了原始错误信息,如果上层需要判断原始错误则无法实现。
比如:查数据库时,有的时需要忽略没查到结果的情况,需要判断错误是不是 gorm.ErrRecordNotFound("record not found"), 如果包裹了信息,则无法实现了。然后就需要通过字符串匹配,判断 err.Error()中的信息,这是非常不合理的。
logs.CtxError(ctx, "%v", err) //普通错误打印
logs.CtxError(ctx, "%+v", err) //带有堆栈的错误打印
Error
。这样做可以让metrics
采集到日志产生的代码行。在错误日志有突增时,可以快速分析定位。controller
或者handler
,转换成rsp code
)