2017-06-21 84 views
0

我在utils包的init()方法中创建了全局Logger我应该关闭Go中的日志文件吗?

```

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 
} 

```

所以,我可以用这样的:

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

我的问题是:我应该关闭日志文件?怎么样?

+0

也许我不需要它,因为句柄将关闭可执行文件退出? – Nil

+0

你使用哪种记录器包?标准的'log'软件包不会导出其'out'成员。 – putu

+0

https://github.com/sirupsen/logrus – Nil

回答

0

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

obj的终结器计划在obj变得无法访问后的某个任意时间运行。不能保证在程序退出之前终结器会运行,因此通常它们仅用于在长时间运行的程序期间释放与对象关联的非内存资源。例如,当程序放弃os.File而不调用Close时,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 
    //... 
} 

在上面的代码中,我们使用defer语句来确保处理程序当应用程序退出时,将被关闭。由于Logger.Out可能定义为io.Writer,我们需要测试Logger.Out是否也实现了io.Closer,如果是的话,它将被关闭。如果Logger.Outos.File,我们还呼叫Sync()确保将所有内容写入磁盘。

编辑
报价文件,并添加file.Sync()确保文件内容写入磁盘。

相关问题