2017-06-21 30 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()確保文件內容寫入磁盤。

相關問題