英文:
Why package log instance can't share to another package in Golang
问题
我的项目有一些包,我不想在函数之间传递日志实例,而是在这些包中使用一个全局日志实例。
这是我做的演示,但是运行go run main.go
后,日志/replica.log中没有打印任何内容。
我的代码有什么问题?
├── log
│ └── replica.log
├── logs
│ └── logs.go
├── main.go
main.go的内容如下:
package main
import (
"./logs"
)
func main() {
logs.Debug("hello")
}
logs.go的内容如下:
package logs
import (
logging "github.com/op/go-logging"
"os"
)
var log = logging.MustGetLogger("replica")
var format = logging.MustStringFormatter(
`%{time:2006-01-02 15:04:05} [%{level:.4s}] %{shortfile}: %{message}`,
)
func init() {
f, err := os.OpenFile("log/replica.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer f.Close()
backend1 := logging.NewLogBackend(f, "", 0)
backend1Formatter := logging.NewBackendFormatter(backend1, format)
logging.SetBackend(backend1Formatter)
}
func Debug(args ...interface{}) {
log.Debug(args)
}
英文:
My project has some packages, I don't want to pass log instance from one function to another, instead use a global log instance in there packages.
Here is the demo I have done, but run go run main.go
, nothing print in logs/replica.log.
What's wrong with my code?
├── log
│   └── replica.log
├── logs
│   └── logs.go
├── main.go
$ cat main.go
<!-- language: lang-golang -->
package main
import (
"./logs"
)
func main() {
logs.Debug("hello")
}
$ cat logs/logs.go
<!-- language: lang-golang -->
package logs
import (
logging "github.com/op/go-logging"
"os"
)
var log = logging.MustGetLogger("replica")
var format = logging.MustStringFormatter(
`%{time:2006-01-02 15:04:05} [%{level:.4s}] %{shortfile}: %{message}`,
)
func init() {
f, err := os.OpenFile("log/replica.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer f.Close()
backend1 := logging.NewLogBackend(f, "", 0)
backend1Formatter := logging.NewBackendFormatter(backend1, format)
logging.SetBackend(backend1Formatter)
}
func Debug(args ...interface{}) {
log.Debug(args)
}
答案1
得分: 1
是的,logs/logs.go:init()中的defer是问题所在。为什么会是问题呢?让我们来看一下Go语言规范,特别是关于延迟语句的部分:
> “defer”语句会调用一个函数,该函数的执行被延迟到包围它的函数体[...]达到函数体末尾的时刻。
当达到init函数体的末尾时,文件会被关闭。请记住,没有好的方法来优雅地关闭全局文件。
英文:
Yes, the defer in logs/logs.go:init() is the issue. Why is that the issue? Let's take a look at the Go Language Spec, specifically the section on Defer statements:
> A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function [...] reache
The file is closed when the end of the init function body is reached. Keep in mind, there's no good way to gracefully close a global file.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论