doumu5662 2017-06-21 05:46
浏览 151
已采纳

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

I created a Global Logger in a utils package's init() method.

```

 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
}

```

So, I can use it like this:

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

My question is: Should I close the log file? How?

  • 写回答

1条回答 默认 最新

  • dty97501 2017-06-21 06:47
    关注

    By default, os.File will be finalized by the Garbage Collector (GC) when application exit. From SetFinalizer documentation

    The finalizer for obj is scheduled to run at some arbitrary time after obj becomes unreachable. There is no guarantee that finalizers will run before a program exits, so typically they are useful only for releasing non-memory resources associated with an object during a long-running program. For example, an os.File object could use a finalizer to close the associated operating system file descriptor when a program discards an os.File without calling Close, but it would be a mistake to depend on a finalizer to flush an in-memory I/O buffer such as a bufio.Writer, because the buffer would not be flushed at program exit.

    If you don't want to rely on GC, you can close it manually in the main function as follows:

    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
        //...
    }
    

    In the above code, we use defer statement to ensure the handler will be closed when the application exit. Since Logger.Out may be defined as io.Writer, we need to test whether the Logger.Out also implements io.Closer, and if yes, it will be closed. If Logger.Out is an os.File, we also call Sync() to ensure all the content is written to disk.

    EDIT
    Quote documentation and add file.Sync() to ensure file content is written to disk.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler