最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【记录】go语言中通过io的MultiWriter实现同时输出log信息到log文件和console

GO crifan 5334浏览 0评论

【背景】

折腾:

【已解决】go语言中实现log信息同时输出到文件和控制台(命令行)

期间,发现是可以通过io的MultiWriter来实现,同时将log信息,输出到log文件和console中的。

所以就去试试。

【折腾过程】

1.此处问题转化为:

【已解决】go语言中如何使用io的MultiWriter

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去设置)

所以去用代码:

//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
    //https://www.crifan.com/go_language_can_printf_info_and_exit_status_1/
    //gLogger.Panic("panic 1")
    //gLogger.Fatal("fatal 1")
    return
}

结果是:

可以实现我们要的效果的:

can show log both in log file and consle via log multiwriter_thumb

对于通过log输出的信息,可以同时在log文件和console中都显示。

效果,貌似还可以的。

6.另外,之前就发现了,貌似每条log信息之间有个多余的空行,觉得很是不爽。

后来猜测到,估计是新建的时候,参考别人代码,加上了那个”\r\n”了,所以去掉:

    //gLogger = log.New(fileAndStdoutWriter, "\r\n", log.Ldate | log.Ltime | log.Lshortfile)
    gLogger = log.New(fileAndStdoutWriter, "", log.Ldate | log.Ltime | log.Lshortfile)

试试效果:

no crlf between output log file_thumb

的确是,没了多余的空行了。

看起来好多了。

7.然后,此处再去清理一下代码,把所有的输出,都从fmt的Printf或Println都变成此log的输出

结果出现异常现象了:

【已解决】go语言中使用MultiWriter输出到文件和console的信息,但是结果只能输出部分信息

 

【总结】

此处,是可以通过io的MultiWriter实现同时输出log信息到文件和console中的,

主体代码为:

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
    //https://www.crifan.com/go_language_can_printf_info_and_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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.173 seconds, using 22.14MB memory