求教一个 go 自定义 log 的问题

2020-04-03 12:38:43 +08:00
 ljy1398202806

目的是想在控制台和文件同时输出,但是我这么写完以后却没有输出 Read Config……

我如果把 InitWriter 的整个代码都放在 init 里就能输出了……

为啥会这样😅

截取了一部分代码

不打算用第三方库,需求比较简单

go 刚学一个星期,有些实在不太懂,求教大佬了

package main

var logger *log.Logger

func init() {
	logger = log.New(InitWriter(), "", log.Ldate|log.Ltime|log.Lshortfile)
	logger.Println("Read Config……")
}
func InitWriter() io.Writer {
	if !PathExists("./log/") {
		os.Mkdir("./log/", 0773)
	}

	path := "./log/" + time.Now().Format("2006-01-02") + ".log"
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0773)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	writers := []io.Writer{
		f,
		os.Stdout}
	return io.MultiWriter(writers...)

}
1543 次点击
所在节点    Go 编程语言
7 条回复
sdrzlyz
2020-04-03 12:51:22 +08:00
defer f.Close()

你文件都关了,还咋往里写?

注意 multi writer 的实现,n 个 writers,第 i 个失败, [i+1,n]就不再写入啦

```
func (t *multiWriter) Write(p []byte) (n int, err error) {
for _, w := range t.writers {
n, err = w.Write(p)
if err != nil {
return
}
if n != len(p) {
err = ErrShortWrite
return
}
}
return len(p), nil
}
```
ljy1398202806
2020-04-03 12:53:23 +08:00
@sdrzlyz 感谢大佬。这块代码是看 https://www.jianshu.com/p/2e1d34c699c5 的,他也写了 defer f.Close(),所以这是写错了么
ljy1398202806
2020-04-03 12:54:22 +08:00
@sdrzlyz 感谢,可以了~
ljy1398202806
2020-04-03 12:56:54 +08:00
@sdrzlyz 嗯。。一开始 defer 没怎么看,刚刚去看了一下,defer 是在函数结束时调用,我的 logger 在外部获取,相当于已经关闭了我还想往里写内容肯定不行
sdrzlyz
2020-04-03 12:59:12 +08:00
@ljy1398202806 你可能没理解我的意思

1 、你这个代码的错误点在于 defer f.Close(), InitWriter() 返回后,f 就被关掉了,后续的 log Write 会失败
2 、把 defer f.Close() 去掉只是看起来 work 的方案,文件的关闭还是需要自行处理一下的
ljy1398202806
2020-04-03 13:17:47 +08:00
@sdrzlyz 我可能没表达清楚,和你的意思是一样的。网上的只是写了一个演示,写完直接就关掉了,我要一直往里写,但一开始照着他所以写不进去
yuanchao
2020-04-03 13:44:29 +08:00
在 main 函数中去打开,关闭这个文件就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/658975

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX