英文:
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
log
functions print to stderr by default and can directed to an arbitrary writer. Thefmt.Printf
function prints to stdout. - The
log
functions can print timestamp, source code location and other info. - The
log
functions andfmt.Printf
are both thread safe, but concurrent writes byfmt.Printf
above 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论