【背景】
折腾:
【已解决】go语言中实现log信息同时输出到文件和控制台(命令行)
期间,发现是可以通过io的MultiWriter来实现,同时将log信息,输出到log文件和console中的。
所以就去试试。
【折腾过程】
1.此处问题转化为:
2.知道了如何用MultiWriter后,但是也发现MultiWriter,不是很好用:
Writer中,输出内容,调用Writer(),结果也只能传入[]byte,而不能是string
搞得如果想要实现输出内容,也要去强制将string转换为[]byte,也还是很不爽。
但是先不管,先去试试,把这个MultiWriter,赋值给log的SetOutput,看看效果如何:
此处,发现:
func New(out io.Writer, prefix string, flag int) *Logger |
即,可以直接在新建log时,传递对应的Writer即可,而无需再新建log后,再去调用SetOutput去设置)
所以去用代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | //init for logger func initLogger(){ var filenameOnly string filenameOnly = GetCurFilename() fmt.Println( "filenameOnly=" , filenameOnly) var logFilename string = filenameOnly + ".log" ; fmt.Println( "logFilename=" , logFilename) logFile, err := os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777 ) if err != nil { fmt.Printf( "open file error=%s\r\n" , err.Error()) os.Exit(- 1 ) } defer logFile.Close() writers := []io.Writer{ logFile, os.Stdout, } fileAndStdoutWriter := io.MultiWriter(writers...) //fileAndStdoutWriter.Write([]byte("show in both log file and console via multiwriter")) //gLogger := log.New(logFile,"\r\n", log.Ldate | log.Ltime | log.Lshortfile) //gLogger = log.New(logFile, "\r\n", log.Ldate | log.Ltime | log.Lshortfile) gLogger = log.New(fileAndStdoutWriter, "\r\n" , log.Ldate | log.Ltime | log.Lshortfile) gLogger.Println( "normal log 1" ) gLogger.Println( "normal log 2" ) //【已解决】go代码出错退出:exit status 1 //gLogger.Panic("panic 1") //gLogger.Fatal("fatal 1") return } |
结果是:
可以实现我们要的效果的:
对于通过log输出的信息,可以同时在log文件和console中都显示。
效果,貌似还可以的。
6.另外,之前就发现了,貌似每条log信息之间有个多余的空行,觉得很是不爽。
后来猜测到,估计是新建的时候,参考别人代码,加上了那个”\r\n”了,所以去掉:
1 2 | //gLogger = log.New(fileAndStdoutWriter, "\r\n", log.Ldate | log.Ltime | log.Lshortfile) gLogger = log.New(fileAndStdoutWriter, "" , log.Ldate | log.Ltime | log.Lshortfile) |
试试效果:
的确是,没了多余的空行了。
看起来好多了。
7.然后,此处再去清理一下代码,把所有的输出,都从fmt的Printf或Println都变成此log的输出
结果出现异常现象了:
【已解决】go语言中使用MultiWriter输出到文件和console的信息,但是结果只能输出部分信息
【总结】
此处,是可以通过io的MultiWriter实现同时输出log信息到文件和console中的,
主体代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package main import ( "fmt" //"builtin" "log" "os" "io" ) var gLogFile *os.File; //init for logger func initLogger(){ var logFilename string = "io_MultiWriter_file.log" ; var err error; //gLogFile, err := os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777) gLogFile, err = os.OpenFile(logFilename, os.O_RDWR | os.O_CREATE, 0777 ) if err != nil { fmt.Printf( "open file error=%s\r\n" , err.Error()) os.Exit(- 1 ) } //not close log file here, otherwise later gLogger is not usable //only close log file after whole go file done writers := []io.Writer{ gLogFile, os.Stdout, } fileAndStdoutWriter := io.MultiWriter(writers...) //fileAndStdoutWriter.Write([]byte("show in both log file and console via multiwriter")) //gLogger := log.New(gLogFile,"\r\n", log.Ldate | log.Ltime | log.Lshortfile) //gLogger = log.New(gLogFile, "\r\n", log.Ldate | log.Ltime | log.Lshortfile) //gLogger = log.New(fileAndStdoutWriter, "\r\n", log.Ldate | log.Ltime | log.Lshortfile) gLogger = log.New(fileAndStdoutWriter, "" , log.Ldate | log.Ltime | log.Lshortfile) //gLogger.Println("normal log 1") //gLogger.Println("normal log 2") gLogger.Println( "logFilename=" , logFilename) //【已解决】go代码出错退出:exit status 1 //gLogger.Panic("panic 1") //gLogger.Fatal("fatal 1") return } func main() { initLogger() gLogger.Println( "this is EmulateLoginBaidu.go\n" ) //de-init something defer gLogFile.Close() } |
但是此方法,还是有缺点的:
不能控制不同的输出目标的level,所以后续还是要去尝试别的方案:
【记录】go语言中通过log4go实现同时输出log信息到log文件和console
转载请注明:在路上 » 【记录】go语言中通过io的MultiWriter实现同时输出log信息到log文件和console