在调试和打印错误时,何时使用log而不是fmt?

huangapple go评论87阅读模式
英文:

When to use log over fmt for debugging and printing error?

问题

我知道我们可以使用logfmt来打印变量或错误。例如,如果我想打印一个变量,我可以这样做:

h := "world"
fmt.Printf("hello = %v\n", h)
log.Printf("halo = %v\n", h)

输出将会是:

hello = world
2016/12/30 09:13:12 halo = world

通常在错误处理中,我会发现像这样的日志:

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

但是从上面的例子中,我也可以使用fmt来打印错误,像这样:

fmt.Printf("Error: something terrible happen -> %v\n", err.Error())

在打印错误时,使用fmt而不是log是一个好的做法吗?然后在调试时,我总是使用fmt而不是log来打印变量。

英文:

I know that we can print variable or error using log and fmt. for example if I want to print variable I can do this :

h := "world"
fmt.Printf("hello = %v\n", h)
log.Printf("halo = %v\n", h)

the output would be :

hello = world
2016/12/30 09:13:12 halo = world

and usually in the error handling I found log like this

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

but from above case I could also use fmt to print the error like this

fmt.Printf("Error : something terrible happen -> %v\n",err.Error())

Is it a good practice to use fmt instead of log for printing the error?
And then I always use fmt instead of log for printing the variable when debugging.

答案1

得分: 58

根据以下事实,在logfmt之间进行选择:

对于这三个子问题的答案是“取决于具体情况”。

英文:

Select between log and fmt using these facts:

The answer to the three sub questions are "it depends".

答案2

得分: 13

我想再添加一个观点:

  • Log是线程安全的,而fmt不是。

    一个Logger可以同时从多个goroutine中使用;它保证对Writer的访问进行序列化。

链接

英文:

I would like to add one more point:

  • Log is thread safe where as fmt is not.

    A Logger can be used simultaneously from multiple goroutines; it guarantees to serialize access to the Writer.

Link

答案3

得分: 7

通常情况下,如果你在程序的输出方面使用 fmt.Print*,在程序的日志记录方面使用 log.*,你通常不会遇到麻烦。

当然,如果你的程序没有“本地”输出(像大多数网络服务器程序一样),你可以同时使用两者进行日志记录,但是 log.* 在日志记录方面更加灵活和适用。

英文:

You generally don't get into trouble if you stick to use fmt.Print* for program output and log.* for program logging.

Of course if your program doesn't have "local" output (as most network server programs) you could use both for logging, but for logging log.* is more flexible and apt.

答案4

得分: 4

从《Essential Go》书中:

标准包log提供了更多功能:

log.Printf("Logging")
log.Printf("Second line\n")

2019/03/26 10:07:11 Logging
2019/03/26 10:07:11 Second line

与fmt.Printf相比,log.Printf:

  • 默认将日志记录到stderr(os.Stderr)
  • 在每个日志行中添加当前时间
  • 如果未明确提供,则通过添加\n确保回显日志位于自己的行上

记录致命问题:

f, err := os.Open("file.txt")
if err != nil {
    log.Fatalf("os.Open('file.txt') failed with '%s'\n", err)
}

log.Fatalf记录消息并调用os.Exit(1)来结束进程。

英文:

From "Essential Go" book

Standard package log offers more functionality:

log.Printf("Logging")
log.Printf("Second line\n")

2019/03/26 10:07:11 Logging
2019/03/26 10:07:11 Second line

Compared to fmt.Printf, log.Printf:

  • By default logs to stderr (os.Stderr)
  • Adds current time to each log line
  • Ensures that echo log is on it’s own line by adding \n if not explicitly provided

To log fatal issues:

f, err := os.Open("file.txt")
if err != nil {
    log.Fatalf("os.Open('file.txt') failed with '%s'\n", err)
}

log.Fatalf logs the message and calls os.Exit(1) to end the process.

huangapple
  • 本文由 发表于 2016年12月30日 10:43:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/41389933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定