何时使用log over fmt进行调试和打印错误?

Guj*_*ana 17 go

我知道我们可以使用log和打印变量或错误fmt.例如,如果我想打印变量,我可以这样做:

h := "world"
fmt.Printf("hello = %v\n", h)
log.Printf("halo = %v\n", h)
Run Code Online (Sandbox Code Playgroud)

输出将是:

hello = world
2016/12/30 09:13:12 halo = world
Run Code Online (Sandbox Code Playgroud)

并且通常在错误处理中我发现这样的日志

if err != nil {
    log.Println("Error : something terrible happen -> ", err)
    return err
}
Run Code Online (Sandbox Code Playgroud)

但从上面的情况我也可以fmt用来打印这样的错误

fmt.Printf("Error : something terrible happen -> %v\n",err.Error())
Run Code Online (Sandbox Code Playgroud)

使用fmt而不是log打印错误是一个好习惯吗?然后我总是使用fmt而不是log在调试时打印变量.

Cer*_*món 27

选择logfmt使用这些事实:

三个子问题的答案是"它取决于".


Jam*_*pam 9

我想补充一点:

  • 日志是线程安全的,而fmt不是.

    Logger可以同时使用多个goroutine; 它保证序列化对Writer的访问.

链接

  • 实际上,尽管`fmt.Printf`在没有任何数据竞争的意义上是线程安全的,但是`Logger`使用互斥锁来序列化输出,而fmt直接将其写出来.通过足够的并发,您可以获得对stdout的交叉写入. (3认同)
  • @GujaratSantana [logger documentation](https://godoc.org/log#Logger)声明可以从多个goroutine同时使用记录器.没有关于`fmt.Printf`的线程安全性的文档.`fmt.Printf`实现是线程安全的,它不太可能被改为不是线程安全的. (2认同)

Pab*_*oni 7

如果您坚持使用 fmt.Print* 进行程序输出并使用 log.* 进行程序记录,通常不会遇到麻烦。

当然,如果您的程序没有“本地”输出(与大多数网络服务器程序一样),您可以使用两者进行日志记录,但对于日志记录 log.* 更加灵活和恰当。