我应该关闭 Go 中的日志文件吗?

Nil*_*Nil 5 logging go

Logger我在 utils 包的方法中创建了一个 Global init()

````

 package utils

 var Logger *log.Logger

 func init() {

  logFile, _ := config.Configure.String("log_file")
  if len(logFile) == 0 {
     appRoot, _ := os.Getwd()
     logFile = filepath.Join(appRoot, "app_runtime.log")
  }

  f, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
  //Look HERE!!! 

  if err != nil {
     panic(err)
  }
  Logger = log.New()

  //Log as JSON
  Logger.Formatter = &log.JSONFormatter{}

  //Output to stdout
  //When production, use file
  Logger.Out = f

  // Only log the debug severity or above.
  Logger.Level = log.DebugLevel
}
Run Code Online (Sandbox Code Playgroud)

````

所以,我可以这样使用它:

utils.Logger.Info("This is debug info")

我的问题是:我应该关闭日志文件吗?如何?

put*_*utu 6

默认情况下,os.File当应用程序退出时,将由垃圾收集器 (GC) 完成。来自SetFinalizer文档

obj 的终结器计划在 obj 变得无法访问后的某个任意时间运行。无法保证终结器将在程序退出之前运行,因此通常它们仅用于在长时间运行的程序期间释放与对象关联的非内存资源。例如,当程序在不调用 Close 的情况下丢弃 os.File 时,os.File 对象可以使用终结器来关闭关联的操作系统文件描述符,但依赖终结器来刷新内存中的 I 将是错误的。 /O 缓冲区,例如 bufio.Writer,因为缓冲区在程序退出时不会被刷新。

如果不想依赖GC,可以在函数中手动关闭,main如下:

func main() {
    //Close log writer when exit
    defer func(){
        if file, ok := Logger.Out.(*os.File); ok {
            file.Sync()
            file.Close()
        } else if handler, ok := Logger.Out.(io.Closer); ok {
            handler.Close()
        }
    }()

    //Your original codes
    //...
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们使用defer语句来确保处理程序将在应用程序退出时关闭。由于Logger.Outmay 被定义为io.Writer,所以我们需要测试是否Logger.Out也实现了io.Closer,如果是,则将其关闭。如果Logger.Out是一个os.File,我们还调用Sync()以确保所有内容都写入磁盘。

编辑
引用文档并添加file.Sync()以确保文件内容写入磁盘。