7.7 日志

golang 的log包使用起来挺简单,这里做一些简单介绍。

示例:

  1. package main
  2. import (
  3. "log"
  4. )
  5. func main() {
  6. arr := []int{1, 2}
  7. log.Print("Print array ", arr, "\n")
  8. log.Println("Println array", arr)
  9. log.Printf("Printf array with item [%d,%d]\n", arr[0], arr[1])
  10. }

结果:

2018/12/14 18:42:02 Print array [1 2] 2018/12/14 18:42:02 Println array [1 2] 2018/12/14 18:42:02 Printf array with item [1,2]

log.Fatal 、log.Fatalln、log.Fatalf

示例:

  1. log.Fatal("Fatal array ", arr, "\n")
  2. log.Fatalln("Fatalln array", arr)
  3. log.Fatalf("Fatalf array with item [%d,%d]\n", arr[0], arr[1])

对于 log.Fatal 接口,会先将日志内容打印到标准输出,接着调用系统的 os.exit(1) 接口退出程序并返回状态 1 。

在实际开发中要慎重,它导致整个系统退出,且不执行defer。

示例

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. )
  7. func sayHelloHandler(w http.ResponseWriter, r *http.Request) {
  8. defer func() {
  9. fmt.Println("--first--")
  10. }()
  11. log.Fatalln("test for defer Fatal")
  12. }
  13. func main() {
  14. http.HandleFunc("/", sayHelloHandler) // 设置访问路由
  15. log.Fatal(http.ListenAndServe(":8080", nil))
  16. }

当访问 http://127.0.0.1:8080/ 后,http 服务停止了,且defer没有调用。

log.SetOutput

将日志写到指定文件中

示例

  1. package main
  2. import (
  3. "log"
  4. "os"
  5. )
  6. func main() {
  7. // 按照所需读写权限创建文件
  8. f, err := os.OpenFile("filename.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. // 完成后延迟关闭
  13. defer f.Close()
  14. //设置日志输出到 f
  15. log.SetOutput(f)
  16. //写入日志内容
  17. log.Println("check to make sure it works")
  18. }

查看生成日志文件filename.log 内容

  1. 2018/12/14 18:56:55 check to make sure it works

log.Logger、log.New

先自定义Logger类型, log.Logger提供了一个New方法用来创建对象:

  1. func New(out io.Writer, prefix string, flag int) *Logger

该函数一共有三个参数:

(1)输出位置out,是一个io.Writer对象,该对象可以是一个文件也可以是实现了该接口的对象。通常我们可以用这个来指定日志输出到哪个文件。 (2)prefix 我们在前面已经看到,就是在日志内容前面的东西。我们可以将其置为 “[Info]” 、 “[Warning]”等来帮助区分日志级别。 (3) flags 是一个选项,显示日志开头的东西,可选的值有:

  1. Ldate = 1 << iota // 形如 2009/01/23 的日期
  2. Ltime // 形如 01:23:23 的时间
  3. Lmicroseconds // 形如 01:23:23.123123 的时间
  4. Llongfile // 全路径文件名和行号: /a/b/c/d.go:23
  5. Lshortfile // 文件名和行号: d.go:23
  6. LstdFlags = Ldate | Ltime // 日期和时间
  1. package main
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. )
  8. var (
  9. Trace *log.Logger // 记录所有日志
  10. Info *log.Logger // 重要的信息
  11. Warning *log.Logger // 需要注意的信息
  12. Error *log.Logger // 致命错误
  13. )
  14. func init() {
  15. file, err := os.OpenFile("filename.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  16. if err != nil {
  17. log.Fatalln(err)
  18. }
  19. Trace = log.New(ioutil.Discard, "TRACE: ", log.Ltime|log.Lshortfile)
  20. Info = log.New(os.Stdout, "Info: ", log.Ltime|log.Lshortfile)
  21. Warning = log.New(os.Stdout, "Warning: ", log.Ltime|log.Lshortfile)
  22. Error = log.New(io.MultiWriter(file, os.Stderr), "Error", log.Ltime|log.Lshortfile)
  23. }
  24. func main() {
  25. Trace.Println("trace")
  26. Info.Println("info")
  27. Warning.Println("warning")
  28. Error.Println("Error")
  29. }

细心的朋友可能发现执行多次程序输出日志的顺序会有变化,这个主要是 os.Stderr和os.Stdout输出的不同引起的,这两个虽然都是输出到终端,但在默认情况下,stdout是行缓冲的,它的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出的。参考:http://blog.sina.com.cn/s/blog_912673ce01013qq9.html

日志库logrus

logrus是在Github中star最多的go日志库,功能强大,性能不错。

安装:

  1. go get -u github.com/sirupsen/logrus

实例

  1. package main
  2. import (
  3. "github.com/sirupsen/logrus"
  4. "os"
  5. )
  6. // Create a new instance of the logger. You can have any number of instances.
  7. var log = logrus.New()
  8. func main() {
  9. // The API for setting attributes is a little different than the package level
  10. // exported logger. See Godoc.
  11. log.Out = os.Stdout
  12. //You could set this to any `io.Writer` such as a file
  13. file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
  14. if err == nil {
  15. log.Out = file
  16. } else {
  17. log.Info("Failed to log to file, using default stderr")
  18. }
  19. log.WithFields(logrus.Fields{
  20. "animal": "walrus",
  21. "size": 10,
  22. }).Info("A group of walrus emerges from the ocean")
  23. }

如果你对别的Go日志库感兴趣可以参考:

links