在golang中封装日志设置的正确模式
发布时间:2020-12-16 09:22:06 所属栏目:大数据 来源:网络整理
导读:当尝试将日志设置代码移动到单独的函数时,我遇到无法从主函数隐藏目标文件对象.在下面的INCORRECT简化示例中,尝试通过单个函数调用设置日志写入Stderr和文件: package mainimport ( "io" "log" "os")func SetupLogging() { logFile,err := os.OpenFile("tes
当尝试将日志设置代码移动到单独的函数时,我遇到无法从主函数隐藏目标文件对象.在下面的INCORRECT简化示例中,尝试通过单个函数调用设置日志写入Stderr和文件:
package main import ( "io" "log" "os" ) func SetupLogging() { logFile,err := os.OpenFile("test.log",os.O_APPEND|os.O_CREATE,0666) if err != nil { log.Panicln(err) } defer logFile.Close() log.SetOutput(io.MultiWriter(os.Stderr,logFile)) } func main() { SetupLogging() log.Println("Test message") } 显然是不起作用,因为defer在SetupLogging函数结束时关闭日志文件. 下面的一个工作示例添加了额外的代码,如果在较大的应用程序中重复作为模式,IMHO会失去一些清晰度: package main import ( "io" "log" "os" ) func SetupLogging() *os.File { logFile,0666) if err != nil { log.Panicln(err) } log.SetOutput(io.MultiWriter(os.Stderr,logFile)) return logFile } func main() { logf := SetupLogging() defer logf.Close() log.Println("Test message") } 有没有不同的方法将打开文件管理完全封装到一个函数中,但仍然很好地释放句柄? 解决方法
我现在已经成功地在多个项目中使用了以下方法大约一年.我们的想法是从设置调用中返回一个函数.结果函数包含销毁逻辑.这是一个例子:
package main import ( "fmt" "io" "log" "os" ) func LogSetupAndDestruct() func() { logFile,os.O_CREATE|os.O_APPEND|os.O_RDWR,logFile)) return func() { e := logFile.Close() if e != nil { fmt.Fprintf(os.Stderr,"Problem closing the log file: %sn",e) } } } func main() { defer LogSetupAndDestruct()() log.Println("Test message") } 它正在使用一个关闭清理逻辑的闭包. 使用这种方法的更详细的公开示例在Viper代码中:here is the return from a test initializer和here it is used to encapsulate the cleanup logic and objects (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |