一个奇怪的go的log包的Bug
startInfo := bytes.Buffer{}
startInfo.WriteByte('[')
startInfo.WriteString(register.Name)
startInfo.WriteString("] Starting server at -> ")
startInfo.WriteString(register.ListenAddr)
startInfo.WriteString(" ;Listening...")
fmt.Println("ok1")
log.Println(startInfo.Bytes())
fmt.Println("ok2")
运行结果:
2023/06/15 17:16:58 ok1
2023/06/15 17:16:58 [91 66 117 115 105 110 101 115 115 229 164 132 231 144 134 229 153 168 93 32 83 116 97 114 116 105 110 103 32 32 115 101 114 118 101 114 32 97 116 32 45 62 32 58 49 50 51 56 32 59 76 105 115 116 101 110 105 110 103 46 46 46]
2023/06/15 17:16:58 ok2
startInfo := bytes.Buffer{}
startInfo.WriteByte('[')
startInfo.WriteString(register.Name)
startInfo.WriteString("] Starting server at -> ")
startInfo.WriteString(register.ListenAddr)
startInfo.WriteString(" ;Listening...")
fmt.Println("ok1")
log.Println(startInfo.String())
fmt.Println("ok2")
运行结果:
2023/06/15 17:16:58 ok1
目前发现,只要有- 或者> 就会这样,去掉就正常,
用strconv.Quote()解决,因为特殊符号被转义为实体动作了,或者用log.printf(“%s”,str)解决
go version go1.20.4 darwin/arm64
package main
import (
"bytes"
"fmt"
"log"
)
type reg struct {
Name string
ListenAddr string
}
func main() {
register := reg{
Name: "123",
ListenAddr: "127.0.0.1",
}
flag := false
if flag {
startInfo := bytes.Buffer{}
startInfo.WriteByte('[')
startInfo.WriteString(register.Name)
startInfo.WriteString("] Starting server at -> ")
startInfo.WriteString(register.ListenAddr)
startInfo.WriteString(" ;Listening...")
fmt.Println("ok1")
log.Println(startInfo.Bytes())
fmt.Println("ok2")
} else {
startInfo := bytes.Buffer{}
startInfo.WriteByte('[')
startInfo.WriteString(register.Name)
startInfo.WriteString("] Starting server at -> ")
startInfo.WriteString(register.ListenAddr)
startInfo.WriteString(" ;Listening...")
fmt.Println("ok1")
log.Println(startInfo.String())
fmt.Println("ok2")
}
}
~~~
会不会和后面的阻塞函数有关,这是后面部分的
server := &http.Server{
Addr: register.ListenAddr,
Handler: handleServer,
}
var startError error
if register.TLS {
startError = server.ListenAndServeTLS("server.crt", "server.key")
} else {
startError = server.ListenAndServe()
}
if startError != nil {
return startError
}
//正常exit
return nil
我问了一下gpt4,以下是gpt4的回复,从你的描述看,这个问题可能并不是一个 bug,而是因为
log.Println()
和fmt.Println()
对待参数的方式有所不同。log.Println()
函数会为每个参数调用fmt.Sprint()
来生成输出的字符串。在你的第一个例子中,你传递给log.Println()
的是一个字节切片(startInfo.Bytes()
),fmt.Sprint()
会将这个字节切片转换为一个字符串,其中每个字节都被转换为其对应的十进制数值,这就是为什么你看到一串数字的原因。在你的第二个例子中,你传递给
log.Println()
的是一个字符串(startInfo.String()
)。这个字符串应该能正常打印出来,但是你说结果卡住了。这可能是因为你的环境或者终端有些问题,或者是因为register.ListenAddr
中包含了一些非打印字符,导致在终端上看起来像是卡住了。你提到你已经设置了
log.SetOutput(file)
,并且在文件中的记录是正常的,这说明log.Println()
是正常工作的。你可以尝试在不同的终端或者环境下运行你的程序,看看是否还会出现同样的问题。如果使用
fmt.Println()
没有问题,那么在这种情况下,你可以继续使用fmt.Println()
来打印日志。如果你需要的是将日志写入文件,那么你可能需要使用log
包,因为fmt
包并没有提供设置输出的功能。另外,你也可以尝试一下
log.Printf()
函数,这个函数允许你指定一个格式字符串,可以更精确地控制输出的格式。例如:这样,你就不需要使用
bytes.Buffer
来手动构建字符串了。