英文:
When to use log over fmt for debugging and printing error?
问题
我知道我们可以使用log和fmt来打印变量或错误。例如,如果我想打印一个变量,我可以这样做:
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
根据以下事实,在log和fmt之间进行选择:
log函数默认打印到stderr,可以通过指定输出来打印到任意写入器。fmt.Printf函数打印到stdout。log函数可以打印时间戳、源代码位置和其他信息。log函数和fmt.Printf函数都是线程安全的,但是fmt.Printf函数在超过特定大小的并发写入时可能会交错。
对于这三个子问题的答案是“取决于具体情况”。
英文:
Select between log and fmt using these facts:
- The
logfunctions print to stderr by default and can directed to an arbitrary writer. Thefmt.Printffunction prints to stdout. - The
logfunctions can print timestamp, source code location and other info. - The
logfunctions andfmt.Printfare both thread safe, but concurrent writes byfmt.Printfabove an OS dependent size can be interleaved.
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.
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论