Go 日志

53 篇文章 0 订阅

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

示例:

package main

import (
   "log"
)
func main() {
   arr := []int{1, 2}
   log.Print("Print array ", arr, "\n")
   log.Println("Println array", arr)
   log.Printf("Printf array with item [%d,%d]\n", arr[0], arr[1])
   
}

结果:

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

示例:

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

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

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

示例

package main

import (
   "fmt"
   "log"
   "net/http"
)

func sayHelloHandler(w http.ResponseWriter, r *http.Request) {
   defer func() {
      fmt.Println("--first--")
   }()
   log.Fatalln("test for defer Fatal")
}

func main() {
   http.HandleFunc("/", sayHelloHandler) //   设置访问路由
   log.Fatal(http.ListenAndServe(":8080", nil))
}

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

log.SetOutput

将日志写到指定文件中

示例

package main

import (
   "log"
   "os"
)

func main() {
   // 按照所需读写权限创建文件
   f, err := os.OpenFile("filename.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
   if err != nil {
      log.Fatal(err)
   }
   // 完成后延迟关闭
   defer f.Close()
   //设置日志输出到 f
   log.SetOutput(f)
   //写入日志内容
   log.Println("check to make sure it works")
}

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

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

log.Logger、log.New

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

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

该函数一共有三个参数:

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

Ldate         = 1 << iota     // 形如 2009/01/23 的日期
Ltime                         // 形如 01:23:23   的时间
Lmicroseconds                 // 形如 01:23:23.123123   的时间
Llongfile                     // 全路径文件名和行号: /a/b/c/d.go:23 
Lshortfile                    // 文件名和行号: d.go:23
LstdFlags     = Ldate | Ltime // 日期和时间
package main

import (
   "io"
   "io/ioutil"
   "log"
   "os"
)

var (
   Trace   *log.Logger // 记录所有日志
   Info    *log.Logger // 重要的信息
   Warning *log.Logger // 需要注意的信息
   Error   *log.Logger // 致命错误
)

func init() {
   file, err := os.OpenFile("filename.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
   if err != nil {
      log.Fatalln(err)
   }
   Trace = log.New(ioutil.Discard, "TRACE: ", log.Ltime|log.Lshortfile)
   Info = log.New(os.Stdout, "Info: ", log.Ltime|log.Lshortfile)
   Warning = log.New(os.Stdout, "Warning: ", log.Ltime|log.Lshortfile)
   Error = log.New(io.MultiWriter(file, os.Stderr), "Error", log.Ltime|log.Lshortfile)
}

func main() {
   Trace.Println("trace")
   Info.Println("info")
   Warning.Println("warning")
   Error.Println("Error")
}

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

日志库logrus

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

安装:

go get -u github.com/sirupsen/logrus

实例

package main

import (
   "github.com/sirupsen/logrus"
   "os"
)

// Create a new instance of the logger. You can have any number of instances.
var log = logrus.New()

func main() {
   // The API for setting attributes is a little different than the package level
   // exported logger. See Godoc.
   log.Out = os.Stdout

   //You could set this to any `io.Writer` such as a file
   file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
   if err == nil {
      log.Out = file
   } else {
      log.Info("Failed to log to file, using default stderr")
   }

   log.WithFields(logrus.Fields{
      "animal": "walrus",
      "size":   10,
   }).Info("A group of walrus emerges from the ocean")
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值