go语言中log库的使用,并且加强添加日志级别控制

发布于:2022-11-05 ⋅ 阅读:(392) ⋅ 点赞:(0)

每门语言日志都是很重要的一部分,它能帮助我们快速定位到问题。

在go语言中内置了log库,主要有三种使用方式

Println : 打印普通日志

Printf : 打印带格式化的日志

Panic : 打印错误信息

简单使用

下面是一段使用示例

package main
import (
	"log"
)
func main() {
	log.Println("log ... ")
	log.Printf("name %s,age %d", "juan", 20)
	log.Panic("error")
}

输出结果

2022/11/05 17:04:03 log ... 
2022/11/05 17:04:03 name juan,age 20
2022/11/05 17:04:03 error
panic: error

goroutine 1 [running]:
log.Panic({0x14000135f38?, 0x14000102000?, 0x14000135f48?})
	/Users/wendell/support/go/go/src/log/log.go:388 +0x64
main.main()
	/Users/wendell/GolandProjects/blog/log.go:61 +0xc4

日志打印加强

上面一个简单的日志输出就完成了,但是这还满足不了我们在生产上使用的要求,我们希望能够把员工的工号信息打印出来,日志是在哪一个go文件哪一行中报错的都是关键信息
log库中也给我们提供了对于api

设置一个前缀。

log.SetPrefix()

增强日志信息内容,比如设置了 Lshortfile 就可以打印出go文件以及行号,设置Llongfile,go文件会把包名也打印出来

log.SetFlags()

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
)

在原来的go文件中添加如下初始化设置方法

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	log.SetPrefix("[工号:test01]")
}

查看打印效果

[工号:test01]2022/11/05 17:11:24 log.go:70: log ... 
[工号:test01]2022/11/05 17:11:24 log.go:71: name juan,age 20
[工号:test01]2022/11/05 17:11:24 log.go:72: error
panic: error

goroutine 1 [running]:
log.Panic({0x140000b7f38?, 0x14000102000?, 0x140000b7f48?})
	/Users/wendell/support/go/go/src/log/log.go:388 +0x64
main.main()
	/Users/wendell/GolandProjects/blog/log.go:72 +0xc4

日志输出到文件

如果想把日志输出到文件中
需要使用 log.SetOutput()

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	log.SetPrefix("[工号:test01]")
	// os.O_CREATE没有文件就创建
	// os.O_WRONLY 可以写入
	// os.O_APPEND 日志追加方式
	file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println(err)
		return
	}
	log.SetOutput(file)
}

再次执行发现多了一个日志文件,并且有错误信息。

在这里插入图片描述

到这虽然已经很完美了,但是大家接触过其它语言知道,一般我们打印日志会选择打印日志的级别,我们的调试日志都是debug级别。一些系统级别的日志会设置成info级别,报错日志为error级别

在生产上我们通过开关控制只打印info级别以上的日志。

那么go如何实现这样的效果呢。go的log库没有这个功能,我们只能通过继承它的方式对其增强

新增一个结构体 MyLog、定义级别常量、给结构体添加设置级别方法,添加 info、debug、error方法
代码如下

package main

import (
	"log"
)

type MyLog struct {
	*log.Logger
	level int
}

const (
	Debug int = iota
	Info
	Error
)

func NewLog() *MyLog {
	return &MyLog{Logger: log.Default()}
}

func (l *MyLog) SetLevel(level int) {
	l.level = level
}

func (l *MyLog) Info(msgArr ...any) {
	l.print(Info, msgArr...)
}

func (l *MyLog) Debug(msgArr ...any) {
	l.print(Debug, msgArr...)
}

func (l *MyLog) Error(msgArr ...any) {
	l.print(Error, msgArr...)
}

func (l *MyLog) print(level int, msgArr ...any) {
	if l.level <= level {
		l.Logger.Print(msgArr...)
	}
}

var myLog = NewLog()

func init() {
	myLog.SetFlags(log.LstdFlags | log.Lshortfile)
	myLog.SetPrefix("[工号:test01]")
	myLog.SetLevel(Info)
	//file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	//if err != nil {
	//	fmt.Println(err)
	//	return
	//}
	//myLog.SetOutput(file)
}

func main() {
	myLog.Debug("Debug 日志打印")
	myLog.Info("Info 日志打印")
	myLog.Error("Error 日志打印")
}

执行结果

[工号:test01]2022/11/05 17:37:39 log.go:40: Info 日志打印
[工号:test01]2022/11/05 17:37:39 log.go:40: Error 日志打印
本文含有隐藏内容,请 开通VIP 后查看