Go标准库日志打印及同时输出到控制台与文件

 更新时间:2022年11月30日 10:04:22   作者:Go和分布式IM  
Go语言内置的log包实现了简单的日志服务,下面这篇文章主要给大家介绍了关于Go标准库日志打印及同时输出到控制台与文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

打印

在使用go写一些小程序时,我们没必要引入额外的包,直接使用fmt标准包打印即可:

import "fmt"

func main() {
   fmt.Println("line1")
   fmt.Print("line2")
   fmt.Printf("line%d \n", 3)

   str1 := fmt.Sprintln("hello", 3)
   str2 := fmt.Sprint("hello ", 1, " 2")
   str3 := fmt.Sprintf("hello %d", 1)
   fmt.Print(str1, str2, str3)
}

line1
line2line3 
hello 3
hello 1 2hello 1

那么,有些场景下,我们希望能同时打印到日志文件中要怎么办呢?

log包

标准库提供了log组件,用法和fmt一致,有3种方式:

import “log"

func main() {
   log.Println("line1")
   log.Print("line2")
   log.Printf("line%d \n", 3)
}

和fmt的区别就是多了时间:

2021/08/25 17:23:47 line1
2021/08/25 17:23:47 line2
2021/08/25 17:23:47 line3 

我们通过SetFlag函数,可以设置打印的格式:

// For example, flags Ldate | Ltime (or LstdFlags) produce,
// 2009/01/23 01:23:23 message
// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
const (
   Ldate         = 1 << iota     // the date in the local time zone: 2009/01/23
   Ltime                         // the time in the local time zone: 01:23:23
   Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
   Llongfile                     // full file name and line number: /a/b/c/d.go:23
   Lshortfile                    // final file name element and line number: d.go:23. overrides Llongfile
   LUTC                          // if Ldate or Ltime is set, use UTC rather than the local time zone
   Lmsgprefix                    // move the "prefix" from the beginning of the line to before the message
   LstdFlags     = Ldate | Ltime // initial values for the standard logger
)

比如,我们只需要时间和文件名:

import “log"

func main() {
   log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

   log.Println("line1")
   log.Print("line2")
   log.Printf("line%d \n", 3)
}

此时,再次运行,则会打印文件和行号:

2021/08/25 17:27:56 mod_unread_redis.go:32: line1
2021/08/25 17:27:56 mod_unread_redis.go:33: line2
2021/08/25 17:27:56 mod_unread_redis.go:34: line3

如何输出日志到文件?

log包使用非常简单,默认情况下,只会输出到控制台。

我们可以使用SetOutput改变输出流,比如输出到文件。

先来看一下函数原型,其接收一个io.Writer接口:

// SetOutput sets the output destination for the standard logger.
func SetOutput(w io.Writer) {
    // ...
}

那么,我们就可以创建一个文件流设置一下就行了。

// 创建、追加、读写,777,所有权限
f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
   return
}
defer func() {
   f.Close()
}()

log.SetOutput(f)

此时,在运行,我们发现日志会输出到文件,但是控制台没有任何东西输出了。

如何同时输出到控制台和文件?

标准库io包中,有一个MultiWriter,可以把文件流和控制台标准输出流整合到一个io.Writer上,其实现上就是一个数组,在执行写操作时,遍历数组:

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
//
// Each write is written to each listed writer, one at a time.
// If a listed writer returns an error, that overall write operation
// stops and returns the error; it does not continue down the list.
func MultiWriter(writers ...Writer) Writer {
   allWriters := make([]Writer, 0, len(writers))
   for _, w := range writers {
      if mw, ok := w.(*multiWriter); ok {
         allWriters = append(allWriters, mw.writers...)
      } else {
         allWriters = append(allWriters, w)
      }
   }
   return &multiWriter{allWriters}
}

// 重写io.Writer的Write函数函数,本质上就是遍历数组,比较巧妙
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
}

使用方式如下:

func main() {
   f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
   if err != nil {
      return
   }
   defer func() {
      f.Close()
   }()

   // 组合一下即可,os.Stdout代表标准输出流
   multiWriter := io.MultiWriter(os.Stdout, f)
   log.SetOutput(multiWriter)

   log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

   log.Println("line1")
   log.Print("line2")
   log.Printf("line%d \n", 3)
}

此时,再运行,则会同时输出到控制台和文件中。

2021/08/25 17:38:02 mod_unread_redis.go:42: line1
2021/08/25 17:38:02 mod_unread_redis.go:43: line2
2021/08/25 17:38:02 mod_unread_redis.go:44: line3 

附:日志切割(按文件大小切割、按日期切割)

其实就是每次记录文件的大小,超过了就重新写一个文件。

通过Stat()函数拿到文件的一些信息

    open, _:= os.Open("文件名")
    stat, _, := open.Stat()
    stat.Size()//拿到文件大小

日期切割:

拿到文件的名称或者检查下有没有当天的日志文件,没有就创建新增。

总结

到此这篇关于Go标准库日志打印及同时输出到控制台与文件的文章就介绍到这了,更多相关Go标准库日志打印及输出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go类型断言提取测试接口值动态类型及静态转换确保类型接口编译安全

    Go类型断言提取测试接口值动态类型及静态转换确保类型接口编译安全

    这篇文章主要为大家介绍了Go类型断言提取测试接口值动态类型及静态转换确保类型实现特定接口的编译时安全性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • GO接收GET/POST参数及发送GET/POST请求的实例详解

    GO接收GET/POST参数及发送GET/POST请求的实例详解

    这篇文章主要介绍了GO接收GET/POST参数及发送GET/POST请求,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • golang使用bcrypt包对密码进行加密的方法实现

    golang使用bcrypt包对密码进行加密的方法实现

    本文主要介绍了golang使用bcrypt包对密码进行加密的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • golang两种调用rpc的方法

    golang两种调用rpc的方法

    这篇文章主要介绍了golang两种调用rpc的方法,结合实例形式分析了Go语言调用rpc的原理与实现方法,需要的朋友可以参考下
    2016-07-07
  • vscode中安装Go插件和配置Go环境详细步骤

    vscode中安装Go插件和配置Go环境详细步骤

    要在VSCode中配置Go语言插件,首先需要确保你的电脑已经安装了Go环境和最新版本的VSCode,这篇文章主要给大家介绍了关于vscode中安装Go插件和配置Go环境的相关资料,需要的朋友可以参考下
    2024-01-01
  • 浅谈golang通道类型

    浅谈golang通道类型

    本文主要介绍了浅谈golang通道类型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Golang利用compress/flate包来压缩和解压数据

    Golang利用compress/flate包来压缩和解压数据

    在处理需要高效存储和快速传输的数据时,数据压缩成为了一项不可或缺的技术,Go语言的compress/flate包为我们提供了对DEFLATE压缩格式的原生支持,本文将深入探讨compress/flate包的使用方法,揭示如何利用它来压缩和解压数据,并提供实际的代码示例,需要的朋友可以参考下
    2024-08-08
  • 聊聊golang的defer的使用

    聊聊golang的defer的使用

    这篇文章主要介绍了聊聊golang的defer的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • go写文件后出现大量NUL字符问题解决

    go写文件后出现大量NUL字符问题解决

    本文主要介绍了go写文件后出现大量NUL字符问题解决,由于每次写的时候设置的长度都是64,在某次不足64时,byte切片空余位置被填充为空字符,下面就来介绍一下如何解决
    2023-12-12
  • 代码整洁利器go fmt命令使用详解

    代码整洁利器go fmt命令使用详解

    这篇文章主要为大家介绍了代码整洁利器go fmt命令使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论